~ubuntu-branches/ubuntu/jaunty/electric/jaunty

« back to all changes in this revision

Viewing changes to src/vhdl/vhdl.c

  • Committer: Bazaar Package Importer
  • Author(s): Onkar Shinde
  • Date: 2009-01-08 02:05:08 UTC
  • mfrom: (1.3.1 upstream) (3.1.3 sid)
  • mto: (3.1.4 sid)
  • mto: This revision was merged to the branch mainline in revision 11.
  • Revision ID: james.westby@ubuntu.com-20090108020508-3e7e6241i7bkit2l
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Electric(tm) VLSI Design System
3
 
 *
4
 
 * File: vhdl.c
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
9
 
 *
10
 
 * Copyright (c) 2000 Static Free Software.
11
 
 *
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.
16
 
 *
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.
21
 
 *
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.
26
 
 *
27
 
 * Static Free Software
28
 
 * 4119 Alpine Road
29
 
 * Portola Valley, California 94028
30
 
 * info@staticfreesoft.com
31
 
 */
32
 
 
33
 
#include "config.h"
34
 
#if VHDLTOOL
35
 
 
36
 
#include "global.h"
37
 
#include "efunction.h"
38
 
#include "vhdl.h"
39
 
#include "sim.h"
40
 
#include "eio.h"
41
 
#include "network.h"
42
 
#include "tecschem.h"
43
 
#include "edialogs.h"
44
 
 
45
 
#define MAXINPUTS              30               /* maximum inputs to logic gate */
46
 
#define IGNORE4PORTTRANSISTORS  1
47
 
 
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 */
62
 
 
63
 
/* the VHDL compiler tool table */
64
 
static KEYWORD vhdloutputopt[] =
65
 
{
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}},
71
 
        TERMKEY
72
 
};
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[] =
78
 
{
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}},
83
 
        TERMKEY
84
 
};
85
 
static COMCOMP vhdlnp = {vhdlnopt, NOTOPLIST, NONEXTLIST, NOPARAMS,
86
 
        NOBACKUP, INPUTOPT, " \t", M_("Negating action"), 0};
87
 
static KEYWORD vhdlsetopt[] =
88
 
{
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}},
98
 
        TERMKEY
99
 
};
100
 
COMCOMP vhdl_comp = {vhdlsetopt, NOTOPLIST, NONEXTLIST, NOPARAMS, NOBACKUP,
101
 
        0, " \t", M_("VHDL compiler action"), 0};
102
 
 
103
 
char    vhdl_delimiterstr[] = "&'()*+,-./:;<=>|";
104
 
char    vhdl_doubledelimiterstr[] = "=>..**:=/=>=<=<>";
105
 
 
106
 
static VKEYWORD vhdl_keywords[] =
107
 
{
108
 
        {"abs",                         KEY_ABS},
109
 
        {"after",                       KEY_AFTER},
110
 
        {"alias",                       KEY_ALIAS},
111
 
#ifndef VHDL50
112
 
        {"all",                         KEY_ALL},
113
 
#endif
114
 
        {"and",                         KEY_AND},
115
 
#ifdef VHDL50
116
 
        {"architectural",       KEY_ARCHITECTURAL},
117
 
#else
118
 
        {"architecture",        KEY_ARCHITECTURE},
119
 
#endif
120
 
        {"array",                       KEY_ARRAY},
121
 
        {"assertion",           KEY_ASSERTION},
122
 
        {"attribute",           KEY_ATTRIBUTE},
123
 
        {"begin",                       KEY_BEGIN},
124
 
        {"behavioral",          KEY_BEHAVIORAL},
125
 
        {"body",                        KEY_BODY},
126
 
        {"case",                        KEY_CASE},
127
 
        {"component",           KEY_COMPONENT},
128
 
        {"connect",                     KEY_CONNECT},
129
 
        {"constant",            KEY_CONSTANT},
130
 
        {"convert",                     KEY_CONVERT},
131
 
        {"dot",                         KEY_DOT},
132
 
        {"downto",                      KEY_DOWNTO},
133
 
        {"else",                        KEY_ELSE},
134
 
        {"elsif",                       KEY_ELSIF},
135
 
        {"end",                         KEY_END},
136
 
        {"entity",                      KEY_ENTITY},
137
 
        {"exit",                        KEY_EXIT},
138
 
        {"for",                         KEY_FOR},
139
 
        {"function",            KEY_FUNCTION},
140
 
        {"generate",            KEY_GENERATE},
141
 
        {"generic",                     KEY_GENERIC},
142
 
        {"if",                          KEY_IF},
143
 
        {"in",                          KEY_IN},
144
 
        {"inout",                       KEY_INOUT},
145
 
        {"is",                          KEY_IS},
146
 
        {"library",                     KEY_LIBRARY},
147
 
        {"linkage",                     KEY_LINKAGE},
148
 
        {"loop",                        KEY_LOOP},
149
 
#ifndef VHDL50
150
 
        {"map",                         KEY_MAP},
151
 
#endif
152
 
        {"mod",                         KEY_MOD},
153
 
        {"nand",                        KEY_NAND},
154
 
        {"next",                        KEY_NEXT},
155
 
        {"nor",                         KEY_NOR},
156
 
        {"not",                         KEY_NOT},
157
 
        {"null",                        KEY_NULL},
158
 
        {"of",                          KEY_OF},
159
 
#ifndef VHDL50
160
 
        {"open",                        KEY_OPEN},
161
 
#endif
162
 
        {"or",                          KEY_OR},
163
 
        {"others",                      KEY_OTHERS},
164
 
        {"out",                         KEY_OUT},
165
 
        {"package",                     KEY_PACKAGE},
166
 
        {"port",                        KEY_PORT},
167
 
        {"range",                       KEY_RANGE},
168
 
        {"record",                      KEY_RECORD},
169
 
        {"rem",                         KEY_REM},
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},
178
 
        {"then",                        KEY_THEN},
179
 
        {"to",                          KEY_TO},
180
 
        {"type",                        KEY_TYPE},
181
 
        {"units",                       KEY_UNITS},
182
 
        {"use",                         KEY_USE},
183
 
        {"variable",            KEY_VARIABLE},
184
 
        {"when",                        KEY_WHEN},
185
 
        {"while",                       KEY_WHILE},
186
 
        {"with",                        KEY_WITH},
187
 
        {"xor",                         KEY_XOR}
188
 
};
189
 
 
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;
205
 
       TOOL       *vhdl_tool;
206
 
static void       *vhdl_componentarray = 0;
207
 
static void       *vhdl_stringarray;
208
 
       UNRESLIST  *vhdl_unresolved_list = 0;
209
 
 
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);
239
 
 
240
 
void vhdl_init(INTBIG *argc, char *argv[], TOOL *thistool)
241
 
{
242
 
        /* only initialize during pass 1 */
243
 
        if (thistool == NOTOOL || thistool == 0) return;
244
 
 
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);
253
 
}
254
 
 
255
 
void vhdl_done(void)
256
 
{
257
 
#ifdef DEBUGMEMORY
258
 
        if (vhdl_componentarray != 0) killstringarray(vhdl_componentarray);
259
 
        vhdl_freescannermemory();
260
 
        if (vhdl_identtable != 0) efree((char *)vhdl_identtable);
261
 
        vhdl_freeparsermemory();
262
 
        vhdl_freesemantic();
263
 
        vhdl_freeunresolvedlist(&vhdl_unresolved_list);
264
 
#endif
265
 
}
266
 
 
267
 
void vhdl_set(INTBIG count, char *par[])
268
 
{
269
 
        INTBIG l;
270
 
        char *pp;
271
 
        REGISTER NODEPROTO *np;
272
 
 
273
 
        if (count == 0) return;
274
 
        l = strlen(pp = par[0]);
275
 
 
276
 
        if (namesamen(pp, "make-vhdl", l) == 0)
277
 
        {
278
 
                if (count >= 2)
279
 
                {
280
 
                        np = getnodeproto(par[1]);
281
 
                        if (np == NONODEPROTO)
282
 
                        {
283
 
                                ttyputerr(_("No facet named %s"), par[1]);
284
 
                                return;
285
 
                        }
286
 
                        if (np->primindex != 0)
287
 
                        {
288
 
                                ttyputerr(M_("Can only convert facets to VHDL, not primitives"));
289
 
                                return;
290
 
                        }
291
 
                } else
292
 
                {
293
 
                        np = getcurfacet();
294
 
                        if (np == NONODEPROTO)
295
 
                        {
296
 
                                ttyputerr(_("No current facet"));
297
 
                                return;
298
 
                        }
299
 
                }
300
 
                begintraversehierarchy();
301
 
                vhdl_convertfacet(np, TRUE);
302
 
 
303
 
                return;
304
 
        }
305
 
 
306
 
        if (namesamen(pp, "compile-now", l) == 0)
307
 
        {
308
 
                np = getcurfacet();
309
 
                if (np == NONODEPROTO)
310
 
                {
311
 
                        ttyputerr(_("Must be editing a cell"));
312
 
                        return;
313
 
                }
314
 
 
315
 
                (void)vhdl_compile(np);
316
 
                return;
317
 
        }
318
 
 
319
 
        if (namesamen(pp, "library", l) == 0)
320
 
        {
321
 
                if (count <= 1)
322
 
                {
323
 
                        ttyputusage("telltool vhdl-compiler library LIBRARY");
324
 
                        return;
325
 
                }
326
 
                vhdl_lib = getlibrary(par[1]);
327
 
                if (vhdl_lib == NOLIBRARY)
328
 
                {
329
 
                        ttyputerr(_("Cannot find library %s"), par[1]);
330
 
                        return;
331
 
                }
332
 
                ttyputverbose(M_("Library %s will be used for behavioral descriptions"), par[1]);
333
 
                return;
334
 
        }
335
 
 
336
 
        if (namesamen(pp, "vhdl-on-disk", l) == 0)
337
 
        {
338
 
                setvalkey((INTBIG)vhdl_tool, VTOOL, vhdl_vhdlondiskkey, 1, VINTEGER);
339
 
                ttyputverbose(M_("VHDL will be kept in separate disk files"));
340
 
                return;
341
 
        }
342
 
 
343
 
        if (namesamen(pp, "netlist-on-disk", l) == 0)
344
 
        {
345
 
                setvalkey((INTBIG)vhdl_tool, VTOOL, vhdl_netlistondiskkey, 1, VINTEGER);
346
 
                ttyputverbose(M_("Netlists will be kept in separate disk files"));
347
 
                return;
348
 
        }
349
 
 
350
 
        if (namesamen(pp, "warn", l) == 0)
351
 
        {
352
 
                vhdl_warnflag = TRUE;
353
 
                ttyputverbose(M_("VHDL compiler will display warnings"));
354
 
                return;
355
 
        }
356
 
 
357
 
        if (namesamen(pp, "external", l) == 0)
358
 
        {
359
 
                vhdl_externentities = TRUE;
360
 
                ttyputverbose(M_("VHDL compiler will allow external references"));
361
 
                return;
362
 
        }
363
 
 
364
 
        if (namesamen(pp, "not", l) == 0)
365
 
        {
366
 
                if (count <= 1)
367
 
                {
368
 
                        ttyputusage("telltool vhdl-compiler not OPTION");
369
 
                        return;
370
 
                }
371
 
                l = strlen(pp = par[1]);
372
 
                if (namesamen(pp, "warn", l) == 0)
373
 
                {
374
 
                        vhdl_warnflag = FALSE;
375
 
                        ttyputverbose(M_("VHDL compiler will not display warnings"));
376
 
                        return;
377
 
                }
378
 
                if (namesamen(pp, "external", l) == 0)
379
 
                {
380
 
                        vhdl_externentities = FALSE;
381
 
                        ttyputverbose(M_("VHDL compiler will not allow external references"));
382
 
                        return;
383
 
                }
384
 
                if (namesamen(pp, "vhdl-on-disk", l) == 0)
385
 
                {
386
 
                        setvalkey((INTBIG)vhdl_tool, VTOOL, vhdl_vhdlondiskkey, 0, VINTEGER);
387
 
                        ttyputverbose(M_("VHDL will be kept in facets"));
388
 
                        return;
389
 
                }
390
 
                if (namesamen(pp, "netlist-on-disk", l) == 0)
391
 
                {
392
 
                        setvalkey((INTBIG)vhdl_tool, VTOOL, vhdl_netlistondiskkey, 0, VINTEGER);
393
 
                        ttyputverbose(M_("Netlists will be kept in facets"));
394
 
                        return;
395
 
                }
396
 
                ttyputbadusage("telltool vhdl-compiler not");
397
 
                return;
398
 
        }
399
 
 
400
 
        if (namesamen(pp, "output-format", l) == 0)
401
 
        {
402
 
                if (count <= 1)
403
 
                {
404
 
                        ttyputusage("telltool vhdl-compiler output-format FORMAT");
405
 
                        return;
406
 
                }
407
 
                l = strlen(pp = par[1]);
408
 
                if (namesamen(pp, "netlisp", l) == 0)
409
 
                {
410
 
                        vhdl_target = TARGET_NETLISP;
411
 
                        ttyputverbose(M_("VHDL compiles to net lisp"));
412
 
                        return;
413
 
                }
414
 
                if (namesamen(pp, "als", l) == 0 && l >= 1)
415
 
                {
416
 
                        vhdl_target = TARGET_ALS;
417
 
                        ttyputverbose(M_("VHDL compiles to ALS simulation"));
418
 
                        return;
419
 
                }
420
 
                if (namesamen(pp, "quisc", l) == 0 && l >= 3)
421
 
                {
422
 
                        vhdl_target = TARGET_QUISC;
423
 
                        ttyputverbose(M_("VHDL compiles to QUISC place-and-route"));
424
 
                        return;
425
 
                }
426
 
                if (namesamen(pp, "silos", l) == 0)
427
 
                {
428
 
                        vhdl_target = TARGET_SILOS;
429
 
                        ttyputverbose(M_("VHDL compiles to SILOS simulation"));
430
 
                        return;
431
 
                }
432
 
                if (namesamen(pp, "rsim", l) == 0)
433
 
                {
434
 
                        vhdl_target = TARGET_RSIM;
435
 
                        ttyputverbose(M_("VHDL compiles to RSIM simulation"));
436
 
                        return;
437
 
                }
438
 
                ttyputbadusage("telltool vhdl-compiler output-format");
439
 
                return;
440
 
        }
441
 
 
442
 
        ttyputbadusage("telltool vhdl-compiler");
443
 
}
444
 
 
445
 
void vhdl_slice(void)
446
 
{
447
 
        REGISTER NODEPROTO *np;
448
 
 
449
 
        np = getcurfacet();
450
 
        if (np == NONODEPROTO)
451
 
        {
452
 
                ttyputerr(_("Must be editing a cell"));
453
 
                toolturnoff(vhdl_tool, FALSE);
454
 
                return;
455
 
        }
456
 
 
457
 
        (void)vhdl_compile(np);
458
 
 
459
 
        toolturnoff(vhdl_tool, FALSE);
460
 
        ttyputmsg(_("VHDL compiler turned off"));
461
 
}
462
 
 
463
 
/*
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
471
 
 *  "end-input"
472
 
 *
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
476
 
 *  "end-output"
477
 
 */
478
 
INTBIG vhdl_request(char *command, va_list ap)
479
 
{
480
 
        INTBIG i, len;
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;
487
 
        REGISTER VIEW *view;
488
 
 
489
 
        var = getvalkey((INTBIG)vhdl_tool, VTOOL, VINTEGER, vhdl_vhdlondiskkey);
490
 
        vhdlondisk = FALSE;
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;
495
 
 
496
 
        if (namesame(command, "begin-vhdl-input") == 0)
497
 
        {
498
 
                /* get the arguments (1=facet, 2=source) */
499
 
                arg1 = va_arg(ap, INTBIG);
500
 
                arg2 = va_arg(ap, INTBIG);
501
 
 
502
 
                return(vhdl_startinput((NODEPROTO *)arg1, io_filetypevhdl, vhdlondisk,
503
 
                        (char **)arg2, &vhdldate));
504
 
        }
505
 
 
506
 
        if (namesame(command, "begin-netlist-input") == 0)
507
 
        {
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);
512
 
 
513
 
                return(vhdl_startinput((NODEPROTO *)arg1, arg2, netlistondisk,
514
 
                        (char **)arg3, &netlistdate));
515
 
        }
516
 
 
517
 
        if (namesame(command, "get-line") == 0)
518
 
        {
519
 
                /* get the arguments (1=buffer) */
520
 
                arg1 = va_arg(ap, INTBIG);
521
 
 
522
 
                return(vhdl_getnextline((char *)arg1));
523
 
        }
524
 
 
525
 
        if (namesame(command, "end-input") == 0)
526
 
        {
527
 
                return(vhdl_endinput());
528
 
        }
529
 
 
530
 
        if (namesame(command, "want-netlist-input") == 0)
531
 
        {
532
 
                /* get the arguments (1=facet, 2=filetype) */
533
 
                arg1 = va_arg(ap, INTBIG);
534
 
                arg2 = va_arg(ap, INTBIG);
535
 
 
536
 
                if (arg2 == sim_filetypequisc)
537
 
                {
538
 
                        view = el_netlistquiscview;   vhdl_target = TARGET_QUISC;
539
 
                } else if (arg2 == sim_filetypeals)
540
 
                {
541
 
                        view = el_netlistalsview;     vhdl_target = TARGET_ALS;
542
 
                } else if (arg2 == sim_filetypenetlisp)
543
 
                {
544
 
                        view = el_netlistnetlispview; vhdl_target = TARGET_NETLISP;
545
 
                } else if (arg2 == sim_filetypesilos)
546
 
                {
547
 
                        view = el_netlistsilosview;   vhdl_target = TARGET_SILOS;
548
 
                } else if (arg2 == sim_filetypersim)
549
 
                {
550
 
                        view = el_netlistrsimview;    vhdl_target = TARGET_RSIM;
551
 
                }
552
 
 
553
 
                /* must have a valid netlist */
554
 
                orignp = (NODEPROTO *)arg1;
555
 
                i = vhdl_startinput(orignp, arg2, netlistondisk, &intended, &netlistdate);
556
 
                vhdl_endinput();
557
 
                if (i == 0)
558
 
                {
559
 
                        /* got netlist: make sure it is more recent than any VHDL or layout */
560
 
                        if (orignp->cellview != view)
561
 
                        {
562
 
                                /* determine date of associated VHDL */
563
 
                                if (vhdl_startinput(orignp, io_filetypevhdl, vhdlondisk, &intended,
564
 
                                        &vhdldate) == 0)
565
 
                                {
566
 
                                        if (netlistdate < vhdldate) i = 1;
567
 
 
568
 
                                        /* if original is not VHDL, ensure that VHDL comes from original */
569
 
                                        if (orignp->cellview != el_vhdlview)
570
 
                                        {
571
 
                                                if (vhdl_getnextline(buffer) != 0)
572
 
                                                {
573
 
                                                        desired = "-- VHDL automatically generated from facet ";
574
 
                                                        len = strlen(desired);
575
 
                                                        if (strncmp(buffer, desired, len) == 0)
576
 
                                                        {
577
 
                                                                if (strcmp(&buffer[len], describenodeproto(orignp)) != 0) i = 1;
578
 
                                                        }
579
 
                                                }
580
 
                                        }
581
 
                                }
582
 
                                vhdl_endinput();
583
 
 
584
 
                                /* if original is not VHDL, check all facets for recency */
585
 
                                if (orignp->cellview != el_vhdlview && i == 0)
586
 
                                {
587
 
                                        /* check all in cell for recency */
588
 
                                        for(np = orignp->cell->firstincell; np != NONODEPROTO; np = np->nextincell)
589
 
                                                if (netlistdate < np->revisiondate)
590
 
                                        {
591
 
                                                i = 1;
592
 
                                                break;
593
 
                                        }
594
 
                                        if (i == 0)
595
 
                                        {
596
 
                                                if (vhdl_morerecentcontents(orignp, netlistdate)) i = 1;
597
 
                                        }
598
 
                                }
599
 
                        }
600
 
                }
601
 
 
602
 
                if (i != 0)
603
 
                {
604
 
                        /* no valid netlist: look for VHDL */
605
 
                        i = vhdl_startinput(orignp, io_filetypevhdl, vhdlondisk, &intended, &vhdldate);
606
 
 
607
 
                        /* if original is not VHDL, ensure that VHDL comes from original */
608
 
                        if (i == 0 && orignp->cellview != el_vhdlview)
609
 
                        {
610
 
                                if (vhdl_getnextline(buffer) != 0)
611
 
                                {
612
 
                                        desired = "-- VHDL automatically generated from facet ";
613
 
                                        len = strlen(desired);
614
 
                                        if (strncmp(buffer, desired, len) == 0)
615
 
                                        {
616
 
                                                if (strcmp(&buffer[len], describenodeproto(orignp)) != 0) i = 1;
617
 
                                        }
618
 
                                }
619
 
                        }
620
 
                        vhdl_endinput();
621
 
                        if (i == 0)
622
 
                        {
623
 
                                /* got VHDL: make sure it is more recent than any layout */
624
 
                                if (orignp->cellview != el_vhdlview)
625
 
                                {
626
 
                                        /* check all in cell for recency */
627
 
                                        for(np = orignp->cell->firstincell; np != NONODEPROTO; np = np->nextincell)
628
 
                                                if (vhdldate < np->revisiondate)
629
 
                                        {
630
 
                                                i = 1;
631
 
                                                break;
632
 
                                        }
633
 
                                        if (i == 0)
634
 
                                        {
635
 
                                                if (vhdl_morerecentcontents(orignp, vhdldate)) i = 1;
636
 
                                        }
637
 
                                }
638
 
                        }
639
 
                        if (i != 0)
640
 
                        {
641
 
                                /* no valid VHDL: convert facet */
642
 
                                np = (NODEPROTO *)arg1;
643
 
                                begintraversehierarchy();
644
 
                                vhdl_convertfacet(np, FALSE);
645
 
                        }
646
 
 
647
 
                        /* compile VHDL to netlist */
648
 
                        if (vhdl_compile(getcurfacet())) return(1);
649
 
                }
650
 
                return(0);
651
 
        }
652
 
 
653
 
        if (namesame(command, "begin-vhdl-output") == 0)
654
 
        {
655
 
                /* get the arguments (1=facet, 2=source) */
656
 
                arg1 = va_arg(ap, INTBIG);
657
 
                arg2 = va_arg(ap, INTBIG);
658
 
 
659
 
                return(vhdl_startoutput((NODEPROTO *)arg1, io_filetypevhdl, vhdlondisk,
660
 
                        (char **)arg2));
661
 
        }
662
 
 
663
 
        if (namesame(command, "put-line") == 0)
664
 
        {
665
 
                /* get the arguments */
666
 
                arg1 = va_arg(ap, INTBIG);
667
 
                arg2 = va_arg(ap, INTBIG);
668
 
                arg3 = va_arg(ap, INTBIG);
669
 
 
670
 
                vhdl_print((char *)arg1, (char *)arg2, (char *)arg3);
671
 
                return(0);
672
 
        }
673
 
 
674
 
        if (namesame(command, "end-output") == 0)
675
 
        {
676
 
                return(vhdl_endoutput());
677
 
        }
678
 
        return(1);
679
 
}
680
 
 
681
 
/*
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.
684
 
 */
685
 
BOOLEAN vhdl_morerecentcontents(NODEPROTO *np, UINTBIG dateoffile)
686
 
{
687
 
        REGISTER NODEINST *ni;
688
 
        REGISTER NODEPROTO *subnp;
689
 
 
690
 
        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
691
 
        {
692
 
                subnp = ni->proto;
693
 
                if (subnp->primindex != 0) continue;
694
 
 
695
 
                /* ignore recursive references (showing icon in contents) */
696
 
                if (subnp->cell == np->cell) continue;
697
 
                if (subnp->cellview == el_iconview)
698
 
                {
699
 
                        subnp = contentsview(subnp);
700
 
                        if (subnp == NONODEPROTO) continue;
701
 
                }
702
 
                if (dateoffile < subnp->revisiondate) return(TRUE);
703
 
                if (vhdl_morerecentcontents(subnp, dateoffile)) return(TRUE);
704
 
        }
705
 
        return(FALSE);
706
 
}
707
 
 
708
 
/****************************** GENERALIZED VHDL/NET I/O ******************************/
709
 
 
710
 
/*
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.
715
 
 */
716
 
INTBIG vhdl_startinput(NODEPROTO *np, INTBIG filetype, BOOLEAN diskflag, char **intended,
717
 
        UINTBIG *revisiondate)
718
 
{
719
 
        REGISTER NODEPROTO *onp;
720
 
        char *filename;
721
 
        REGISTER VIEW *view;
722
 
 
723
 
        if (np == NONODEPROTO || np->primindex != 0)
724
 
        {
725
 
                *intended = "NO CURRENT FACET";
726
 
                return(1);
727
 
        }
728
 
 
729
 
        if (filetype == io_filetypevhdl)
730
 
        {
731
 
                view = el_vhdlview;
732
 
        } else if (filetype == sim_filetypequisc)
733
 
        {
734
 
                view = el_netlistquiscview;
735
 
        } else if (filetype == sim_filetypeals)
736
 
        {
737
 
                view = el_netlistalsview;
738
 
        } else if (filetype == sim_filetypenetlisp)
739
 
        {
740
 
                view = el_netlistnetlispview;
741
 
        } else if (filetype == sim_filetypesilos)
742
 
        {
743
 
                view = el_netlistsilosview;
744
 
        } else if (filetype == sim_filetypersim)
745
 
        {
746
 
                view = el_netlistrsimview;
747
 
        }
748
 
 
749
 
        vhdl_fp = 0;
750
 
        vhdl_var = NOVARIABLE;
751
 
        if (diskflag)
752
 
        {
753
 
                /* attempt to open file */
754
 
                (void)initinfstr();
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);
760
 
        } else
761
 
        {
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)
767
 
                {
768
 
                        *intended = "CANNOT FIND FACET VIEW";
769
 
                        return(1);
770
 
                }
771
 
 
772
 
                (void)initinfstr();
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;
779
 
        }
780
 
        vhdl_linecount = 0;
781
 
        return(0);
782
 
}
783
 
 
784
 
INTBIG vhdl_endinput(void)
785
 
{
786
 
        if (vhdl_fp != 0)
787
 
        {
788
 
                xclose(vhdl_fp);
789
 
                vhdl_fp = 0;
790
 
        }
791
 
        if (vhdl_var != NOVARIABLE) vhdl_var = NOVARIABLE;
792
 
        return(0);
793
 
}
794
 
 
795
 
/*
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.
798
 
 */
799
 
INTBIG vhdl_getnextline(char *addr)
800
 
{
801
 
        BOOLEAN ret;
802
 
        REGISTER char *line;
803
 
 
804
 
        if (vhdl_fp != 0)
805
 
        {
806
 
                ret = xfgets(addr, MAXVHDLLINE-1, vhdl_fp);
807
 
                if (ret) return(0);
808
 
        } else if (vhdl_var != NOVARIABLE)
809
 
        {
810
 
                if (vhdl_linecount >= getlength(vhdl_var)) return(0);
811
 
                line = ((char **)vhdl_var->addr)[vhdl_linecount];
812
 
                if (strlen(line) >= MAXVHDLLINE)
813
 
                {
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;
818
 
                } else
819
 
                {
820
 
                        (void)strcpy(addr, line);
821
 
                }
822
 
        } else return(0);
823
 
        vhdl_linecount++;
824
 
        return(vhdl_linecount);
825
 
}
826
 
 
827
 
/*
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.
833
 
 */
834
 
INTBIG vhdl_startoutput(NODEPROTO *np, INTBIG filetype, BOOLEAN diskflag, char **intended)
835
 
{
836
 
        REGISTER char *prompt;
837
 
        char *truefile, *ext;
838
 
        REGISTER VIEW *view;
839
 
 
840
 
        if (filetype == io_filetypevhdl)
841
 
        {
842
 
                view = el_vhdlview;            ext = "vhdl";
843
 
        } else if (filetype == sim_filetypequisc)
844
 
        {
845
 
                view = el_netlistquiscview;    ext = "sci";
846
 
        } else if (filetype == sim_filetypeals)
847
 
        {
848
 
                view = el_netlistalsview;      ext = "net";
849
 
        } else if (filetype == sim_filetypenetlisp)
850
 
        {
851
 
                view = el_netlistnetlispview;  ext = "net";
852
 
        } else if (filetype == sim_filetypesilos)
853
 
        {
854
 
                view = el_netlistsilosview;    ext = "sil";
855
 
        } else if (filetype == sim_filetypersim)
856
 
        {
857
 
                view = el_netlistrsimview;     ext = "net";
858
 
        }
859
 
 
860
 
        vhdl_fp = 0;
861
 
        vhdl_facet = NONODEPROTO;
862
 
        if (diskflag)
863
 
        {
864
 
                /* attempt to open output file */
865
 
                (void)initinfstr();
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);
874
 
                if (vhdl_fp == 0)
875
 
                {
876
 
                        if (truefile == 0) return(-1);
877
 
                        return(1);
878
 
                }
879
 
        } else
880
 
        {
881
 
                /* make proper view of this cell */
882
 
                (void)initinfstr();
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);
892
 
        }
893
 
        return(0);
894
 
}
895
 
 
896
 
INTBIG vhdl_endoutput(void)
897
 
{
898
 
        if (vhdl_fp != 0)
899
 
        {
900
 
                xclose(vhdl_fp);
901
 
                vhdl_fp = 0;
902
 
        }
903
 
        if (vhdl_facet != NONODEPROTO)
904
 
        {
905
 
                stringarraytotextfacet(vhdl_stringarray, vhdl_facet, FALSE);
906
 
                killstringarray(vhdl_stringarray);
907
 
                vhdl_facet = NONODEPROTO;
908
 
        }
909
 
        return(0);
910
 
}
911
 
 
912
 
/*
913
 
 * Routine to write a formatted string to the current output file.
914
 
 */
915
 
void vhdl_printoneline(char *fstring, ...)
916
 
{
917
 
        char buff[4000];
918
 
        va_list ap;
919
 
 
920
 
        var_start(ap, fstring);
921
 
        evsnprintf(buff, 4000, fstring, ap);
922
 
        va_end(ap);
923
 
        if (vhdl_fp == 0) addtostringarray(vhdl_stringarray, buff); else
924
 
                xprintf(vhdl_fp, "%s\n", buff);
925
 
}
926
 
 
927
 
/*
928
 
 * Routine to write a formatted string to the current output file.
929
 
 */
930
 
void vhdl_print(char *fstring, ...)
931
 
{
932
 
        INTBIG i;
933
 
        char buff[4000], *sptr, save;
934
 
        va_list ap;
935
 
 
936
 
        var_start(ap, fstring);
937
 
        evsnprintf(buff, 4000, fstring, ap);
938
 
        va_end(ap);
939
 
        sptr = buff;
940
 
        while (strlen(sptr) > 70)
941
 
        {
942
 
                for(i=70; i>0; i--) if (isspace(sptr[i])) break;
943
 
                if (i <= 0) 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);
947
 
                sptr[i] = save;
948
 
                if (vhdl_target == TARGET_SILOS)
949
 
                {
950
 
                        i--;
951
 
                        sptr[i] = '+';
952
 
                }
953
 
                sptr = &sptr[i];
954
 
        }
955
 
        if (vhdl_fp == 0) addtostringarray(vhdl_stringarray, sptr); else
956
 
                xprintf(vhdl_fp, "%s\n", sptr);
957
 
}
958
 
 
959
 
/*
960
 
 * Routine to determine the revision date of facet "np", including any subfacets.
961
 
 */
962
 
UINTBIG vhdl_getfacetdate(NODEPROTO *np)
963
 
{
964
 
        REGISTER UINTBIG mostrecent, subfacetdate;
965
 
        REGISTER NODEINST *ni;
966
 
 
967
 
        mostrecent = np->revisiondate;
968
 
        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
969
 
        {
970
 
                if (ni->proto->primindex != 0) continue;
971
 
 
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;
976
 
        }
977
 
        return(mostrecent);
978
 
}
979
 
 
980
 
/****************************** GENERATION ******************************/
981
 
 
982
 
/*
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.
986
 
 */
987
 
void vhdl_convertfacet(NODEPROTO *np, BOOLEAN force)
988
 
{
989
 
        REGISTER NODEPROTO *npvhdl, *onp;
990
 
        REGISTER LIBRARY *lib;
991
 
        REGISTER INTBIG i, len;
992
 
        REGISTER BOOLEAN backannotate;
993
 
        BOOLEAN vhdlondisk;
994
 
        REGISTER UINTBIG dateoflayout;
995
 
        REGISTER VARIABLE *var;
996
 
        FILE *f;
997
 
        char *intended, *filename, *desired, *firstline;
998
 
 
999
 
        /* cannot make VHDL for facet with no ports */
1000
 
        if (np->firstportproto == NOPORTPROTO)
1001
 
        {
1002
 
                ttyputerr(_("Cannot convert facet %s to VHDL: it has no ports"), describenodeproto(np));
1003
 
                return;
1004
 
        }
1005
 
 
1006
 
        vhdlondisk = FALSE;
1007
 
        var = getvalkey((INTBIG)vhdl_tool, VTOOL, VINTEGER, vhdl_vhdlondiskkey);
1008
 
        if (var != NOVARIABLE && var->addr != 0) vhdlondisk = TRUE;
1009
 
 
1010
 
        if (!force)
1011
 
        {
1012
 
                /* determine most recent change to this or any subfacet */
1013
 
                dateoflayout = vhdl_getfacetdate(np);
1014
 
 
1015
 
                /* if there is already VHDL that is newer, stop now */
1016
 
                if (vhdlondisk)
1017
 
                {
1018
 
                        /* look for the disk file */
1019
 
                        f = xopen(np->cell->cellname, io_filetypevhdl, "", &filename);
1020
 
                        if (f != NULL)
1021
 
                        {
1022
 
                                xclose(f);
1023
 
                                if (filedate(filename) >= dateoflayout) return;
1024
 
                        }
1025
 
                } else
1026
 
                {
1027
 
                        /* look for the facet */
1028
 
                        npvhdl = anyview(np, el_vhdlview);
1029
 
                        if (npvhdl != NONODEPROTO)
1030
 
                        {
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)
1034
 
                                {
1035
 
                                        firstline = ((char **)var->addr)[0];
1036
 
                                        desired = "-- VHDL automatically generated from facet ";
1037
 
                                        len = strlen(desired);
1038
 
                                        if (strncmp(firstline, desired, len) == 0)
1039
 
                                        {
1040
 
                                                if (strcmp(&desired[len], describenodeproto(np)) != 0)
1041
 
                                                        dateoflayout = npvhdl->revisiondate + 1;
1042
 
                                        }
1043
 
                                }
1044
 
 
1045
 
                                if (npvhdl->revisiondate >= dateoflayout) return;
1046
 
                        }
1047
 
                }
1048
 
        }
1049
 
 
1050
 
        /* begin output of VHDL */
1051
 
        i = vhdl_startoutput(np, io_filetypevhdl, vhdlondisk, &intended);
1052
 
        if (i != 0)
1053
 
        {
1054
 
                if (i > 0) ttyputerr(_("Cannot write %s"), intended);
1055
 
                return;
1056
 
        }
1057
 
        ttyputmsg(_("Converting layout in facet %s, writing VHDL to %s"), describenodeproto(np),
1058
 
                intended);
1059
 
 
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)
1063
 
                        onp->temp1 = 0;
1064
 
        backannotate = vhdl_generatevhdl(np);
1065
 
        if (backannotate)
1066
 
                ttyputmsg(_("Back-annotation information has been added (library must be saved)"));
1067
 
 
1068
 
        /* that's it */
1069
 
        vhdl_endoutput();
1070
 
}
1071
 
 
1072
 
BOOLEAN vhdl_generatevhdl(NODEPROTO *np)
1073
 
{
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;
1079
 
        INTBIG special;
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;
1086
 
 
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;
1091
 
 
1092
 
        /* indicate the source of this VHDL */
1093
 
        (void)initinfstr();
1094
 
        (void)addstringtoinfstr("-- VHDL automatically generated from facet ");
1095
 
        (void)addstringtoinfstr(describenodeproto(np));
1096
 
        vhdl_printoneline(returninfstr());
1097
 
 
1098
 
        /* build the "entity" line */
1099
 
        (void)initinfstr();
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());
1106
 
 
1107
 
        /* add the "end" line */
1108
 
        (void)initinfstr();
1109
 
        (void)addstringtoinfstr("  end ");
1110
 
        vhdl_addstring(np->cell->cellname, NONODEPROTO);
1111
 
        (void)addstringtoinfstr(";");
1112
 
        vhdl_print(returninfstr());
1113
 
 
1114
 
        /* now write the "architecture" line */
1115
 
        (void)initinfstr();
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());
1122
 
 
1123
 
        /* enumerate negated arcs */
1124
 
        instnum = 1;
1125
 
        for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
1126
 
        {
1127
 
                if ((ai->userbits&ISNEGATED) == 0) continue;
1128
 
                ai->temp1 = instnum;
1129
 
                instnum++;
1130
 
        }
1131
 
 
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)
1135
 
        {
1136
 
                vhdl_componentarray = newstringarray(vhdl_tool->cluster);
1137
 
                if (vhdl_componentarray == 0) return(backannotate);
1138
 
        }
1139
 
        clearstrings(vhdl_componentarray);
1140
 
        componentlist = getstringarray(vhdl_componentarray, &componentcount);
1141
 
        instnum = 1;
1142
 
        gotinverters = 0;
1143
 
        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1144
 
        {
1145
 
                if (ni->proto->primindex == 0)
1146
 
                {
1147
 
                        /* ignore recursive references (showing icon in contents) */
1148
 
                        if (ni->proto->cell == np->cell) continue;
1149
 
                }
1150
 
                pt = vhdl_primname(ni, &special);
1151
 
                if (pt[0] == 0) continue;
1152
 
 
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++;
1156
 
 
1157
 
                /* write only once per prototype */
1158
 
                if (special == BLOCKINVERTER)
1159
 
                {
1160
 
                        gotinverters = 1;
1161
 
                        continue;
1162
 
                }
1163
 
                if (special == BLOCKNAND)
1164
 
                {
1165
 
                        i = atoi(&pt[4]);
1166
 
                        if (i <= MAXINPUTS) gotnand[i]++; else
1167
 
                                ttyputerr("Cannot handle %ld-input NAND, limit is %d", i, MAXINPUTS);
1168
 
                        continue;
1169
 
                }
1170
 
                if (special == BLOCKNOR)
1171
 
                {
1172
 
                        i = atoi(&pt[3]);
1173
 
                        if (i <= MAXINPUTS) gotnor[i]++; else
1174
 
                                ttyputerr("Cannot handle %ld-input NOR, limit is %d", i, MAXINPUTS);
1175
 
                        continue;
1176
 
                }
1177
 
                if (special == BLOCKXNOR)
1178
 
                {
1179
 
                        i = atoi(&pt[3]);
1180
 
                        if (i <= MAXINPUTS) gotxnor[i]++; else
1181
 
                                ttyputerr("Cannot handle %ld-input XNOR, limit is %d", i, MAXINPUTS);
1182
 
                        continue;
1183
 
                }
1184
 
 
1185
 
                /* ignore component with no ports */
1186
 
                if (ni->proto->firstportproto == NOPORTPROTO) continue;
1187
 
 
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;
1192
 
 
1193
 
                /* new component: add to the list */
1194
 
                addtostringarray(vhdl_componentarray, pt);
1195
 
                componentlist = getstringarray(vhdl_componentarray, &componentcount);
1196
 
 
1197
 
                (void)initinfstr();
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;");
1205
 
        }
1206
 
 
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)
1210
 
        {
1211
 
                gotinverters = 1;
1212
 
                break;
1213
 
        }
1214
 
        if (gotinverters != 0)
1215
 
        {
1216
 
                vhdl_print("  component inverter port(a: in BIT; y: out BIT);");
1217
 
                vhdl_print("    end component;");
1218
 
        }
1219
 
        for(i=0; i<MAXINPUTS; i++)
1220
 
        {
1221
 
                if (gotnand[i] != 0)
1222
 
                {
1223
 
                        (void)initinfstr();
1224
 
                        (void)addstringtoinfstr("  component nand");
1225
 
                        (void)sprintf(line, "%ld", i);
1226
 
                        (void)addstringtoinfstr(line);
1227
 
                        (void)addstringtoinfstr(" port(");
1228
 
                        for(j=1; j<=i; j++)
1229
 
                        {
1230
 
                                if (j > 1) (void)addstringtoinfstr(", ");
1231
 
                                (void)sprintf(line, "a%ld", j);
1232
 
                                (void)addstringtoinfstr(line);
1233
 
                        }
1234
 
                        (void)addstringtoinfstr(": in BIT; y: out BIT);");
1235
 
                        vhdl_print(returninfstr());
1236
 
                        vhdl_print("    end component;");
1237
 
                }
1238
 
                if (gotnor[i] != 0)
1239
 
                {
1240
 
                        (void)initinfstr();
1241
 
                        (void)addstringtoinfstr("  component nor");
1242
 
                        (void)sprintf(line, "%ld", i);
1243
 
                        (void)addstringtoinfstr(line);
1244
 
                        (void)addstringtoinfstr(" port(");
1245
 
                        for(j=1; j<=i; j++)
1246
 
                        {
1247
 
                                if (j > 1) (void)addstringtoinfstr(", ");
1248
 
                                (void)sprintf(line, "a%ld", j);
1249
 
                                (void)addstringtoinfstr(line);
1250
 
                        }
1251
 
                        (void)addstringtoinfstr(": in BIT; y: out BIT);");
1252
 
                        vhdl_print(returninfstr());
1253
 
                        vhdl_print("    end component;");
1254
 
                }
1255
 
                if (gotxnor[i] != 0)
1256
 
                {
1257
 
                        (void)initinfstr();
1258
 
                        (void)addstringtoinfstr("  component xnor");
1259
 
                        (void)sprintf(line, "%ld", i);
1260
 
                        (void)addstringtoinfstr(line);
1261
 
                        (void)addstringtoinfstr(" port(");
1262
 
                        for(j=1; j<=i; j++)
1263
 
                        {
1264
 
                                if (j > 1) (void)addstringtoinfstr(", ");
1265
 
                                (void)sprintf(line, "a%ld", j);
1266
 
                                (void)addstringtoinfstr(line);
1267
 
                        }
1268
 
                        (void)addstringtoinfstr(": in BIT; y: out BIT);");
1269
 
                        vhdl_print(returninfstr());
1270
 
                        vhdl_print("    end component;");
1271
 
                }
1272
 
        }
1273
 
 
1274
 
        /* write internal nodes */
1275
 
        for(net = np->firstnetwork; net != NONETWORK; net = net->nextnetwork)
1276
 
                net->temp1 = 0;
1277
 
        for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
1278
 
        {
1279
 
                pp->network->temp1 = 1;
1280
 
                if (pp->network->signals > 1)
1281
 
                {
1282
 
                        for(i=0; i<pp->network->signals; i++)
1283
 
                                pp->network->networklist[i]->temp1 = 1;
1284
 
                }
1285
 
        }
1286
 
        first = 0;
1287
 
        for(net = np->firstnetwork; net != NONETWORK; net = net->nextnetwork)
1288
 
        {
1289
 
                if (net->portcount != 0 || net->buslinkcount != 0) continue;
1290
 
 
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++)
1294
 
                {
1295
 
                        if (net->signals <= 1)
1296
 
                        {
1297
 
                                if (net->namecount > 0) pt = net->netname; else
1298
 
                                        pt = describenetwork(net);
1299
 
                                net->temp1 = 1;
1300
 
                        } else
1301
 
                        {
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]);
1306
 
                        }
1307
 
                        if (first == 0)
1308
 
                        {
1309
 
                                (void)initinfstr();
1310
 
                                (void)addstringtoinfstr("  signal ");
1311
 
                                linelen = 9;
1312
 
                        } else
1313
 
                        {
1314
 
                                (void)addstringtoinfstr(", ");
1315
 
                                linelen += 2;
1316
 
                        }
1317
 
                        first = 1;
1318
 
                        if (linelen + strlen(pt) > 80)
1319
 
                        {
1320
 
                                vhdl_print(returninfstr());
1321
 
                                (void)initinfstr();
1322
 
                                (void)addstringtoinfstr("    ");
1323
 
                                linelen = 4;
1324
 
                        }
1325
 
                        vhdl_addstring(pt, np);
1326
 
                        linelen += strlen(pt);
1327
 
                }
1328
 
        }
1329
 
        if (first != 0)
1330
 
        {
1331
 
                (void)addstringtoinfstr(": BIT;");
1332
 
                vhdl_print(returninfstr());
1333
 
        }
1334
 
 
1335
 
        /* write pseudo-internal nodes for all negated arcs */
1336
 
        first = 0;
1337
 
        for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
1338
 
        {
1339
 
                if ((ai->userbits&ISNEGATED) == 0 || ai->temp1 == 0) continue;
1340
 
                if (first == 0)
1341
 
                {
1342
 
                        (void)initinfstr();
1343
 
                        (void)addstringtoinfstr("  signal ");
1344
 
                } else (void)addstringtoinfstr(", ");
1345
 
                (void)sprintf(line, "PINV%ld", ai->temp1);
1346
 
                (void)addstringtoinfstr(line);
1347
 
                first++;
1348
 
        }
1349
 
        if (first != 0)
1350
 
        {
1351
 
                (void)addstringtoinfstr(": BIT;");
1352
 
                vhdl_print(returninfstr());
1353
 
        }
1354
 
 
1355
 
        /* write the instances */
1356
 
        vhdl_print("begin");
1357
 
        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1358
 
        {
1359
 
                /* ignore component with no ports */
1360
 
                if (ni->proto->firstportproto == NOPORTPROTO) continue;
1361
 
 
1362
 
                if (ni->proto->primindex == 0)
1363
 
                {
1364
 
                        /* ignore recursive references (showing icon in contents) */
1365
 
                        if (ni->proto->cell == np->cell) continue;
1366
 
                }
1367
 
 
1368
 
                pt = vhdl_primname(ni, &special);
1369
 
                if (pt[0] == 0) continue;
1370
 
 
1371
 
                (void)initinfstr();
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
1375
 
                {
1376
 
                        ttyputerr("VHDL conversion warning: no name on node %s", describenodeinst(ni));
1377
 
                        (void)sprintf(line, "NODE%ld", (INTBIG)ni);
1378
 
                        (void)addstringtoinfstr(line);
1379
 
                }
1380
 
                (void)addstringtoinfstr(": ");
1381
 
                vhdl_addstring(pt, NONODEPROTO);
1382
 
 
1383
 
                (void)addstringtoinfstr(" port map(");
1384
 
                vhdl_addrealports(ni, special);
1385
 
                (void)addstringtoinfstr(");");
1386
 
                vhdl_print(returninfstr());
1387
 
        }
1388
 
 
1389
 
        /* write pseudo-nodes for all negated arcs */
1390
 
        for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
1391
 
        {
1392
 
                if ((ai->userbits&ISNEGATED) == 0 || ai->temp1 == 0) continue;
1393
 
                (void)initinfstr();
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)
1400
 
                {
1401
 
                        (void)sprintf(line, "PINV%ld", ai->temp1);
1402
 
                        (void)addstringtoinfstr(line);
1403
 
                        (void)addstringtoinfstr(", ");
1404
 
                        net = ai->network;
1405
 
                        if (net->namecount > 0) vhdl_addstring(net->netname, np); else
1406
 
                                (void)addstringtoinfstr(describenetwork(net));
1407
 
                } else
1408
 
                {
1409
 
                        net = ai->network;
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);
1415
 
                }
1416
 
                (void)addstringtoinfstr(");");
1417
 
                vhdl_print(returninfstr());
1418
 
        }
1419
 
 
1420
 
        /* write the end of the body */
1421
 
        (void)initinfstr();
1422
 
        (void)addstringtoinfstr("end ");
1423
 
        vhdl_addstring(np->cell->cellname, NONODEPROTO);
1424
 
        (void)addstringtoinfstr("_BODY;");
1425
 
        vhdl_print(returninfstr());
1426
 
        vhdl_print("");
1427
 
 
1428
 
        /* finally, generate VHDL for all subfacets */
1429
 
        np->temp1 = 1;
1430
 
        for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1431
 
        {
1432
 
                if (ni->proto->primindex != 0) continue;
1433
 
 
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;
1440
 
 
1441
 
                /* ignore component with no ports */
1442
 
                if (cnp->firstportproto == NOPORTPROTO) continue;
1443
 
 
1444
 
                /* if ALS, see if this facet is in the reference library */
1445
 
                if (vhdl_lib != NOLIBRARY && vhdl_target == TARGET_ALS)
1446
 
                {
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;
1451
 
                }
1452
 
 
1453
 
                downhierarchy(ni, 0);
1454
 
                if (vhdl_generatevhdl(cnp)) backannotate = TRUE;
1455
 
                uphierarchy();
1456
 
        }
1457
 
        return(backannotate);
1458
 
}
1459
 
 
1460
 
void vhdl_addrealports(NODEINST *ni, INTBIG special)
1461
 
{
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;
1469
 
        char line[50];
1470
 
 
1471
 
        np = ni->proto;
1472
 
        cnp = contentsview(np);
1473
 
        if (cnp == NONODEPROTO) cnp = np;
1474
 
        first = 0;
1475
 
        for(pass = 0; pass < 5; pass++)
1476
 
        {
1477
 
                for(cpp = cnp->firstportproto; cpp != NOPORTPROTO; cpp = cpp->nextportproto)
1478
 
                {
1479
 
#ifdef IGNORE4PORTTRANSISTORS
1480
 
                        /* ignore the bias port of 4-port transistors */
1481
 
                        if (ni->proto == sch_transistor4prim)
1482
 
                        {
1483
 
                                if (namesame(cpp->protoname, "b") == 0) continue;
1484
 
                        }
1485
 
#endif
1486
 
                        if (cnp == np) pp = cpp; else
1487
 
                                pp = equivalentport(cnp, cpp, np);
1488
 
                        if (pass == 0)
1489
 
                        {
1490
 
                                /* must be an input port */
1491
 
                                if ((pp->userbits&STATEBITS) != INPORT) continue;
1492
 
                        }
1493
 
                        if (pass == 1)
1494
 
                        {
1495
 
                                /* must be an output port */
1496
 
                                if ((pp->userbits&STATEBITS) != OUTPORT) continue;
1497
 
                        }
1498
 
                        if (pass == 2)
1499
 
                        {
1500
 
                                /* must be an output port */
1501
 
                                if ((pp->userbits&STATEBITS) != PWRPORT) continue;
1502
 
                        }
1503
 
                        if (pass == 3)
1504
 
                        {
1505
 
                                /* must be an output port */
1506
 
                                if ((pp->userbits&STATEBITS) != GNDPORT) continue;
1507
 
                        }
1508
 
                        if (pass == 4)
1509
 
                        {
1510
 
                                /* any other port type */
1511
 
                                if ((pp->userbits&STATEBITS) == INPORT || (pp->userbits&STATEBITS) == OUTPORT ||
1512
 
                                        (pp->userbits&STATEBITS) == PWRPORT || (pp->userbits&STATEBITS) == GNDPORT)
1513
 
                                                continue;
1514
 
                        }
1515
 
 
1516
 
                        if (special == BLOCKMOSTRAN)
1517
 
                        {
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;
1522
 
                        }
1523
 
                        if (special == BLOCKPOSLOGIC || special == BLOCKBUFFER || special == BLOCKINVERTER ||
1524
 
                                special == BLOCKNAND || special == BLOCKNOR || special == BLOCKXNOR)
1525
 
                        {
1526
 
                                /* ignore ports not named "a" or "y" */
1527
 
                                if (strcmp(pp->protoname, "a") != 0 && strcmp(pp->protoname, "y") != 0)
1528
 
                                {
1529
 
                                        pp->temp1 = 1;
1530
 
                                        continue;
1531
 
                                }
1532
 
                        }
1533
 
                        if (special == BLOCKFLOPTS || special == BLOCKFLOPDS)
1534
 
                        {
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)
1538
 
                                {
1539
 
                                        pp->temp1 = 1;
1540
 
                                        continue;
1541
 
                                }
1542
 
                        }
1543
 
                        if (special == BLOCKFLOPTR || special == BLOCKFLOPDR)
1544
 
                        {
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)
1548
 
                                {
1549
 
                                        pp->temp1 = 1;
1550
 
                                        continue;
1551
 
                                }
1552
 
                        }
1553
 
 
1554
 
                        /* if multiple connections, get them all */
1555
 
                        if ((pp->userbits&PORTISOLATED) != 0)
1556
 
                        {
1557
 
                                for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1558
 
                                {
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)
1564
 
                                        {
1565
 
                                                if ((ai->end[0].portarcinst == pi && (ai->userbits&REVERSEEND) == 0) ||
1566
 
                                                        (ai->end[1].portarcinst == pi && (ai->userbits&REVERSEEND) != 0))
1567
 
                                                {
1568
 
                                                        (void)sprintf(line, "PINV%ld", ai->temp1);
1569
 
                                                        (void)addstringtoinfstr(line);
1570
 
                                                        continue;
1571
 
                                                }
1572
 
                                        }
1573
 
                                        net = ai->network;
1574
 
                                        if (net->namecount > 0) vhdl_addstring(net->netname, ni->parent); else
1575
 
                                                (void)addstringtoinfstr(describenetwork(net));
1576
 
                                }
1577
 
                                continue;
1578
 
                        }
1579
 
 
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)
1584
 
                        {
1585
 
                                ai = pi->conarcinst;
1586
 
                                if (((ai->proto->userbits&AFUNCTION)>>AFUNCTIONSH) != APNONELEC)
1587
 
                                {
1588
 
                                        if (first != 0) (void)addstringtoinfstr(", ");   first = 1;
1589
 
                                        if ((ai->userbits&ISNEGATED) != 0 && ai->temp1 != 0)
1590
 
                                        {
1591
 
                                                if ((ai->end[0].portarcinst == pi && (ai->userbits&REVERSEEND) == 0) ||
1592
 
                                                        (ai->end[1].portarcinst == pi && (ai->userbits&REVERSEEND) != 0))
1593
 
                                                {
1594
 
                                                        (void)sprintf(line, "PINV%ld", ai->temp1);
1595
 
                                                        (void)addstringtoinfstr(line);
1596
 
                                                        continue;
1597
 
                                                }
1598
 
                                        }
1599
 
 
1600
 
                                        net = ai->network;
1601
 
                                        if (net->signals > 1)
1602
 
                                        {
1603
 
                                                for(i=0; i<net->signals; i++)
1604
 
                                                {
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));
1609
 
                                                }
1610
 
                                        } else
1611
 
                                        {
1612
 
                                                if (net->namecount > 0) vhdl_addstring(net->netname, ni->parent); else
1613
 
                                                        (void)addstringtoinfstr(describenetwork(net));
1614
 
                                        }
1615
 
                                        continue;
1616
 
                                }
1617
 
                        }
1618
 
 
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)
1623
 
                        {
1624
 
                                if (first != 0) (void)addstringtoinfstr(", ");   first = 1;
1625
 
                                vhdl_addstring(pe->exportproto->protoname, ni->parent);
1626
 
                                continue;
1627
 
                        }
1628
 
 
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));
1634
 
                }
1635
 
        }
1636
 
}
1637
 
 
1638
 
/*
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"
1654
 
 */
1655
 
char *vhdl_primname(NODEINST *ni, INTBIG *special)
1656
 
{
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;
1665
 
        static char pt[30];
1666
 
 
1667
 
        /* initialize */
1668
 
        if (tech_vhdl_names_key == 0) tech_vhdl_names_key = makekey("TECH_vhdl_names");
1669
 
 
1670
 
        /* facet instances are easy */
1671
 
        *special = BLOCKNORMAL;
1672
 
        if (ni->proto->primindex == 0) return(ni->proto->cell->cellname);
1673
 
 
1674
 
        /* get the primitive function */
1675
 
        k = nodefunction(ni);
1676
 
        pt[0] = 0;
1677
 
        switch (k)
1678
 
        {
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;
1684
 
                        break;
1685
 
                case NPTRADMOS:   case NPTRA4DMOS:
1686
 
                        (void)strcpy(pt, "DMOStran");
1687
 
                        *special = BLOCKMOSTRAN;
1688
 
                        break;
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;
1694
 
                        break;
1695
 
                case NPTRANPN:    case NPTRA4NPN:
1696
 
                        (void)strcpy(pt, "NPNtran");
1697
 
                        break;
1698
 
                case NPTRAPNP:    case NPTRA4PNP:
1699
 
                        (void)strcpy(pt, "PNPtran");
1700
 
                        break;
1701
 
                case NPTRANJFET:  case NPTRA4NJFET:
1702
 
                        (void)strcpy(pt, "NJFET");
1703
 
                        break;
1704
 
                case NPTRAPJFET:  case NPTRA4PJFET:
1705
 
                        (void)strcpy(pt, "PJFET");
1706
 
                        break;
1707
 
                case NPTRADMES:   case NPTRA4DMES:
1708
 
                        (void)strcpy(pt, "DMEStran");
1709
 
                        break;
1710
 
                case NPTRAEMES:   case NPTRA4EMES:
1711
 
                        (void)strcpy(pt, "EMEStran");
1712
 
                        break;
1713
 
 
1714
 
                case NPFLIPFLOP:
1715
 
                        switch (ni->userbits&FFTYPE)
1716
 
                        {
1717
 
                                case FFTYPERS:
1718
 
                                        (void)strcpy(pt, "rsff");
1719
 
                                        *special = BLOCKFLOP;
1720
 
                                        break;
1721
 
                                case FFTYPEJK:
1722
 
                                        (void)strcpy(pt, "jkff");
1723
 
                                        *special = BLOCKFLOP;
1724
 
                                        break;
1725
 
                                case FFTYPED:
1726
 
                                        (void)strcpy(pt, "dsff");
1727
 
                                        *special = BLOCKFLOPDS;
1728
 
                                        for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1729
 
                                        {
1730
 
                                                if (namesame(pi->proto->protoname, "clear") == 0)
1731
 
                                                {
1732
 
                                                        (void)strcpy(pt, "drff");
1733
 
                                                        *special = BLOCKFLOPDR;
1734
 
                                                        break;
1735
 
                                                }
1736
 
                                        }
1737
 
                                        break;
1738
 
                                case FFTYPET:
1739
 
                                        (void)strcpy(pt, "tsff");
1740
 
                                        *special = BLOCKFLOPTS;
1741
 
                                        for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1742
 
                                        {
1743
 
                                                if (namesame(pi->proto->protoname, "clear") == 0)
1744
 
                                                {
1745
 
                                                        (void)strcpy(pt, "trff");
1746
 
                                                        *special = BLOCKFLOPTR;
1747
 
                                                        break;
1748
 
                                                }
1749
 
                                        }
1750
 
                                        break;
1751
 
                                default:
1752
 
                                        (void)strcpy(pt, "fflop");
1753
 
                                        *special = BLOCKFLOP;
1754
 
                                        break;
1755
 
                        }
1756
 
                        break;
1757
 
 
1758
 
                case NPBUFFER:
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)
1764
 
                        {
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;
1770
 
                        }
1771
 
                        if (pi != NOPORTARCINST)
1772
 
                        {
1773
 
                                for(ptr = str; *ptr != 0; ptr++) if (*ptr == '/') break;
1774
 
                                if (*ptr == '/') strcpy(pt, &ptr[1]); else
1775
 
                                        strcpy(pt, str);
1776
 
                                *special = BLOCKINVERTER;
1777
 
                                ai->temp1 = 0;
1778
 
                        } else
1779
 
                        {
1780
 
                                strcpy(pt, str);
1781
 
                                for(ptr = pt; *ptr != 0; ptr++) if (*ptr == '/') break;
1782
 
                                if (*ptr == '/') *ptr = 0;                                      
1783
 
                        }
1784
 
                        break;
1785
 
                case NPGATEAND:
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];
1789
 
                        inport = isneg = 0;
1790
 
                        for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1791
 
                        {
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++;
1798
 
                        }
1799
 
                        if (isneg != 0)
1800
 
                        {
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;
1805
 
                                ai->temp1 = 0;
1806
 
                        } else
1807
 
                        {
1808
 
                                (void)sprintf(pt, str, inport);
1809
 
                                for(ptr = pt; *ptr != 0; ptr++) if (*ptr == '/') break;
1810
 
                                if (*ptr == '/') *ptr = 0;                                      
1811
 
                                *special = BLOCKPOSLOGIC;
1812
 
                        }
1813
 
                        break;
1814
 
                case NPGATEOR:
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];
1818
 
                        inport = isneg = 0;
1819
 
                        for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1820
 
                        {
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++;
1827
 
                        }
1828
 
                        if (isneg != 0)
1829
 
                        {
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;
1834
 
                                ai->temp1 = 0;
1835
 
                        } else
1836
 
                        {
1837
 
                                (void)sprintf(pt, str, inport);
1838
 
                                for(ptr = pt; *ptr != 0; ptr++) if (*ptr == '/') break;
1839
 
                                if (*ptr == '/') *ptr = 0;                                      
1840
 
                                *special = BLOCKPOSLOGIC;
1841
 
                        }
1842
 
                        break;
1843
 
                case NPGATEXOR:
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];
1847
 
                        inport = isneg = 0;
1848
 
                        for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1849
 
                        {
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++;
1856
 
                        }
1857
 
                        if (isneg != 0)
1858
 
                        {
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;
1863
 
                                ai->temp1 = 0;
1864
 
                        } else
1865
 
                        {
1866
 
                                (void)sprintf(pt, str, inport);
1867
 
                                for(ptr = pt; *ptr != 0; ptr++) if (*ptr == '/') break;
1868
 
                                if (*ptr == '/') *ptr = 0;                                      
1869
 
                                *special = BLOCKPOSLOGIC;
1870
 
                        }
1871
 
                        break;
1872
 
                case NPMUX:
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];
1876
 
                        inport = isneg = 0;
1877
 
                        inport = 0;
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);
1881
 
                        break;
1882
 
                case NPCONPOWER:
1883
 
                        strcpy(pt, "power");
1884
 
                        break;
1885
 
                case NPCONGROUND:
1886
 
                        strcpy(pt, "ground");
1887
 
                        break;
1888
 
        }
1889
 
        if (*pt == 0)
1890
 
        {
1891
 
                /* if the node has an export with power/ground, make it that */
1892
 
                for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
1893
 
                {
1894
 
                        pp = pe->exportproto;
1895
 
                        if (portispower(pp))
1896
 
                        {
1897
 
                                strcpy(pt, "power");
1898
 
                                break;
1899
 
                        }
1900
 
                        if (portisground(pp))
1901
 
                        {
1902
 
                                strcpy(pt, "ground");
1903
 
                                break;
1904
 
                        }
1905
 
                }
1906
 
        }
1907
 
        return(pt);
1908
 
}
1909
 
 
1910
 
/*
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.
1914
 
 */
1915
 
void vhdl_addstring(char *orig, NODEPROTO *environment)
1916
 
{
1917
 
        REGISTER char *pt;
1918
 
        REGISTER INTBIG len, nonalnum;
1919
 
        REGISTER NODEINST *ni;
1920
 
 
1921
 
        /* remove all nonVHDL characters while adding to current string */
1922
 
        nonalnum = 0;
1923
 
        for(pt = orig; *pt != 0; pt++)
1924
 
                if (isalnum(*pt)) (void)addtoinfstr(*pt); else
1925
 
        {
1926
 
                (void)addtoinfstr('_');
1927
 
                nonalnum++;
1928
 
        }
1929
 
 
1930
 
        /* if there were nonalphanumeric characters, this cannot be a VHDL keyword */
1931
 
        if (nonalnum == 0)
1932
 
        {
1933
 
                /* check for VHDL keyword clashes */
1934
 
                len = strlen(orig);
1935
 
                if (vhdl_iskeyword(orig, len) != NOVKEYWORD)
1936
 
                {
1937
 
                        (void)addstringtoinfstr("NV");
1938
 
                        return;
1939
 
                }
1940
 
 
1941
 
                /* "bit" isn't a keyword, but the compiler can't handle it */
1942
 
                if (namesame(orig, "bit") == 0)
1943
 
                {
1944
 
                        (void)addstringtoinfstr("NV");
1945
 
                        return;
1946
 
                }
1947
 
        }
1948
 
 
1949
 
        /* see if there is a name clash */
1950
 
        if (environment != NONODEPROTO)
1951
 
        {
1952
 
                for(ni = environment->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1953
 
                {
1954
 
                        if (ni->proto->primindex != 0) continue;
1955
 
                        if (namesame(orig, ni->proto->cell->cellname) == 0) break;
1956
 
                }
1957
 
                if (ni != NONODEINST)
1958
 
                {
1959
 
                        (void)addstringtoinfstr("NV");
1960
 
                        return;
1961
 
                }
1962
 
        }
1963
 
}
1964
 
 
1965
 
/*
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".
1976
 
 */
1977
 
void vhdl_addportlist(NODEINST *ni, NODEPROTO *np, INTBIG special)
1978
 
{
1979
 
        REGISTER PORTPROTO *pp, *opp;
1980
 
        REGISTER NODEPROTO *cnp;
1981
 
        char before[10];
1982
 
 
1983
 
        if (special == BLOCKFLOPTS || special == BLOCKFLOPDS)
1984
 
        {
1985
 
                (void)addstringtoinfstr("i1, ck, preset: in BIT; q: out BIT");
1986
 
                return;
1987
 
        }
1988
 
        if (special == BLOCKFLOPTR || special == BLOCKFLOPDR)
1989
 
        {
1990
 
                (void)addstringtoinfstr("i1, ck, clear: in BIT; q: out BIT");
1991
 
                return;
1992
 
        }
1993
 
 
1994
 
        /* if this is an icon, use the contents */
1995
 
        if (np->primindex == 0 && np->cellview == el_iconview)
1996
 
        {
1997
 
                cnp = contentsview(np);
1998
 
                if (cnp != NONODEPROTO)
1999
 
                {
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);
2005
 
                        np = cnp;
2006
 
                }
2007
 
        }
2008
 
 
2009
 
        /* flag important ports */
2010
 
        for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
2011
 
        {
2012
 
                pp->temp1 = 0;
2013
 
                if (special == BLOCKMOSTRAN)
2014
 
                {
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; }
2019
 
                }
2020
 
                if (special == BLOCKPOSLOGIC || special == BLOCKBUFFER || special == BLOCKINVERTER)
2021
 
                {
2022
 
                        /* ignore ports not named "a" or "y" */
2023
 
                        if (strcmp(pp->protoname, "a") != 0 && strcmp(pp->protoname, "y") != 0)
2024
 
                        {
2025
 
                                pp->temp1 = 1;
2026
 
                                continue;
2027
 
                        }
2028
 
                }
2029
 
        }
2030
 
 
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);
2037
 
}
2038
 
 
2039
 
void vhdl_addtheseports(NODEINST *ni, NODEPROTO *np, INTBIG bits, char *before)
2040
 
{
2041
 
        REGISTER PORTPROTO *pp;
2042
 
        REGISTER PORTARCINST *pi;
2043
 
        REGISTER BOOLEAN didsome;
2044
 
        REGISTER INTBIG i, count, inst;
2045
 
        char instname[10], **strings;
2046
 
 
2047
 
        didsome = FALSE;
2048
 
        for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
2049
 
        {
2050
 
#ifdef IGNORE4PORTTRANSISTORS
2051
 
                if (np == sch_transistor4prim)
2052
 
                {
2053
 
                        if (namesame(pp->protoname, "b") == 0) continue;
2054
 
                }
2055
 
#endif
2056
 
                if (pp->temp1 != 0) continue;
2057
 
                if (bits == 0)
2058
 
                {
2059
 
                        if ((pp->userbits&STATEBITS) == INPORT || (pp->userbits&STATEBITS) == OUTPORT ||
2060
 
                                (pp->userbits&STATEBITS) == PWRPORT || (pp->userbits&STATEBITS) == GNDPORT)
2061
 
                                        continue;
2062
 
                } else
2063
 
                {
2064
 
                        if ((INTBIG)((pp->userbits&STATEBITS)) != bits) continue;
2065
 
                }
2066
 
                if (ni != NONODEINST && (pp->userbits&PORTISOLATED) != 0)
2067
 
                {
2068
 
                        inst = 1;
2069
 
                        for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
2070
 
                        {
2071
 
                                if (pi->proto != pp) continue;
2072
 
                                count = net_evalbusname(APBUS, pp->protoname, &strings, NOARCINST, np, 0);
2073
 
                                for(i=0; i<count; i++)
2074
 
                                {
2075
 
                                        (void)addstringtoinfstr(before);
2076
 
                                        (void)strcpy(before, ", ");
2077
 
                                        vhdl_addstring(strings[i], np);
2078
 
                                        (void)sprintf(instname, "%ld", inst);
2079
 
                                        (void)addstringtoinfstr(instname);
2080
 
                                        didsome = TRUE;
2081
 
                                }
2082
 
                                inst++;
2083
 
                        }
2084
 
                } else
2085
 
                {
2086
 
                        count = net_evalbusname(APBUS, pp->protoname, &strings, NOARCINST, np, 0);
2087
 
                        for(i=0; i<count; i++)
2088
 
                        {
2089
 
                                (void)addstringtoinfstr(before);
2090
 
                                (void)strcpy(before, ", ");
2091
 
                                vhdl_addstring(strings[i], np);
2092
 
                                didsome = TRUE;
2093
 
                        }
2094
 
                }
2095
 
        }
2096
 
        if (didsome)
2097
 
        {
2098
 
                if (bits == INPORT)
2099
 
                {
2100
 
                        (void)addstringtoinfstr(": in BIT");
2101
 
                } else if (bits == OUTPORT || bits == PWRPORT || bits == GNDPORT)
2102
 
                {
2103
 
                        (void)addstringtoinfstr(": out BIT");
2104
 
                } else
2105
 
                {
2106
 
                        (void)addstringtoinfstr(": inout BIT");
2107
 
                }
2108
 
                (void)strcpy(before, "; ");
2109
 
        }
2110
 
}
2111
 
 
2112
 
/****************************** COMPILATION ******************************/
2113
 
 
2114
 
/*
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
2118
 
 * on error.
2119
 
 */
2120
 
BOOLEAN vhdl_compile(NODEPROTO *basefacet)
2121
 
{
2122
 
        char *intended, *fromintended;
2123
 
        INTBIG  i, filetype;
2124
 
        BOOLEAN err;
2125
 
        REGISTER VARIABLE *var;
2126
 
        UINTBIG netlistdate, vhdldate;
2127
 
        INTBIG retval;
2128
 
        BOOLEAN vhdlondisk, netlistondisk;
2129
 
 
2130
 
        /* determine netlist type */
2131
 
        switch (vhdl_target)
2132
 
        {
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;
2138
 
        }
2139
 
 
2140
 
        var = getvalkey((INTBIG)vhdl_tool, VTOOL, VINTEGER, vhdl_vhdlondiskkey);
2141
 
        vhdlondisk = FALSE;
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;
2146
 
 
2147
 
        /* see if there is netlist associated with this facet */
2148
 
        if (vhdl_startinput(basefacet, filetype, netlistondisk, &intended, &netlistdate) == 0)
2149
 
                err = FALSE; else
2150
 
                        err = TRUE;
2151
 
        if (!err)
2152
 
        {
2153
 
                /* got netlist, don't need to read it, just wanted the date and existence */
2154
 
                vhdl_endinput();
2155
 
        }
2156
 
 
2157
 
        /* get VHDL */
2158
 
        if (vhdl_startinput(basefacet, io_filetypevhdl, vhdlondisk, &intended, &vhdldate) != 0)
2159
 
        {
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);
2163
 
                return(TRUE);
2164
 
        }
2165
 
 
2166
 
        /* if there is a newer netlist, stop now */
2167
 
        if (!err && netlistdate >= vhdldate)
2168
 
        {
2169
 
                vhdl_endinput();
2170
 
                return(FALSE);
2171
 
        }
2172
 
 
2173
 
        /* build and clear vhdl_identtable */
2174
 
        if (vhdl_identtable == 0)
2175
 
        {
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;
2181
 
        }
2182
 
 
2183
 
        if (allocstring(&fromintended, intended, el_tempcluster)) return(TRUE);
2184
 
        vhdl_errorcount = 0;
2185
 
        vhdl_scanner();
2186
 
        (void)vhdl_endinput();
2187
 
        err = vhdl_parser(vhdl_tliststart);
2188
 
        if (!err) err = vhdl_semantic();
2189
 
        if (err)
2190
 
        {
2191
 
                ttyputmsg(_("ERRORS during compilation, no output produced"));
2192
 
                efree(fromintended);
2193
 
                return(TRUE);
2194
 
        }
2195
 
 
2196
 
        /* prepare to create netlist */
2197
 
        retval = vhdl_startoutput(basefacet, filetype, netlistondisk, &intended);
2198
 
        if (retval != 0)
2199
 
        {
2200
 
                if (retval > 0) ttyputerr(_("Cannot write %s"), intended);
2201
 
                return(TRUE);
2202
 
        }
2203
 
        ttyputmsg(_("Compiling VHDL in %s, writing netlist to %s"), fromintended, intended);
2204
 
        efree(fromintended);
2205
 
 
2206
 
        /* write output */
2207
 
        switch (vhdl_target)
2208
 
        {
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;
2214
 
        }
2215
 
 
2216
 
        /* finish up */
2217
 
        vhdl_endoutput();
2218
 
        return(FALSE);
2219
 
}
2220
 
 
2221
 
/*
2222
 
Module:  vhdl_scanner
2223
 
------------------------------------------------------------------------
2224
 
Description:
2225
 
        Lexical scanner of input file creating token list.
2226
 
------------------------------------------------------------------------
2227
 
Calling Sequence:  vhdl_scanner();
2228
 
------------------------------------------------------------------------
2229
 
*/
2230
 
void vhdl_scanner(void)
2231
 
{
2232
 
        char *c, buffer[MAXVHDLLINE], *end, tchar;
2233
 
        INTBIG line_num, space;
2234
 
        VKEYWORD *key;
2235
 
 
2236
 
        /* start by clearing previous scanner memory */
2237
 
        vhdl_freescannermemory();
2238
 
 
2239
 
        c = "";
2240
 
        for(;;)
2241
 
        {
2242
 
                if (*c == 0)
2243
 
                {
2244
 
                        line_num = vhdl_getnextline(buffer);
2245
 
                        if (line_num == 0) return;
2246
 
                        space = TRUE;
2247
 
                        c = buffer;
2248
 
                } else if (isspace(*c)) space = TRUE; else
2249
 
                        space = FALSE;
2250
 
                while (isspace(*c)) c++;
2251
 
                if (*c == 0) continue;
2252
 
                if (isalpha(*c))
2253
 
                {
2254
 
                        /* could be identifier (keyword) or bit string literal */
2255
 
                        if (*(c + 1) == '"')
2256
 
                        {
2257
 
                                if ((tchar = vhdl_toupper(*c)) == 'B')
2258
 
                                {
2259
 
                                        /* EMPTY */ 
2260
 
                                } else if (tchar == '0')
2261
 
                                {
2262
 
                                        /* EMPTY */ 
2263
 
                                } else if (tchar == 'X')
2264
 
                                {
2265
 
                                        /* EMPTY */ 
2266
 
                                }
2267
 
                        }
2268
 
                        end = c + 1;
2269
 
                        while (isalnum(*end) || *end == '_') end++;
2270
 
 
2271
 
                        /* got alphanumeric from c to end - 1 */
2272
 
                        if ((key = vhdl_iskeyword(c, (INTBIG)(end - c))) != NOVKEYWORD)
2273
 
                        {
2274
 
                                vhdl_makekeytoken(key, line_num, (INTBIG)space);
2275
 
                        } else
2276
 
                        {
2277
 
                                vhdl_makeidenttoken(c, (INTBIG)(end - c), line_num, (INTBIG)space);
2278
 
                        }
2279
 
                        c = end;
2280
 
                } else if (isdigit(*c))
2281
 
                {
2282
 
                        /* could be decimal or based literal */
2283
 
                        end = c + 1;
2284
 
                        while (isdigit(*end) || *end == '_') end++;
2285
 
 
2286
 
                        /* got numeric from c to end - 1 */
2287
 
                        vhdl_makedecimaltoken(c, (INTBIG)(end - c), line_num, (INTBIG)space);
2288
 
                        c = end;
2289
 
                } else
2290
 
                {
2291
 
                        switch (*c)
2292
 
                        {
2293
 
                                case '"':
2294
 
                                        /* got a start of a string */
2295
 
                                        end = c + 1;
2296
 
                                        while (*end != '\n')
2297
 
                                        {
2298
 
                                                if (*end == '"')
2299
 
                                                {
2300
 
                                                        if (*(end + 1) == '"') end++; else
2301
 
                                                                break;
2302
 
                                                }
2303
 
                                                end++;
2304
 
                                        }
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++;
2308
 
                                        c = end;
2309
 
                                        break;
2310
 
                                case '&':
2311
 
                                        vhdl_maketoken((INTBIG)TOKEN_AMPERSAND, line_num, (INTBIG)space);
2312
 
                                        c++;
2313
 
                                        break;
2314
 
                                case '\'':
2315
 
                                        /* character literal */
2316
 
                                        if (isgraph(*(c + 1)) && *(c + 2) == '\'')
2317
 
                                        {
2318
 
                                                vhdl_makechartoken(*(c + 1), line_num, (INTBIG)space);
2319
 
                                                c += 3;
2320
 
                                        } else c++;
2321
 
                                        break;
2322
 
                                case '(':
2323
 
                                        vhdl_maketoken((INTBIG)TOKEN_LEFTBRACKET, line_num, (INTBIG)space);
2324
 
                                        c++;
2325
 
                                        break;
2326
 
                                case ')':
2327
 
                                        vhdl_maketoken((INTBIG)TOKEN_RIGHTBRACKET, line_num, (INTBIG)space);
2328
 
                                        c++;
2329
 
                                        break;
2330
 
                                case '*':
2331
 
                                        /* could be STAR or DOUBLESTAR */
2332
 
                                        if (*(c + 1) == '*')
2333
 
                                        {
2334
 
                                                vhdl_maketoken((INTBIG)TOKEN_DOUBLESTAR, line_num, (INTBIG)space);
2335
 
                                                c += 2;
2336
 
                                        } else
2337
 
                                        {
2338
 
                                                vhdl_maketoken((INTBIG)TOKEN_STAR, line_num, (INTBIG)space);
2339
 
                                                c++;
2340
 
                                        }
2341
 
                                        break;
2342
 
                                case '+':
2343
 
                                        vhdl_maketoken((INTBIG)TOKEN_PLUS, line_num, (INTBIG)space);
2344
 
                                        c++;
2345
 
                                        break;
2346
 
                                case ',':
2347
 
                                        vhdl_maketoken((INTBIG)TOKEN_COMMA, line_num, (INTBIG)space);
2348
 
                                        c++;
2349
 
                                        break;
2350
 
                                case '-':
2351
 
                                        if (*(c + 1) == '-')
2352
 
                                        {
2353
 
                                                /* got a comment, throw away rest of line */
2354
 
                                                c = buffer + strlen(buffer);
2355
 
                                        } else
2356
 
                                        {
2357
 
                                                /* got a minus sign */
2358
 
                                                vhdl_maketoken((INTBIG)TOKEN_MINUS, line_num, (INTBIG)space);
2359
 
                                                c++;
2360
 
                                        }
2361
 
                                        break;
2362
 
                                case '.':
2363
 
                                        /* could be PERIOD or DOUBLEDOT */
2364
 
                                        if (*(c + 1) == '.')
2365
 
                                        {
2366
 
                                                vhdl_maketoken((INTBIG)TOKEN_DOUBLEDOT, line_num, (INTBIG)space);
2367
 
                                                c += 2;
2368
 
                                        } else
2369
 
                                        {
2370
 
                                                vhdl_maketoken((INTBIG)TOKEN_PERIOD, line_num, (INTBIG)space);
2371
 
                                                c++;
2372
 
                                        }
2373
 
                                        break;
2374
 
                                case '/':
2375
 
                                        /* could be SLASH or NE */
2376
 
                                        if (*(c + 1) == '=')
2377
 
                                        {
2378
 
                                                vhdl_maketoken((INTBIG)TOKEN_NE, line_num, (INTBIG)space);
2379
 
                                                c += 2;
2380
 
                                        } else
2381
 
                                        {
2382
 
                                                vhdl_maketoken((INTBIG)TOKEN_SLASH, line_num, (INTBIG)space);
2383
 
                                                c++;
2384
 
                                        }
2385
 
                                        break;
2386
 
                                case ':':
2387
 
                                        /* could be COLON or VARASSIGN */
2388
 
                                        if (*(c + 1) == '=')
2389
 
                                        {
2390
 
                                                vhdl_maketoken((INTBIG)TOKEN_VARASSIGN, line_num, (INTBIG)space);
2391
 
                                                c += 2;
2392
 
                                        } else
2393
 
                                        {
2394
 
                                                vhdl_maketoken((INTBIG)TOKEN_COLON, line_num, (INTBIG)space);
2395
 
                                                c++;
2396
 
                                        }
2397
 
                                        break;
2398
 
                                case ';':
2399
 
                                        vhdl_maketoken((INTBIG)TOKEN_SEMICOLON, line_num, (INTBIG)space);
2400
 
                                        c++;
2401
 
                                        break;
2402
 
                                case '<':
2403
 
                                        /* could be LT or LE or BOX */
2404
 
                                        switch (*(c + 1))
2405
 
                                        {
2406
 
                                                case '=':
2407
 
                                                        vhdl_maketoken((INTBIG)TOKEN_LE, line_num, (INTBIG)space);
2408
 
                                                        c += 2;
2409
 
                                                        break;
2410
 
                                                case '>':
2411
 
                                                        vhdl_maketoken((INTBIG)TOKEN_BOX, line_num, (INTBIG)space);
2412
 
                                                        c += 2;
2413
 
                                                        break;
2414
 
                                                default:
2415
 
                                                        vhdl_maketoken((INTBIG)TOKEN_LT, line_num, (INTBIG)space);
2416
 
                                                        c++;
2417
 
                                                        break;
2418
 
                                        }
2419
 
                                        break;
2420
 
                                case '=':
2421
 
                                        /* could be EQUAL or double delimiter ARROW */
2422
 
                                        if (*(c + 1) == '>')
2423
 
                                        {
2424
 
                                                vhdl_maketoken((INTBIG)TOKEN_ARROW, line_num, (INTBIG)space);
2425
 
                                                c += 2;
2426
 
                                        } else
2427
 
                                        {
2428
 
                                                vhdl_maketoken((INTBIG)TOKEN_EQ, line_num, (INTBIG)space);
2429
 
                                                c++;
2430
 
                                        }
2431
 
                                        break;
2432
 
                                case '>':
2433
 
                                        /* could be GT or GE */
2434
 
                                        if (*(c + 1) == '=')
2435
 
                                        {
2436
 
                                                vhdl_maketoken((INTBIG)TOKEN_GE, line_num, (INTBIG)space);
2437
 
                                                c += 2;
2438
 
                                        } else
2439
 
                                        {
2440
 
                                                vhdl_maketoken((INTBIG)TOKEN_GT, line_num, (INTBIG)space);
2441
 
                                                c++;
2442
 
                                        }
2443
 
                                        break;
2444
 
                                case '|':
2445
 
                                        vhdl_maketoken((INTBIG)TOKEN_VERTICALBAR, line_num, (INTBIG)space);
2446
 
                                        c++;
2447
 
                                        break;
2448
 
                                default:
2449
 
        /*      AJ      vhdl_makestrtoken(TOKEN_UNKNOWN, c, 1, line_num, space); */
2450
 
                                        vhdl_maketoken((INTBIG)TOKEN_UNKNOWN, line_num, (INTBIG)space);
2451
 
                                        c++;
2452
 
                                        break;
2453
 
                        }
2454
 
                }
2455
 
        }
2456
 
}
2457
 
 
2458
 
/*
2459
 
Module:  vhdl_makekeytoken
2460
 
------------------------------------------------------------------------
2461
 
Description:
2462
 
        Add a token to the token list which has a key reference.
2463
 
------------------------------------------------------------------------
2464
 
Calling Sequence:  vhdl_makekeytoken(key, line_num, space);
2465
 
 
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
 
------------------------------------------------------------------------
2472
 
*/
2473
 
void vhdl_makekeytoken(VKEYWORD *key, INTBIG line_num, INTBIG space)
2474
 
{
2475
 
        TOKENLIST *newtoken;
2476
 
 
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)
2485
 
        {
2486
 
                vhdl_tliststart = vhdl_tlistend = newtoken;
2487
 
        } else
2488
 
        {
2489
 
                vhdl_tlistend->space = space;
2490
 
                vhdl_tlistend->next = newtoken;
2491
 
                vhdl_tlistend = newtoken;
2492
 
        }
2493
 
}
2494
 
 
2495
 
/*
2496
 
Module:  vhdl_makeidenttoken
2497
 
------------------------------------------------------------------------
2498
 
Description:
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);
2502
 
 
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
 
------------------------------------------------------------------------
2510
 
*/
2511
 
void vhdl_makeidenttoken(char *str, INTBIG length, INTBIG line_num, INTBIG space)
2512
 
{
2513
 
        TOKENLIST *newtoken;
2514
 
        char *newstring;
2515
 
        IDENTTABLE *ikey;
2516
 
 
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;
2522
 
 
2523
 
        /* check if ident exits in the global name space */
2524
 
        if ((ikey = vhdl_findidentkey(newstring)) == (IDENTTABLE *)0)
2525
 
        {
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)
2535
 
        {
2536
 
                vhdl_tliststart = vhdl_tlistend = newtoken;
2537
 
        } else
2538
 
        {
2539
 
                vhdl_tlistend->space = space;
2540
 
                vhdl_tlistend->next = newtoken;
2541
 
                vhdl_tlistend = newtoken;
2542
 
        }
2543
 
}
2544
 
 
2545
 
/*
2546
 
Module:  vhdl_makestrtoken
2547
 
------------------------------------------------------------------------
2548
 
Description:
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);
2553
 
 
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
 
------------------------------------------------------------------------
2561
 
*/
2562
 
void vhdl_makestrtoken(char *string, INTBIG length, INTBIG line_num, INTBIG space)
2563
 
{
2564
 
        TOKENLIST *newtoken;
2565
 
        char *newstring, *str, *str2;
2566
 
 
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;
2572
 
 
2573
 
        /* merge two adjacent double quotes */
2574
 
        str = newstring;
2575
 
        while (*str)
2576
 
        {
2577
 
                if (*str == '"')
2578
 
                {
2579
 
                        if (*(str + 1) == '"')
2580
 
                        {
2581
 
                                str2 = str + 1;
2582
 
                                do
2583
 
                                {
2584
 
                                        *str2 = *(str2 + 1);
2585
 
                                        str2++;
2586
 
                                } while (*str2 != 0);
2587
 
                        }
2588
 
                }
2589
 
                str++;
2590
 
        }
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)
2597
 
        {
2598
 
                vhdl_tliststart = vhdl_tlistend = newtoken;
2599
 
        } else
2600
 
        {
2601
 
                vhdl_tlistend->space = space;
2602
 
                vhdl_tlistend->next = newtoken;
2603
 
                vhdl_tlistend = newtoken;
2604
 
        }
2605
 
}
2606
 
 
2607
 
/*
2608
 
Module:  vhdl_makedecimaltoken
2609
 
------------------------------------------------------------------------
2610
 
Description:
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);
2614
 
 
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
 
------------------------------------------------------------------------
2622
 
*/
2623
 
void vhdl_makedecimaltoken(char *string, INTBIG length, INTBIG line_num,
2624
 
        INTBIG space)
2625
 
{
2626
 
        TOKENLIST *newtoken;
2627
 
        char *newstring;
2628
 
 
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)
2640
 
        {
2641
 
                vhdl_tliststart = vhdl_tlistend = newtoken;
2642
 
        } else
2643
 
        {
2644
 
                vhdl_tlistend->space = space;
2645
 
                vhdl_tlistend->next = newtoken;
2646
 
                vhdl_tlistend = newtoken;
2647
 
        }
2648
 
}
2649
 
 
2650
 
/*
2651
 
Module:  vhdl_maketoken
2652
 
------------------------------------------------------------------------
2653
 
Description:
2654
 
        Add a token to the token list which has no string reference.
2655
 
------------------------------------------------------------------------
2656
 
Calling Sequence:  vhdl_maketoken(token, line_num, space);
2657
 
 
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
 
------------------------------------------------------------------------
2664
 
*/
2665
 
void vhdl_maketoken(INTBIG token, INTBIG line_num, INTBIG space)
2666
 
{
2667
 
        TOKENLIST *newtoken;
2668
 
 
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)
2677
 
        {
2678
 
                vhdl_tliststart = vhdl_tlistend = newtoken;
2679
 
        } else
2680
 
        {
2681
 
                vhdl_tlistend->space = space;
2682
 
                vhdl_tlistend->next = newtoken;
2683
 
                vhdl_tlistend = newtoken;
2684
 
        }
2685
 
}
2686
 
 
2687
 
/*
2688
 
Module:  vhdl_makechartoken
2689
 
------------------------------------------------------------------------
2690
 
Description:
2691
 
        Make a character literal token.
2692
 
------------------------------------------------------------------------
2693
 
Calling Sequence:  vhdl_makechartoken(c, line_num, space);
2694
 
 
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
 
------------------------------------------------------------------------
2701
 
*/
2702
 
void vhdl_makechartoken(char c, INTBIG line_num, INTBIG space)
2703
 
{
2704
 
        TOKENLIST *newtoken;
2705
 
 
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)
2714
 
        {
2715
 
                vhdl_tliststart = vhdl_tlistend = newtoken;
2716
 
        } else
2717
 
        {
2718
 
                vhdl_tlistend->space = space;
2719
 
                vhdl_tlistend->next = newtoken;
2720
 
                vhdl_tlistend = newtoken;
2721
 
        }
2722
 
}
2723
 
 
2724
 
void vhdl_freescannermemory(void)
2725
 
{
2726
 
        TOKENLIST *tok, *nexttok;
2727
 
        REGISTER INTBIG i;
2728
 
 
2729
 
        /* free parsed tokens */
2730
 
        for(tok = vhdl_tliststart; tok != NOTOKENLIST; tok = nexttok)
2731
 
        {
2732
 
                nexttok = tok->next;
2733
 
                if (tok->token == TOKEN_STRING || tok->token == TOKEN_DECIMAL)
2734
 
                        efree(tok->pointer);
2735
 
                efree((char *)tok);
2736
 
        }
2737
 
        vhdl_tliststart = vhdl_tlistend = NOTOKENLIST;
2738
 
 
2739
 
        /* clear identifier table */
2740
 
        if (vhdl_identtable != 0)
2741
 
        {
2742
 
                for (i = 0; i < IDENT_TABLE_SIZE; i++)
2743
 
                        if (vhdl_identtable[i].string != 0)
2744
 
                {
2745
 
                        efree(vhdl_identtable[i].string);
2746
 
                        vhdl_identtable[i].string = 0;
2747
 
                }
2748
 
        }
2749
 
}
2750
 
 
2751
 
/*
2752
 
Module:  vhdl_iskeyword
2753
 
------------------------------------------------------------------------
2754
 
Description:
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);
2759
 
 
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
 
------------------------------------------------------------------------
2767
 
*/
2768
 
VKEYWORD *vhdl_iskeyword(char *string, INTBIG length)
2769
 
{
2770
 
        INTBIG aindex, num, check, base;
2771
 
        char tstring[MAXVHDLLINE];
2772
 
 
2773
 
        if (length >= MAXVHDLLINE) return(NOVKEYWORD);
2774
 
        for (aindex = 0; aindex < length; aindex++)
2775
 
                tstring[aindex] = string[aindex];
2776
 
        tstring[length] = 0;
2777
 
        base = 0;
2778
 
        num = sizeof(vhdl_keywords) / sizeof(VKEYWORD);
2779
 
        aindex = num >> 1;
2780
 
        while (num)
2781
 
        {
2782
 
                check = namesame(tstring, vhdl_keywords[base + aindex].name);
2783
 
                if (check == 0) return(&vhdl_keywords[base + aindex]);
2784
 
                if (check < 0)
2785
 
                {
2786
 
                        num = aindex;
2787
 
                        aindex = num >> 1;
2788
 
                } else
2789
 
                {
2790
 
                        base += aindex + 1;
2791
 
                        num -= aindex + 1;
2792
 
                        aindex = num >> 1;
2793
 
                }
2794
 
        }
2795
 
        return(NOVKEYWORD);
2796
 
}
2797
 
 
2798
 
/*
2799
 
Module:  vhdl_findidentkey
2800
 
------------------------------------------------------------------------
2801
 
Description:
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
2804
 
        found.
2805
 
------------------------------------------------------------------------
2806
 
Calling Sequence:  ikey = vhdl_findidentkey(string);
2807
 
 
2808
 
Name            Type            Description
2809
 
----            ----            -----------
2810
 
string          *char           Pointer to string of name.
2811
 
ikey            *IDENTTABLE     Pointer to entry in table if found,
2812
 
                                                                or 0 if not found.
2813
 
------------------------------------------------------------------------
2814
 
*/
2815
 
IDENTTABLE *vhdl_findidentkey(char *string)
2816
 
{
2817
 
        INTBIG attempt;
2818
 
        char *ident;
2819
 
 
2820
 
        attempt = vhdl_identfirsthash(string);
2821
 
        for(;;)
2822
 
        {
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);
2827
 
        }
2828
 
        return((IDENTTABLE *)0);
2829
 
}
2830
 
 
2831
 
/*
2832
 
Module:  vhdl_makeidentkey
2833
 
------------------------------------------------------------------------
2834
 
Description:
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);
2840
 
 
2841
 
Name            Type            Description
2842
 
----            ----            -----------
2843
 
string          *char           Pointer to string of name.
2844
 
ikey            *IDENTTABLE     Pointer to entry in table created.
2845
 
------------------------------------------------------------------------
2846
 
*/
2847
 
IDENTTABLE *vhdl_makeidentkey(char *string)
2848
 
{
2849
 
        INTBIG attempt, count;
2850
 
 
2851
 
        count = 0;
2852
 
        attempt = vhdl_identfirsthash(string);
2853
 
        while (vhdl_identtable[attempt].string)
2854
 
        {
2855
 
                if (++count >= MAX_HASH_TRYS)
2856
 
                {
2857
 
                        ttyputmsg(_("ERROR hashing identifier - tried %ld times"), count);
2858
 
                        return(0);
2859
 
                }
2860
 
                attempt = vhdl_identsecondhash(string, attempt);
2861
 
        }
2862
 
        vhdl_identtable[attempt].string = string;
2863
 
        return(&vhdl_identtable[attempt]);
2864
 
}
2865
 
 
2866
 
/*
2867
 
Module:  vhdl_identfirsthash
2868
 
------------------------------------------------------------------------
2869
 
Description:
2870
 
        Return the hash value for the passed string.  The first hash
2871
 
        function is:
2872
 
 
2873
 
                value = ((firstchar << 7) + (lastchar << 4) + length) mod
2874
 
                                IDENT_TABLE_SIZE;
2875
 
 
2876
 
        Note:  lowercase letters are converted to uppercase.
2877
 
------------------------------------------------------------------------
2878
 
Calling Sequence:  value = vhdl_identfirsthash(string);
2879
 
 
2880
 
Name            Type            Description
2881
 
----            ----            -----------
2882
 
string          *char           Pointer to string to hash.
2883
 
value           INTBIG          Returned hash value.
2884
 
------------------------------------------------------------------------
2885
 
*/
2886
 
INTBIG vhdl_identfirsthash(char *string)
2887
 
{
2888
 
        REGISTER INTBIG length, value;
2889
 
 
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;
2894
 
        return(value);
2895
 
}
2896
 
 
2897
 
/*
2898
 
Module:  vhdl_identsecondhash
2899
 
------------------------------------------------------------------------
2900
 
Description:
2901
 
        Return the hash value for the passed string.  The second hash
2902
 
        function is:
2903
 
 
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);
2908
 
 
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
 
------------------------------------------------------------------------
2915
 
*/
2916
 
INTBIG vhdl_identsecondhash(char *string, INTBIG previous_hash)
2917
 
{
2918
 
        INTBIG length, value;
2919
 
        char *sptr;
2920
 
 
2921
 
        value = 0;
2922
 
        for (sptr = string; *sptr; sptr++)
2923
 
                value += (vhdl_toupper(*sptr) & 0xFF);
2924
 
        value <<= 4;
2925
 
        length = strlen(string);
2926
 
        value = (previous_hash + value + length) % IDENT_TABLE_SIZE;
2927
 
        return(value);
2928
 
}
2929
 
 
2930
 
/*
2931
 
Module:  vhdl_toupper
2932
 
------------------------------------------------------------------------
2933
 
Description:
2934
 
        Convert a character to uppercase if it is a lowercase letter only.
2935
 
------------------------------------------------------------------------
2936
 
Calling Sequence:  c = vhdl_toupper(c);
2937
 
 
2938
 
Name            Type            Description
2939
 
----            ----            -----------
2940
 
c                       char            Character to be converted.
2941
 
------------------------------------------------------------------------
2942
 
*/
2943
 
char vhdl_toupper(char c)
2944
 
{
2945
 
        if (islower(c))
2946
 
                c = toupper(c);
2947
 
        return(c);
2948
 
}
2949
 
 
2950
 
/*
2951
 
Module:  vhdl_findtopinterface
2952
 
------------------------------------------------------------------------
2953
 
Description:
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);
2958
 
 
2959
 
Name                    Type            Description
2960
 
----                    ----            -----------
2961
 
units                   *DBUNITS        Pointer to database design units.
2962
 
top_interface   *DBINTERFACE    Pointer to top interface.
2963
 
------------------------------------------------------------------------
2964
 
*/
2965
 
DBINTERFACE *vhdl_findtopinterface(DBUNITS *units)
2966
 
{
2967
 
        DBINTERFACE *interfacef;
2968
 
        DBBODY *body;
2969
 
        DBCOMPONENTS *compo;
2970
 
        SYMBOLTREE *symbol;
2971
 
 
2972
 
        /* clear flags of all interfaces in database */
2973
 
        for (interfacef = units->interfaces; interfacef != NULL; interfacef = interfacef->next)
2974
 
                interfacef->flags &= ~TOP_ENTITY_FLAG;
2975
 
 
2976
 
        /* go through the list of bodies and flag any interfaces */
2977
 
        for (body = units->bodies; body != NULL; body = body->next)
2978
 
        {
2979
 
                /* go through component list */
2980
 
                if (body->declare == 0) continue;
2981
 
                for (compo = body->declare->components; compo != NULL; compo = compo->next)
2982
 
                {
2983
 
                        symbol = vhdl_searchsymbol(compo->name, vhdl_gsymbols);
2984
 
                        if (symbol != NULL && symbol->pointer != NULL)
2985
 
                        {
2986
 
                                ((DBINTERFACE *)(symbol->pointer))->flags |= TOP_ENTITY_FLAG;
2987
 
                        }
2988
 
                }
2989
 
        }
2990
 
 
2991
 
        /* find interface with the flag bit not set */
2992
 
        for (interfacef = units->interfaces; interfacef != NULL; interfacef = interfacef->next)
2993
 
        {
2994
 
                if (!(interfacef->flags & TOP_ENTITY_FLAG)) break;
2995
 
        }
2996
 
        return(interfacef);
2997
 
}
2998
 
 
2999
 
void vhdl_freeunresolvedlist(UNRESLIST **lstart)
3000
 
{
3001
 
        UNRESLIST *unres;
3002
 
 
3003
 
        while (*lstart != 0)
3004
 
        {
3005
 
                unres = *lstart;
3006
 
                *lstart = (*lstart)->next;
3007
 
                efree((char *)unres);
3008
 
        }
3009
 
}
3010
 
 
3011
 
/*
3012
 
Module:  vhdl_unresolved
3013
 
------------------------------------------------------------------------
3014
 
Description:
3015
 
        Maintain a list of unresolved interfaces for later reporting.
3016
 
------------------------------------------------------------------------
3017
 
Calling Sequence:  vhdl_unresolved(iname, lstart);
3018
 
 
3019
 
Name            Type            Description
3020
 
----            ----            -----------
3021
 
iname           *IDENTTABLE     Pointer to global name space.
3022
 
lstart          **UNRESLIST     Address of start of list pointer;
3023
 
------------------------------------------------------------------------
3024
 
*/
3025
 
void vhdl_unresolved(IDENTTABLE *iname, UNRESLIST **lstart)
3026
 
{
3027
 
        UNRESLIST *ulist;
3028
 
 
3029
 
        for (ulist = *lstart; ulist != NULL; ulist = ulist->next)
3030
 
        {
3031
 
                if (ulist->interfacef == iname) break;
3032
 
        }
3033
 
        if (ulist) ulist->numref++; else
3034
 
        {
3035
 
                ulist = (UNRESLIST *)emalloc((INTBIG)sizeof(UNRESLIST), vhdl_tool->cluster);
3036
 
                ulist->interfacef = iname;
3037
 
                ulist->numref = 1;
3038
 
                ulist->next = *lstart;
3039
 
                *lstart = ulist;
3040
 
        }
3041
 
}
3042
 
 
3043
 
/****************************** VHDL OPTIONS DIALOG ******************************/
3044
 
 
3045
 
/* VHDL Options */
3046
 
static DIALOGITEM vhdl_optionsdialogitems[] =
3047
 
{
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, ""}
3059
 
};
3060
 
static DIALOG vhdl_optionsdialog = {{50,75,419,403}, N_("VHDL Options"), 0, 11, vhdl_optionsdialogitems};
3061
 
 
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) */
3068
 
 
3069
 
void vhdl_optionsdlog(void)
3070
 
{
3071
 
        INTBIG itemHit;
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;
3078
 
 
3079
 
        if (DiaInitDialog(&vhdl_optionsdialog)) return;
3080
 
        var = getval((INTBIG)vhdl_tool, VTOOL, VINTEGER, "VHDL_vhdl_on_disk");
3081
 
        vhdlondisk = FALSE;
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;
3086
 
 
3087
 
        /* setup for generated names in the technology */
3088
 
        tech = sch_tech;
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)
3093
 
        {
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++)
3097
 
                {
3098
 
                        varnames[i] = (char *)emalloc(1, el_tempcluster);
3099
 
                        varnames[i][0] = 0;
3100
 
                }
3101
 
        } else
3102
 
        {
3103
 
                len = getlength(var);
3104
 
                varnames = (char **)emalloc(len * (sizeof (char *)), el_tempcluster);
3105
 
                for(i=0; i<len; i++)
3106
 
                {
3107
 
                        pt = ((char **)var->addr)[i];
3108
 
                        varnames[i] = (char *)emalloc(strlen(pt)+1, el_tempcluster);
3109
 
                        strcpy(varnames[i], pt);
3110
 
                }
3111
 
        }
3112
 
        nplist = (NODEPROTO **)emalloc(i * (sizeof (NODEPROTO *)), el_tempcluster);
3113
 
        for(i=0, np = tech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto, i++)
3114
 
                nplist[i] = np;
3115
 
        for(i=0; i<len; i++)
3116
 
        {
3117
 
                (void)initinfstr();
3118
 
                (void)addstringtoinfstr(nplist[i]->primname);
3119
 
                if (*varnames[i] != 0)
3120
 
                {
3121
 
                        (void)addstringtoinfstr(" (");
3122
 
                        (void)addstringtoinfstr(varnames[i]);
3123
 
                        (void)addstringtoinfstr(")");
3124
 
                }
3125
 
                DiaStuffLine(DVHO_PRIMLIST, returninfstr());
3126
 
        }
3127
 
        DiaSelectLine(DVHO_PRIMLIST, 0);
3128
 
 
3129
 
        if (!vhdlondisk) DiaSetControl(DVHO_VHDLINFACET, 1);
3130
 
        if (!netlistondisk) DiaSetControl(DVHO_NETINFACET, 1);
3131
 
 
3132
 
        /* loop until done */
3133
 
        technameschanged = 0;
3134
 
        for(;;)
3135
 
        {
3136
 
                itemHit = DiaNextHit();
3137
 
                if (itemHit == OK || itemHit == CANCEL) break;
3138
 
                if (itemHit == DVHO_VHDLINFACET || itemHit == DVHO_NETINFACET)
3139
 
                {
3140
 
                        DiaSetControl(itemHit, 1 - DiaGetControl(itemHit));
3141
 
                        continue;
3142
 
                }
3143
 
                if (itemHit == DVHO_PRIMLIST)
3144
 
                {
3145
 
                        DiaSetText(DVHO_UNNEGATEDNAME, "");
3146
 
                        DiaSetText(DVHO_NEGATEDNAME, "");
3147
 
                        i = DiaGetCurLine(DVHO_PRIMLIST);
3148
 
                        pt = varnames[i];
3149
 
                        for(opt = pt; *opt != 0; opt++) if (*opt == '/') break;
3150
 
                        if (*opt == '/')
3151
 
                        {
3152
 
                                *opt = 0;
3153
 
                                DiaSetText(DVHO_UNNEGATEDNAME, pt);
3154
 
                                DiaSetText(DVHO_NEGATEDNAME, &opt[1]);
3155
 
                                *opt = '/';
3156
 
                        } else
3157
 
                        {
3158
 
                                DiaSetText(DVHO_UNNEGATEDNAME, pt);
3159
 
                                DiaSetText(DVHO_NEGATEDNAME, pt);
3160
 
                        }
3161
 
                        continue;
3162
 
                }
3163
 
                if (itemHit == DVHO_UNNEGATEDNAME || itemHit == DVHO_NEGATEDNAME)
3164
 
                {
3165
 
                        i = DiaGetCurLine(DVHO_PRIMLIST);
3166
 
                        (void)initinfstr();
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;
3172
 
 
3173
 
                        technameschanged++;
3174
 
                        (void)reallocstring(&varnames[i], pt, el_tempcluster);
3175
 
 
3176
 
                        (void)initinfstr();
3177
 
                        (void)addstringtoinfstr(nplist[i]->primname);
3178
 
                        if (*varnames[i] != 0)
3179
 
                        {
3180
 
                                (void)addstringtoinfstr(" (");
3181
 
                                (void)addstringtoinfstr(varnames[i]);
3182
 
                                (void)addstringtoinfstr(")");
3183
 
                        }
3184
 
                        DiaSetScrollLine(DVHO_PRIMLIST, i, returninfstr());
3185
 
                        continue;
3186
 
                }
3187
 
        }
3188
 
 
3189
 
        if (itemHit != CANCEL)
3190
 
        {
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));
3200
 
        }
3201
 
        DiaDoneDialog();
3202
 
        for(i=0; i<len; i++) efree(varnames[i]);
3203
 
        efree((char *)varnames);
3204
 
        efree((char *)nplist);
3205
 
}
3206
 
 
3207
 
#endif  /* VHDLTOOL - at top */