1 /****************************************************************************
2 Copyright (C) 1987-2015 by Jeffery P. Hansen
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 Last edit by hansen on Tue May 5 20:53:56 2009
19 ****************************************************************************/
20
21 #ifdef __cplusplus
22 #include <cstdlib>
23 #include <cstdio>
24 #include <cassert>
25 #include <cstring>
26 #else
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <assert.h>
30 #include <string.h>
31 #endif
32
33 #include <pwd.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36
37 #include "tkgate.h"
38 #include "print.h"
39
readprintcapentry(char * buf,int N,FILE * f)40 char *readprintcapentry(char *buf,int N,FILE *f)
41 {
42 char *p,*q;
43 int l;
44
45 for (;;) {
46 p = buf;
47 for (;;) {
48 if (!fgets(p,N-(p-buf),f)) return 0;
49 q = strrchr(p,'\n');
50 if (q) *q = 0;
51 l = strlen(p);
52 if (l > 0 && p[l-1] == '\\') {
53 p += l-1;
54 } else
55 break;
56 }
57 for (p = buf;*p && strchr(" \t",*p);p++);
58 if (*p == '#' || *p == 0) continue;
59
60 return buf;
61 }
62 return 0;
63 }
64
65 /*
66 Check to see if modifications are OK, and if not issue a message.
67 */
modifyOK(EditState * es,unsigned flags)68 int modifyOK(EditState *es,unsigned flags)
69 {
70 if (!(flags & 0x2) && es->isInterface) {
71 message(0,msgLookup("err.badeditop")); /* Illegal interface edit mode operation. */
72 return 0;
73 }
74 if (!(flags & 0x1) && GModuleDef_isDataProtected(es->env)) {
75 message(0,msgLookup("err.protdata"),es->env->m_name); /* Not a library module */
76 return 0;
77 }
78 return 1;
79 }
80
81 /*****************************************************************************
82 *****************************************************************************/
gat_hdl(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])83 static int gat_hdl(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
84 {
85 TkgGateWin *gw = TkGate.gw;
86 EditState *es = gw->parms->circuit->es;
87 int i;
88 const char *name = ((argc > 2) && (*argv[2] != '-')) ? argv[2] : 0;
89
90 #if 0
91 {
92 printf("gat_hdl");
93 for (i = 1;i < argc;i++)
94 printf(" %s",argv[i]);
95 printf("\n");
96 }
97 #endif
98
99 if (argc < 2) return TCL_ERROR;
100
101 for (i = 1;i < argc;i++) {
102 if (strcmp(argv[i],"-cursor") == 0) {
103 int line,pos;
104 if (sscanf(argv[i+1],"%d.%d",&line,&pos) == 2) {
105 hdl_saveCursor(name,line,pos);
106 break;
107 }
108 }
109 }
110
111 if (strcmp(argv[1],"load") == 0)
112 hdl_load(es->env);
113 else if (strcmp(argv[1],"save") == 0) {
114 if (hdl_save(name) < 0)
115 Tcl_SetResult(tcl, "cancel", TCL_STATIC);
116 } else if (strcmp(argv[1],"checksave") == 0) {
117 Tcl_SetResult(tcl, "cancel", TCL_STATIC);
118 } else if (strcmp(argv[1],"close") == 0) {
119 hdl_close();
120 } else if (strcmp(argv[1],"getindex") == 0) {
121 int line,pos;
122 if (hdl_getCursor(&line,&pos) == 0) {
123 char res[127];
124 sprintf(res,"%d.%d",line,pos);
125 Tcl_SetResult(tcl, res, TCL_VOLATILE);
126 } else
127 Tcl_SetResult(tcl, "1.0", TCL_STATIC);
128 } else if (strcmp(argv[1],"touch") == 0) {
129 ob_touch(TkGate.circuit); /* Modify somthing to force undo to thing there are changes */
130 }
131
132 return TCL_OK;
133 }
134
135 /*
136 * Called to do final tkgate initilization
137 */
gat_init(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])138 static int gat_init(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
139 {
140 TkGate_init(tcl);
141 ClearModified();
142 ob_set_mode(OM_START);
143
144 return TCL_OK;
145 }
146
gat_reinitDelay(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])147 static int gat_reinitDelay(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
148 {
149 TkGate_initDelay();
150 return TCL_OK;
151 }
152
153 /*
154 * Retrieve or store interface information about a module.
155 *
156 * gat_interface load <name> <array>
157 * gat_interface generate <name> <options>
158 * gat_interface puticon <name> <options>
159 * gat_interface geticon <name> <options>
160 *
161 */
gat_interface(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])162 static int gat_interface(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
163 {
164 if (argc < 3) {
165 Tcl_SetResult(tcl, "too few arguments.", TCL_STATIC);
166 return TCL_ERROR;
167 }
168
169 if (igen_command(argv[1],argv[2],argc-3,argv + 3) != 0) {
170 Tcl_SetResult(tcl, "invalid command.", TCL_STATIC);
171 return TCL_ERROR;
172 }
173
174 return TCL_OK;
175 }
176
177 /*
178 gat_new "name.v" topmod
179 */
gat_new(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])180 static int gat_new(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
181 {
182 TkgGateWin *gw = TkGate.gw;
183 EditState **es = &gw->parms->circuit->es;
184 const char *file,*topMod;
185 GModuleDef *M;
186 ob_OMMode_t old_mode;
187
188 assert(argc == 3);
189
190 tkgate_setMajorMode(MM_EDIT);
191
192 old_mode = ob_get_mode();
193 if (old_mode != OM_DISABLED) {
194 ob_set_mode(OM_DISABLED);
195 }
196 ob_clear();
197
198 file = argv[1];
199 topMod = argv[2];
200 ob_touch(TkGate.circuit);
201 Circuit_initOptions(TkGate.circuit);
202 Circuit_setTitle(file);
203 ClearModified();
204
205 Circuit_clear();
206 Circuit_setCurrentFile(file);
207
208 Circuit_unloadAllLibraries(TkGate.circuit);
209
210 editstate_flushModules(es);
211
212 M = env_findAdd(topMod,1);
213 ob_touch(M);
214 TkGate.circuit->root_mod = M;
215
216 editstate_push(es,M,0);
217 editstate_setCurrent(*es);
218 ob_touch(TkGate.circuit);
219
220 ClearModified();
221
222 DoTcl("LibraryMgr::loadBaseLibraries");
223
224 /*
225 * Mark this so we can warn if we try to overwrite existing file.
226 */
227 TkGate.circuit->c_isNewFile = 1;
228
229 FlagRedraw();
230
231 if (old_mode == OM_ENABLED) {
232 ob_set_mode(old_mode);
233 }
234 return TCL_OK;
235 }
236
237 /*
238 gat_load "name.v"
239 */
gat_load(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])240 static int gat_load(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
241 {
242 TkgGateWin *gw = TkGate.gw;
243 const char *name;
244 const char *modFlag;
245 ob_OMMode_t old_mode;
246
247 assert(argc == 2);
248 name = argv[1];
249
250 tkgate_setMajorMode(MM_EDIT);
251
252 if ((modFlag = Tcl_GetVar(tcl,"tkg_modifiedFlag",TCL_GLOBAL_ONLY)) && *modFlag != '0') {
253 DoTcl("File::confDelMods");
254 if (!Tcl_GetStringResult(TkGate.tcl) || strcmp(Tcl_GetStringResult(TkGate.tcl),"yes") != 0) {
255 Tcl_SetResult(tcl,"0", TCL_STATIC);
256 return TCL_OK;
257 }
258 }
259
260 old_mode = ob_get_mode();
261 if (old_mode != OM_DISABLED) {
262 ob_set_mode(OM_DISABLED);
263 }
264 ob_clear();
265
266 ob_touch(gw->parms->circuit);
267 if (VerilogOpen(&gw->parms->circuit->es,name,0) < 0) {
268
269 /*
270 * We failed to open the file, but if there is no current file we assume
271 * this was given on the command line and we are starting a new circuit.
272 */
273 if (!*CurrentFile_path(TkGate.circuit->currentFile)) {
274 /* Circuit_setCurrentFile(name);*/
275 } else
276 message(1,msgLookup("err.badopen"),name); /* Unable to open input file '%s' */
277
278 ClearModified();
279
280 if (old_mode == OM_ENABLED) {
281 ob_set_mode(old_mode);
282 }
283
284 Tcl_SetResult(tcl,"0", TCL_STATIC);
285 return TCL_OK;
286 }
287
288 sel_clearDelta();
289
290 Circuit_setCurrentFile(name);
291
292 ClearModified();
293 FlagRedraw();
294
295 if (old_mode == OM_ENABLED) {
296 ob_set_mode(old_mode);
297 }
298
299 Tcl_SetResult(tcl,"1", TCL_STATIC);
300 return TCL_OK;
301 }
302
303 /*
304 gat_loadMore "name.v"
305 */
gat_loadMore(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])306 static int gat_loadMore(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
307 {
308 TkgGateWin *gw = TkGate.gw;
309 const char *name;
310
311 assert(argc == 2);
312 name = argv[1];
313
314 tkgate_setMajorMode(MM_EDIT);
315
316 ob_touch(gw->parms->circuit);
317
318 if (VerilogOpen(&gw->parms->circuit->es,name,1) < 0) {
319 Tcl_SetResult(tcl, "0", TCL_STATIC);
320 return TCL_OK;
321 }
322
323 sel_clearDelta();
324
325 Circuit_setCurrentFile(name);
326
327 FlagRedraw();
328
329 Tcl_SetResult(tcl, "1", TCL_STATIC);
330 return TCL_OK;
331 }
332
333
gat_libIsLoaded(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])334 static int gat_libIsLoaded(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
335 {
336 if (argc < 2)
337 return TCL_OK;
338
339 if (SHash_find(TkGate.libraries,argv[1]))
340 Tcl_SetResult(TkGate.tcl, "1", TCL_STATIC);
341 else
342 Tcl_SetResult(TkGate.tcl, "0", TCL_STATIC);
343
344 return TCL_OK;
345 }
346
347 /*
348 gat_loadLibrary "name.v"
349 */
gat_loadLibrary(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])350 static int gat_loadLibrary(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
351 {
352 const char *name;
353
354 assert(argc == 2);
355 name = argv[1];
356
357 Circuit_loadLibrary(TkGate.circuit,name);
358
359 return TCL_OK;
360 }
361
362 /*****************************************************************************
363 *
364 * gat_unloadLibrary <name>
365 *
366 * Unload the named library.
367 *
368 *****************************************************************************/
gat_unloadLibrary(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])369 static int gat_unloadLibrary(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
370 {
371 const char *name;
372
373 assert(argc == 2);
374 name = argv[1];
375
376 Circuit_unloadLibrary(TkGate.circuit,name);
377
378 FlagRedraw();
379
380 return TCL_OK;
381 }
382
gat_mode(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])383 static int gat_mode(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
384 {
385 TkgGateWin *gw = TkGate.gw;
386 int mode = 0;
387
388 assert(argc == 2);
389
390 sscanf(argv[1],"%d",&mode);
391
392 setEditMode(gw->parms->circuit->es,mode);
393
394 return TCL_OK;
395 }
396
397
398 /*
399 gat_make and {opts}
400 */
gat_make(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])401 static int gat_make(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
402 {
403 TkgGateWin *gw = TkGate.gw;
404 EditState *es = gw->parms->circuit->es;
405 EditState **pes = &gw->parms->circuit->es;
406 GGateInfo *GI;
407 int x,y,r;
408 GCElement *g;
409 const char *xstr,*ystr;
410 const char *dodraw_s = "1";
411 int dodraw = 1;
412
413 assert(argc >= 2);
414
415 dodraw_s = seekOption("-dodraw",argv+2,argc-2);
416 if (dodraw_s)
417 dodraw = (*dodraw_s != '0');
418
419 /*
420 * If we are in interface mode and we are requesting to make a block, use this as
421 * an indication that we want to open that block for interface testing.
422 */
423 if (editstate_isInterfaceMode()) {
424 const char *func = seekOption("-func",argv+2,argc-2);
425
426 if (func) {
427 modint_openSelected(func);
428 }
429
430 return TCL_OK;
431 }
432
433 if (tkgate_currentMode() != MM_EDIT) return TCL_OK;
434 if (!modifyOK(es,0)) return TCL_OK;
435
436 xstr = seekOption("-x",argv+2,argc-2);
437 ystr = seekOption("-y",argv+2,argc-2);
438
439 if (xstr && ystr) {
440 sscanf(xstr,"%d",&x);
441 sscanf(ystr,"%d",&y);
442 r = EditState_getRotation();
443 x /= TkGate.circuit->zoom_factor;
444 y /= TkGate.circuit->zoom_factor;
445 x = wtoc_x(x);
446 y = wtoc_y(y);
447 } else if (TkGate.ed->mark_vis) {
448 x = TkGate.ed->tx;
449 y = TkGate.ed->ty;
450 r = EditState_getRotation();
451 } else {
452 message(0,msgLookup("err.nomark")); /* Please set a mark with the left mouse button before selecting a gate type. */
453 return TCL_OK;
454 }
455
456 GI = GGateInfo_lookup(argv[1]);
457 if (!GI) {
458 message(1,msgLookup("err.badgate"),argv[1]); /* Unknown gate type. */
459 return TCL_OK;
460 }
461
462 badermessage(GI->name);
463
464 mark_unpost();
465
466 g = (*GI->MakeFunction)(pes,es->env,GI->code,x,y,r,0,0,argv+2,argc-2);
467
468 if (!g) return TCL_OK; /* Make was canceled */
469
470 if (TkGate.defaultTech) {
471 ob_touch(g);
472 ob_free(g->tech);
473 g->tech = ob_strdup(TkGate.defaultTech);
474 }
475
476 if (dodraw)
477 gate_draw(g,0);
478
479 if ((GI->code == GC_BLOCK || GI->code == GC_SYMBLOCK))
480 SetModified(MF_MODULE);
481
482 if (dodraw && g && pes) {
483 sel_appendGate(*pes,g,1);
484 sel_finish(*pes);
485 ob_touch(TkGate.circuit);
486 TkGate.circuit->select = g;
487
488 if ((GI->code == GC_BLOCK || GI->code == GC_SYMBLOCK) && r != 0) {
489 gate_draw(g,0);
490 while (r-- > 0)
491 sel_rotate(*pes,1);
492 gate_draw(g,0);
493 }
494 }
495
496 scrollbar_bbx_update();
497
498 SynchronizeInterface();
499
500 return TCL_OK;
501 }
502
gat_closeBox(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])503 static int gat_closeBox(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
504 {
505 TkgGateWin *gw = TkGate.gw;
506 EditState **es = &gw->parms->circuit->es;
507
508 if (!(*es)->parent) {
509 message(0,msgLookup("err.closeroot")); /* "Can't close top-level module. Use quit." */
510 return TCL_OK;
511 }
512
513 ob_touch(TkGate.circuit);
514 EditState_unselectGate(*es);
515 editstate_pop(es);
516 editstate_setCurrent(*es);
517 ClearErrorMark();
518 net_unselect(0);
519 cpath_reshow();
520
521 SetModified(MF_MODULE);
522 SynchronizeInterface();
523
524 FlagRedraw();
525
526 return TCL_OK;
527 }
528
529 /*****************************************************************************
530 *
531 * Open the specified or currently selected module in the module editor.
532 *
533 * Usage:
534 * gat_openBox [<module-name>]
535 * gat_openBox -hierarchical [<module-name>]
536 *
537 *****************************************************************************/
gat_openBox(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])538 static int gat_openBox(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
539 {
540 TkgGateWin *gw = TkGate.gw;
541 EditState **es = &gw->parms->circuit->es;
542 GModuleDef *M = 0;
543 GCElement *b = 0;
544 const char *modName = 0;
545 int hierarchical = 1;
546
547 if (argc == 2) {
548 modName = argv[1];
549 hierarchical = 0;
550 } else if (argc == 3) {
551 modName = argv[2];
552 hierarchical = 1;
553 }
554
555 if (hdl_checkSave(0) < 0) { /* Make sure hdl is up to date */
556 Tcl_SetResult(tcl, "cancel", TCL_STATIC);
557 return TCL_OK;
558 }
559
560 /*
561 * Opening already selected module.
562 */
563 if (modName && es && *es && (*es)->env && strcmp((*es)->env->m_name,modName) == 0)
564 return TCL_OK;
565
566 ob_touch(TkGate.circuit);
567
568 /*
569 * If we are in interface mode, just change the interface we are editing.
570 */
571 if ((*es)->isInterface) {
572 modint_openSelected(modName);
573 return TCL_OK;
574 }
575
576 if (!hierarchical) {
577 /* NOTE: The 'jump-to-module' feature can not be used in simulation or analysis mode. */
578
579 if (tkgate_currentMode() == MM_SIMULATE) {
580 SimInterface_navigateToModule(es,modName);
581 return TCL_OK;
582 }
583 }
584
585 if (modName) {
586 char *p;
587
588 /*
589 * Trim all but the last module name
590 */
591 p = strrchr(modName,'/');
592 if (p) modName = p+1;
593
594 M = env_findModule(modName);
595 if (!M) {
596 message(1,msgLookup("err.nomod"),modName); /* Module '%s' is not defined. */
597 return TCL_OK;
598 }
599 } else {
600 b = TkGate.circuit->select;
601 if (b && GCElement_isModule(b))
602 M = env_findAdd(b->u.block.moduleName,0);
603 else
604 return TCL_OK;
605 }
606
607 if (M->m_hidden && tkgate_currentMode() == MM_EDIT) {
608 message(1,msgLookup("err.modlock")); /* Logic Block is Locked! */
609 return TCL_OK;
610 }
611
612 EditState_unselectGate(*es);
613
614 if (hierarchical) {
615 if (b) block_explode(b);
616 editstate_push(es,M,b);
617 } else {
618 while (*es)
619 editstate_pop(es);
620 editstate_push(es,M,0);
621 }
622 editstate_setCurrent(*es);
623 ClearErrorMark();
624 net_unselect(0);
625 cpath_reshow();
626
627 SetModified(MF_MODULE|MF_SYNCONLY);
628 SynchronizeInterface();
629
630 FlagRedraw();
631
632 return TCL_OK;
633 }
634
635 /*****************************************************************************
636 *
637 * Set top-level module.
638 *
639 * Usage:
640 * gat_reroot <module-name>
641 *
642 *****************************************************************************/
gat_reroot(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])643 static int gat_reroot(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
644 {
645 GModuleDef *M;
646
647 assert(argc == 2);
648 M = env_findModule(argv[1]);
649 if (!M) {
650 message(1,msgLookup("err.nomod"),argv[1]); /* Module '%s' is not defined. */
651 return TCL_OK;
652 }
653
654 Circuit_changeRoot(M);
655
656 SynchronizeInterface();
657 FlagRedraw();
658 return TCL_OK;
659 }
660
661 /*****************************************************************************
662 * Get the list of available printers
663 *
664 * Usage:
665 * gat_getPrinterList
666 *
667 * The returned list is of the form: {{name1 longname1} {name2 longname2} ...}
668 *
669 *****************************************************************************/
gat_getPrinterList(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])670 static int gat_getPrinterList(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
671 {
672 char *printerList = malloc(STRMAX);
673 int N = STRMAX;
674 int C = 0;
675 FILE *f;
676
677 strcpy(printerList,"{default \"Default Printer\"}");
678 C = strlen(printerList);
679
680 f = fopen("/etc/printcap","r");
681 if (f) {
682 char buf[STRMAX*2];
683
684 while (readprintcapentry(buf,2*STRMAX,f)) {
685 char *nameEntry;
686 char *shortName = 0;
687 char *longName = 0;
688 char *t;
689 int l;
690
691 nameEntry = strtok(buf,":");
692 for (t = strtok(nameEntry,"|");t && !(shortName && longName);t = strtok(0,"|")) {
693 if (strchr(t,' ') && !longName)
694 longName = t;
695 else if (!shortName)
696 shortName = t;
697 }
698 if (!shortName) continue;
699 if (!longName) longName = shortName;
700
701 l = strlen(shortName) + strlen(longName) + 6;
702 if (C >= N) {
703 N += STRMAX;
704 printerList = realloc(printerList,N);
705 }
706
707 sprintf(printerList + C," {%s \"%s\"}",shortName,longName);
708 C += l;
709 }
710 fclose(f);
711 }
712
713 Tcl_SetResult(TkGate.tcl, printerList, TCL_VOLATILE);
714
715 free(printerList);
716
717 return TCL_OK;
718 }
719
720 /*****************************************************************************
721 *
722 * setrot {0/90/180/270}
723 *
724 * set rotation for new gates
725 *
726 *****************************************************************************/
gat_setrot(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])727 static int gat_setrot(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
728 {
729 char buf[STRMAX];
730 int N = 0;
731
732 assert(argc == 2);
733
734 sscanf(argv[1],"%d",&N);
735 EditState_setRotation(N);
736
737 sprintf(buf,"%d",N);
738 Tcl_SetVar(TkGate.tcl,"rot",buf,TCL_GLOBAL_ONLY);
739
740
741 return TCL_OK;
742 }
743
744 /*
745 Relay a command from the simulator to the scope
746 */
gat_scopeCommand(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])747 static int gat_scopeCommand(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
748 {
749 SimInterface_command(&TkGate.circuit->simulator,argv[1]);
750 return TCL_OK;
751 }
752
753 /*
754 Relay a command from the analyzer to cpath
755 */
gat_analyzerCommand(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])756 static int gat_analyzerCommand(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
757 {
758 cpath_command(argv[1]);
759 return TCL_OK;
760 }
761
gat_errBoxReport(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])762 static int gat_errBoxReport(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
763 {
764 TkgGateWin *gw = TkGate.gw;
765 EditState **es = &gw->parms->circuit->es;
766 int N = 0;
767
768 ob_touch(TkGate.circuit);
769
770 char res[127];
771 if (argc != 2 || sscanf(argv[1],"%d",&N) != 1) {
772 if (argc != 2)
773 sprintf(res,"argument error argc=%d",argc);
774 else
775 sprintf(res,"argument error argv[1]=<%s>",argv[1]);
776 Tcl_SetResult(tcl, res, TCL_VOLATILE);
777 return TCL_ERROR;
778 }
779
780 if (N >=0 && tkgate_currentMode() == MM_SIMULATE) {
781 DoTcl("errmsg [m db.err.neededit]");
782 return TCL_OK;
783 }
784
785 if (N >= 0)
786 *es = EditState_moveToError(N,*es);
787 else {
788 Error_purge();
789 }
790
791 return TCL_OK;
792 }
793
794 /*****************************************************************************
795 *
796 * Save the current circuit to a file.
797 *
798 * Tcl syntax:
799 *
800 * gat_save <filename>
801 *
802 *****************************************************************************/
gat_saveCircuit(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])803 static int gat_saveCircuit(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
804 {
805 const char *fileName = argv[1];
806
807 assert(argc == 2);
808
809 if (TkGate.circuit->c_isNewFile) {
810 FILE *f = fopen(fileName,"r");
811 int abortSave = 0;
812
813 if (f) {
814 DoTcl("yesno [format [m circ.reallyoverwrite] %s]",fileName);
815 if (strcmp(Tcl_GetStringResult(tcl),"yes") != 0)
816 abortSave = 1;
817
818 fclose(f);
819 }
820 if (abortSave) return TCL_OK;
821 }
822
823
824 ob_begin_framef("-Save",FF_TRANSPARENT);
825 ob_touch(TkGate.circuit);
826 TkGate.circuit->c_isNewFile = 0;
827 VerilogSave(fileName);
828 Circuit_setCurrentFile(fileName);
829 ob_end_frame();
830
831 return TCL_OK;
832 }
833
834
gat_addPort(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])835 static int gat_addPort(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
836 {
837 TkgGateWin *gw = TkGate.gw;
838 EditState *es = gw->parms->circuit->es;
839 GCElement *g;
840 GGateInfo *gi;
841 int i;
842
843 if (!modifyOK(es,2)) return TCL_OK;
844
845 g = TkGate.circuit->select;
846 if (!g) return TCL_OK;
847 gi = g->typeinfo;
848
849 if (gi->code == GC_BLOCK) {
850 message(1,msgLookup("err.oldportact"));
851 return TCL_OK;
852 }
853
854
855 /* Find port that can be extended. */
856 for (i = 0;i < gi->NumPads;i++)
857 if (gi->Pad[i].CanAdd) break;
858
859 if (i >= gi->NumPads) {
860 message(1,msgLookup("err.badportadd"));
861 return TCL_OK;
862 }
863
864 if (gi->Pad[i].iotype == IN )
865 (*gi->AddInput)(es,TkGate.circuit->select);
866 else if (gi->Pad[i].iotype == OUT)
867 (*gi->AddOutput)(es,TkGate.circuit->select);
868 else
869 (*gi->AddTri)(es,TkGate.circuit->select);
870
871 sel_refinish(es);
872
873 return TCL_OK;
874 }
875
gat_changePinDir(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])876 static int gat_changePinDir(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
877 {
878 TkgGateWin *gw = TkGate.gw;
879 EditState *es = gw->parms->circuit->es;
880
881 if (!TkGate.circuit->select)
882 return TCL_OK;
883
884 (*TkGate.circuit->select->typeinfo->ChangePin)(es,TkGate.circuit->select);
885
886 sel_refinish(es);
887
888 return TCL_OK;
889 }
890
gat_dohyperlink(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])891 static int gat_dohyperlink(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
892 {
893 if (argc == 2) {
894 dohyperlink(argv[1]);
895 }
896 return TCL_OK;
897 }
898
899 /*
900 Delete selected gate.
901 */
gat_deleteSelected(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])902 static int gat_deleteSelected(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
903 {
904 TkgGateWin *gw = TkGate.gw;
905 EditState *es = gw->parms->circuit->es;
906
907 if (!es) return TCL_OK;
908
909 if (!modifyOK(es,2)) return TCL_OK;
910
911 if ((es)->isInterface) {
912 sel_interfaceReset(es);
913 return TCL_OK;
914 }
915
916 if (TkGate.circuit->select || TkGate.circuit->mg_selection) {
917 sel_delete(es);
918 scrollbar_bbx_update();
919 } else if (DoTcl("tkg_getSelectedBlock") == TCL_OK && Tcl_GetStringResult(tcl)[0] != 0) {
920 DoTcl("BlockOp::delete");
921 } else {
922 message(1,msgLookup("err.nodel")); /* "No deletable selection." */
923 return TCL_OK;
924 }
925
926 SynchronizeInterface();
927
928 return TCL_OK;
929 }
930
gat_replicate(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])931 static int gat_replicate(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
932 {
933 TkgGateWin *gw = TkGate.gw;
934 EditState *es = gw->parms->circuit->es;
935
936 if (!modifyOK(es,0)) return TCL_OK;
937
938 setEditMode(es,MODE_REPLICATE);
939 scrollbar_bbx_update();
940
941 return TCL_OK;
942 }
943
gat_renameBlock(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])944 static int gat_renameBlock(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
945 {
946 TkgGateWin *gw = TkGate.gw;
947 EditState **es = &gw->parms->circuit->es;
948 const char *oldName,*newName;
949 const char *curName = TkGate.circuit->es->env->m_name;
950 int isCurrentRename = 0;
951
952 assert(argc == 3);
953 oldName = argv[1];
954 newName = argv[2];
955
956
957 /*
958 * Test to see if we are renaming the module we have open.
959 */
960 if (strcmp(oldName,curName) == 0) {
961 isCurrentRename = 1;
962 }
963
964 if (checkValidName(argv[2],0) != 0) {
965 message(1,msgLookup("err.badid"),argv[2]);
966 return TCL_OK;
967 }
968
969 if (!env_findModule(oldName)) {
970 message(1,msgLookup("err.modnotdef"),oldName); /* "Module '%s' is undefined." */
971 return TCL_OK;
972 }
973
974 if (env_findModule(newName)) {
975 message(1,msgLookup("err.moddef"),newName); /* "The block '%s' already exists." */
976 return TCL_OK;
977 }
978
979 env_rename(oldName,newName);
980
981
982 SetModified(MF_NET|MF_GATE|MF_MODULE);
983
984 if (isCurrentRename) {
985 editstate_setCurrent(*es);
986 SynchronizeInterface();
987 FlagRedraw();
988 }
989
990 return TCL_OK;
991 }
992
gat_computestrhash(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])993 static int gat_computestrhash(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
994 {
995 if (argc != 2) {
996 Tcl_SetResult(tcl, "wrong number of parameters.", TCL_STATIC);
997 return TCL_ERROR;
998 }
999
1000 Tcl_SetObjResult(tcl, Tcl_NewLongObj(computestrhash(argv[1])));
1001
1002 return TCL_OK;
1003 }
1004
gat_copyBlock(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1005 static int gat_copyBlock(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1006 {
1007 TkgGateWin *gw = TkGate.gw;
1008 EditState *es = gw->parms->circuit->es;
1009
1010 if (checkValidName(argv[2],0) != 0) {
1011 message(1,msgLookup("err.badid"),argv[2]);
1012 return TCL_OK;
1013 }
1014
1015 env_copy(es,argv[1],argv[2]);
1016
1017 SetModified(MF_MODULE);
1018
1019 return TCL_OK;
1020 }
1021
1022 /*****************************************************************************
1023 *
1024 * This function has no specific purpose. It is simply a placehold to put
1025 * debugging code for whatever bug I am currently trying to fix
1026 *
1027 *****************************************************************************/
gat_debug(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1028 static int gat_debug(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1029 {
1030 GModuleDef *m = env_findModule("REGS");
1031 GCElement *g;
1032 int n;
1033 int i;
1034
1035 if (GCElement_getType(m->m_interface) == GC_SYMBLOCK)
1036 g = m->m_interface;
1037 else
1038 g = m->m_altInterface;
1039
1040
1041 n = GCElement_numPads(g);
1042
1043 printf("REGS-symbol %p\n",g);
1044 for (i = 0;i < n;i++) {
1045 const char *name = GCElement_getPadName(g,i);
1046 /**
1047 * @TODO to remove
1048 */
1049 /* GWire *w = g->wires[i]; */
1050 printf(" pad %s:\n",name);
1051 }
1052
1053 return TCL_OK;
1054 }
1055
1056 /*****************************************************************************
1057 *
1058 * gat_deletBlock <name>
1059 *
1060 * Delete the named module
1061 *
1062 *****************************************************************************/
gat_deleteBlock(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1063 static int gat_deleteBlock(ClientData _d,Tcl_Interp *tcl,
1064 int argc,const char *argv[])
1065 {
1066 TkgGateWin *gw = TkGate.gw;
1067 EditState *es = gw->parms->circuit->es;
1068
1069 if (argv[1])
1070 env_delete(es,argv[1]);
1071
1072 return TCL_OK;
1073 }
1074
gat_claimBlock(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1075 static int gat_claimBlock(ClientData _d,Tcl_Interp *tcl,
1076 int argc,const char *argv[])
1077 {
1078 GModuleDef *M;
1079
1080 if (argc < 2) return TCL_OK;
1081
1082 M = env_findModule(argv[1]);
1083 if (M) {
1084 if (!M->m_isLib) {
1085 message(1,msgLookup("msg.notlib"),argv[1]); /* Not a library module */
1086 return TCL_OK;
1087 }
1088
1089 /* DoTcl("tkg_blockListSetLibFlag %s 0",argv[1]);*/
1090 GModuleDef_claim(M);
1091 SetModified(MF_MODULE);
1092 }
1093
1094 return TCL_OK;
1095 }
1096
1097 /*****************************************************************************
1098 * gat_newBlock name
1099 *
1100 *****************************************************************************/
gat_newBlock(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1101 static int gat_newBlock(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1102 {
1103 GModuleDef *M;
1104 char *aname;
1105 const char *modName;
1106
1107 if (argc != 2) {
1108 Tcl_SetResult(tcl, "wrong number of arguments.", TCL_STATIC);
1109 return TCL_ERROR;
1110 }
1111
1112 aname = (char*)argv[1];
1113
1114 Tcl_SetVar2(tcl,aname,"ok","0",TCL_GLOBAL_ONLY);
1115
1116 modName = Tcl_GetVar2(tcl,aname,"name",TCL_GLOBAL_ONLY);
1117 if (!modName || !*modName || checkValidName(modName,0) != 0) {
1118 message(1,msgLookup("err.badid"),modName);
1119 return TCL_OK;
1120 }
1121 if (env_findModule(modName)) {
1122 message(1,msgLookup("err.moddef"),modName);
1123 return TCL_OK;
1124 }
1125 if (strncmp(modName,TkGate.circuit->c_gatePrefix,strlen(TkGate.circuit->c_gatePrefix)) == 0) {
1126 message(1,msgLookup("err.primprefix"),modName,TkGate.circuit->c_gatePrefix);
1127 return TCL_OK;
1128 }
1129 if (ycIsKW((char*)modName)) {
1130 message(1,msgLookup("err.iskeyword"),modName);
1131 return TCL_OK;
1132 }
1133
1134 M = env_defineModule(modName,0);
1135 if (M) {
1136 const char *r;
1137
1138 r = Tcl_GetVar2(tcl,aname,"ppos",TCL_GLOBAL_ONLY);
1139 M->m_pptype = (strcmp(r,"fix") == 0) ? PPT_FIXED : PPT_SCALED;
1140
1141 r = Tcl_GetVar2(tcl,aname,"type",TCL_GLOBAL_ONLY);
1142 M->m_type = (strcmp(r,"netlist") == 0) ? MT_NETLIST : MT_TEXTHDL;
1143
1144 r = Tcl_GetVar2(tcl,aname,"prot",TCL_GLOBAL_ONLY);
1145 M->m_protData = strbin(r);
1146
1147 r = Tcl_GetVar2(tcl,aname,"protint",TCL_GLOBAL_ONLY);
1148 M->m_protIntf = strbin(r);
1149
1150 r = Tcl_GetVar2(tcl,aname,"proted",TCL_GLOBAL_ONLY);
1151 M->m_protEdit = strbin(r);
1152
1153 Tcl_SetVar2(tcl,aname,"ok","1",TCL_GLOBAL_ONLY);
1154 }
1155
1156 if (M->m_type == MT_TEXTHDL) {
1157 char buf[STRMAX];
1158
1159 sprintf(buf,"module %s;\n\nendmodule\n",M->m_name);
1160 GModuleDef_saveText(M,buf);
1161 }
1162
1163 return TCL_OK;
1164 }
1165
gat_batInc(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1166 static int gat_batInc(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1167 {
1168 TkgGateWin *gw = TkGate.gw;
1169 EditState *es = gw->parms->circuit->es;
1170
1171 if (TkGate.batp) {
1172 SetBatCursor(es);
1173 Tcl_Eval(tcl,"after $tkg_batRate gat_batInc");
1174 }
1175
1176 return TCL_OK;
1177 }
1178
1179 /*****************************************************************************
1180 *
1181 * Set variables for the delays of the currently seleced gate in the specified tecnology
1182 *
1183 ******************************************************************************/
gat_setGateTechDelays(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1184 static int gat_setGateTechDelays(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1185 {
1186 GCElement *g = TkGate.circuit->select;
1187 GDelayDef *dd;
1188 GGateInfo *gi;
1189 int i;
1190 int delays[MAXDELAYS];
1191
1192 if (!g) return TCL_OK;
1193 gi = g->typeinfo;
1194
1195 dd = GDelayDef_findTech(gi->delay_defs,argv[1]);
1196 if (!dd) return TCL_OK;
1197
1198 if (GDelayDef_getDelays(dd, g, delays) < 0)
1199 return TCL_OK;
1200
1201 for (i = 0;i < gi->num_delays;i++) {
1202 DoTcl("set ::edgat_techdelay(%s) %d",gi->delayNames[i],delays[i]);
1203 }
1204 DoTcl("update");
1205 return TCL_OK;
1206 }
1207
1208 /*
1209 * gat_editProps
1210 *
1211 * Used for implementing the edit gate (or net) properties boxes. This
1212 * should probably be rewritten at some time to use the same dialog box
1213 * model as module properties boxes.
1214 *
1215 */
gat_editProps(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1216 static int gat_editProps(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1217 {
1218 TkgGateWin *gw = TkGate.gw;
1219 EditState **es = &gw->parms->circuit->es;
1220 GCElement *g = TkGate.circuit->select;
1221 GGateInfo *gi;
1222 const char *temp;
1223 int ok;
1224
1225 /*
1226 * If we are editing the interface, then switch to editing a specific module.
1227 */
1228 if ((*es)->isInterface) {
1229 if (g->typeinfo->code == GC_BLOCK) {
1230 GWire *w = block_hitPort(g,TkGate.ed->tx,TkGate.ed->ty);
1231 if (w) {
1232 block_setPortName(g,w,*es);
1233 return TCL_OK;
1234 }
1235 }
1236
1237 if (editstate_getInterfaceMode() == INTFMODE_ALL)
1238 modint_openSelected(0);
1239 return TCL_OK;
1240 }
1241
1242 if ((!g || g->typeinfo->code == GC_JOINT) && TkGate.circuit->nsel) {
1243 DoTcl("gat_editNet %s",TkGate.circuit->nsel->n_signame);
1244 return TCL_OK;
1245 }
1246
1247 if (!g) {
1248 DoTcl("SideBar::editModuleOrNet");
1249 return TCL_OK;
1250 }
1251 gi = g->typeinfo;
1252
1253 switch (gi->code) {
1254 case GC_BLOCK :
1255 {
1256 GWire *w = block_hitPort(g,TkGate.ed->tx,TkGate.ed->ty);
1257 if (w) {
1258 block_setPortName(g,w,*es);
1259 return TCL_OK;
1260 }
1261 }
1262 break;
1263 case GC_JOINT :
1264 return TCL_OK;
1265 case GC_LOGICIN :
1266 case GC_LOGICTRI :
1267 case GC_LOGICOUT :
1268 net_editProps(g->wires[0]->net,TkGate.ed->tx,TkGate.ed->ty);
1269 return TCL_OK;
1270 }
1271
1272 if (!gi->EditProps) {
1273 message(1,msgLookup("err.noprop")); /* Selected gate has no editable properites. */
1274 return TCL_OK;
1275 }
1276
1277
1278 /*
1279 * Standard gate properties editing.
1280 */
1281 #if 0
1282 printf("gat_editProps g=%p gi=%p [%s]\n",g,gi,gi->name);
1283 #endif
1284 (*gi->EditProps)(g,1);
1285 DoTcl("EditGate::post");
1286 if ((temp = Tcl_GetVar(tcl,"edgat_ok",TCL_GLOBAL_ONLY)) && sscanf(temp,"%d",&ok) == 1 && ok) {
1287 if (GModuleDef_isDataProtected(TkGate.circuit->es->env)) {
1288 message(0,msgLookup("err.protdata")); /* "Can not edit library module." */
1289 return TCL_OK;
1290 }
1291
1292 if (tkgate_currentMode() == MM_EDIT)
1293 (*gi->EditProps)(g,0);
1294 else
1295 message(1,msgLookup("err.noteditpchg"));
1296 }
1297
1298 sel_refinish(*es);
1299
1300 return TCL_OK;
1301 }
1302
1303 /*****************************************************************************
1304 * gat_editCircProps <command> <array>
1305 *
1306 * Save or load properties about the circuit. "<command>" is either "load" or "save"
1307 *
1308 *
1309 * file File name
1310 * filev File version
1311 * title Circuit title
1312 * discard Discard changes on quiting (used for tutorial circuits)
1313 * extbar Extender bar style
1314 * scripts List of simulator scripts
1315 *
1316 *****************************************************************************/
gat_editCircProps(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1317 static int gat_editCircProps(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1318 {
1319 static char *tvModeNames[] = {"never","after","all"};
1320 char *aname = 0;
1321 Circuit *c = TkGate.circuit;
1322
1323 if (argc != 3) {
1324 Tcl_SetResult(tcl, "wrong number of arguments.", TCL_STATIC);
1325 return TCL_ERROR;
1326 }
1327
1328 /* Tcl/Tk 8.3 wants non-const parameters to SetVar */
1329 aname = (char*)argv[2];
1330
1331 if (strcmp(argv[1],"load") == 0) {
1332 int n;
1333 char u[STRMAX];
1334
1335 Tcl_SetVar2(tcl,aname,"file",CurrentFile_path(c->currentFile),TCL_GLOBAL_ONLY);
1336 Tcl_SetVar2(tcl,aname,"filev",c->fileVersion,TCL_GLOBAL_ONLY);
1337 Tcl_SetVar2(tcl,aname,"title",c->title,TCL_GLOBAL_ONLY);
1338 Tcl_SetVar2(tcl,aname,"encoding",c->c_encoding,TCL_GLOBAL_ONLY);
1339 Tcl_SetVar2(tcl,aname,"locale",c->c_locale->l_name,TCL_GLOBAL_ONLY);
1340 Tcl_SetVar2(tcl,aname,"discard",binstr(c->discardChanges),TCL_GLOBAL_ONLY);
1341 Tcl_SetVar2(tcl,aname,"extbar",binstr(c->useExtBars),TCL_GLOBAL_ONLY);
1342 Tcl_SetVar2(tcl,aname,"shownet",binstr(c->showSwitchNets),TCL_GLOBAL_ONLY);
1343 Tcl_SetVar2(tcl,aname,"autostart",binstr(c->simAutoStart),TCL_GLOBAL_ONLY);
1344 Tcl_SetVar2(tcl,aname,"clockMode",binstr(c->simClockMode),TCL_GLOBAL_ONLY);
1345 Tcl_SetVar2(tcl,aname,"clockName",c->simClockName,TCL_GLOBAL_ONLY);
1346 if (c->numInitScripts > 0) {
1347 char *scripts = Tcl_Merge(c->numInitScripts,(const char**)c->initScripts);
1348 Tcl_SetVar2(tcl,aname,"scripts",scripts,TCL_GLOBAL_ONLY);
1349 if (scripts)
1350 Tcl_Free((char*)scripts);
1351 } else
1352 Tcl_SetVar2(tcl,aname,"scripts","",TCL_GLOBAL_ONLY);
1353
1354 Timescale_decode(c->c_timescale.ts_units, &n, u);
1355 Tcl_SetVar2(tcl,aname,"unitsU",u,TCL_GLOBAL_ONLY);
1356 sprintf(u,"%d",n);
1357 Tcl_SetVar2(tcl,aname,"unitsN",u,TCL_GLOBAL_ONLY);
1358
1359 Timescale_decode(c->c_timescale.ts_precision, &n, u);
1360 Tcl_SetVar2(tcl,aname,"precisionU",u,TCL_GLOBAL_ONLY);
1361 sprintf(u,"%d",n);
1362 Tcl_SetVar2(tcl,aname,"precisionN",u,TCL_GLOBAL_ONLY);
1363
1364 sprintf(u,"%lg",c->c_startup);
1365 Tcl_SetVar2(tcl,aname,"initMode",tvModeNames[c->c_tvMode],TCL_GLOBAL_ONLY);
1366 Tcl_SetVar2(tcl,aname,"initTime",u,TCL_GLOBAL_ONLY);
1367 Tcl_SetVar2(tcl,aname,"initUnits",Timescale_codeToUnits(c->c_startupUnits),TCL_GLOBAL_ONLY);
1368 } else if (strcmp(argv[1],"save") == 0) {
1369 const char *r;
1370 int numScripts;
1371 const char **scriptList;
1372 int n;
1373 Locale *locale;
1374
1375 r = Tcl_GetVar2(tcl,aname,"ok",TCL_GLOBAL_ONLY);
1376 if (r && *r == '1') {
1377 r = Tcl_GetVar2(tcl,aname,"discard",TCL_GLOBAL_ONLY);
1378 c->discardChanges = strbin(r);
1379 r = Tcl_GetVar2(tcl,aname,"extbar",TCL_GLOBAL_ONLY);
1380 c->useExtBars = strbin(r);
1381 r = Tcl_GetVar2(tcl,aname,"shownet",TCL_GLOBAL_ONLY);
1382 c->showSwitchNets = strbin(r);
1383 r = Tcl_GetVar2(tcl,aname,"autostart",TCL_GLOBAL_ONLY);
1384 c->simAutoStart = strbin(r);
1385 r = Tcl_GetVar2(tcl,aname,"title",TCL_GLOBAL_ONLY);
1386 Circuit_setTitle(r);
1387 r = Tcl_GetVar2(tcl,aname,"encoding",TCL_GLOBAL_ONLY);
1388 Circuit_setFileEncoding(c,r);
1389
1390 r = Tcl_GetVar2(tcl,aname,"locale",TCL_GLOBAL_ONLY);
1391 locale = (Locale*)SHash_find(TkGate.localeNameTable,r);
1392 if (locale && c->c_locale != locale) {
1393 Circuit_setLocale(c,locale);
1394 FlagRedraw();
1395 }
1396
1397 r = Tcl_GetVar2(tcl,aname,"clockMode",TCL_GLOBAL_ONLY);
1398 c->simClockMode = strbin(r);
1399 r = Tcl_GetVar2(tcl,aname,"clockName",TCL_GLOBAL_ONLY);
1400 Circuit_setClockName(r);
1401
1402 r = Tcl_GetVar2(tcl,aname,"scripts",TCL_GLOBAL_ONLY);
1403 if (Tcl_SplitList(tcl,r,&numScripts,&scriptList) == TCL_OK) {
1404 Circuit_setScripts(numScripts,scriptList);
1405 if (scriptList)
1406 Tcl_Free((char*)scriptList);
1407 }
1408
1409 r = Tcl_GetVar2(tcl,aname,"unitsN",TCL_GLOBAL_ONLY);
1410 sscanf(r,"%d",&n);
1411 r = Tcl_GetVar2(tcl,aname,"unitsU",TCL_GLOBAL_ONLY);
1412 c->c_timescale.ts_units = Timescale_parse(n,r);
1413 r = Tcl_GetVar2(tcl,aname,"precisionN",TCL_GLOBAL_ONLY);
1414 sscanf(r,"%d",&n);
1415 r = Tcl_GetVar2(tcl,aname,"precisionU",TCL_GLOBAL_ONLY);
1416 c->c_timescale.ts_precision = Timescale_parse(n,r);
1417
1418 if (c->c_timescale.ts_precision > c->c_timescale.ts_units)
1419 c->c_timescale.ts_precision = c->c_timescale.ts_units;
1420
1421 r = Tcl_GetVar2(tcl,aname,"initMode",TCL_GLOBAL_ONLY);
1422 for (n = 0;n < 3;n++)
1423 if (strcmp(r,tvModeNames[n]) == 0) {
1424 c->c_tvMode = n;
1425 break;
1426 }
1427 r = Tcl_GetVar2(tcl,aname,"initTime",TCL_GLOBAL_ONLY);
1428 sscanf(r,"%lf",&c->c_startup);
1429 r = Tcl_GetVar2(tcl,aname,"initUnits",TCL_GLOBAL_ONLY);
1430 c->c_startupUnits = Timescale_unitsToCode(r);
1431 if (c->c_startupUnits < 0) {
1432 c->c_startupUnits = UC_NANOSEC;
1433 logError(ERL_WARN,"bad unit code in gat_editCircProps.");
1434 }
1435 }
1436 } else {
1437 Tcl_SetResult(tcl, "bad command.", TCL_STATIC);
1438 return TCL_ERROR;
1439 }
1440
1441 Tcl_SetVar2(tcl,aname,"ok","1",TCL_GLOBAL_ONLY);
1442
1443 return TCL_OK;
1444 }
1445
1446
1447 /*****************************************************************************
1448 *
1449 * gat_editModProps <command> <array> <module>
1450 *
1451 * Save or load properties about a module. "<command>" is either "load" or "save"
1452 *
1453 *****************************************************************************/
gat_editModProps(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1454 static int gat_editModProps(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1455 {
1456 char *aname = 0;
1457 char *mname = 0;
1458 GModuleDef *M;
1459
1460 if (argc != 4) {
1461 Tcl_SetResult(tcl, "wrong number of arguments.", TCL_STATIC);
1462 return TCL_ERROR;
1463 }
1464
1465 /* Tcl/Tk 8.3 wants non-const parameters to SetVar */
1466 aname = (char*)argv[2];
1467 mname = (char*)argv[3];
1468
1469 M = env_findModule(mname);
1470 if (!M) {
1471 Tcl_SetVar2(tcl,aname,"ok","0",TCL_GLOBAL_ONLY);
1472 return TCL_OK;
1473 }
1474
1475 if (strcmp(argv[1],"load") == 0) {
1476 GModuleDef_getPropsToTcl(M,tcl,aname);
1477 } else if (strcmp(argv[1],"save") == 0) {
1478 GModuleDef_setPropsFromTcl(M,tcl,aname);
1479 SetModified(MF_MODULE);
1480 SynchronizeInterface();
1481 } else {
1482 Tcl_SetResult(tcl, "bad command.", TCL_STATIC);
1483 return TCL_ERROR;
1484 }
1485
1486 Tcl_SetVar2(tcl,aname,"ok","1",TCL_GLOBAL_ONLY);
1487
1488 return TCL_OK;
1489 }
1490
1491 /*****************************************************************************
1492 *
1493 * Update net properties
1494 *
1495 *****************************************************************************/
gat_changeNet(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1496 static int gat_changeNet(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1497 {
1498 TkgGateWin *gw = TkGate.gw;
1499 EditState *es = gw->parms->circuit->es;
1500 const char *oldName = argv[1];
1501 const char *newName = argv[2];
1502 const char *vtype = argv[6];
1503 int hide = 0;
1504 int nbits = 1;
1505 int io = 0;
1506 GNet *n;
1507 GWire *w;
1508
1509 if (GModuleDef_isDataProtected(TkGate.circuit->es->env)) {
1510 message(0,msgLookup("err.protdata")); /* "Can not edit library module." */
1511 return TCL_OK;
1512 }
1513
1514 sscanf(argv[3],"%d",&hide);
1515 sscanf(argv[4],"%d",&nbits);
1516 sscanf(argv[5],"%d",&io);
1517
1518 n = (GNet*) SHash_find(es->env->m_nets,oldName);
1519
1520 if (!n) return TCL_OK;
1521
1522 w = n->n_driver;
1523 net_setSize(w->net,nbits);
1524 net_rename(n,newName,!hide);
1525 GNet_setVType(n, vtype);
1526
1527 if (w->net->n_ionet) {
1528 GGateInfo *gi = GGateInfo_codeLookup(io);
1529 if (gi && (gi->code == GC_LOGICIN || gi->code == GC_LOGICOUT || gi->code == GC_LOGICTRI))
1530 gate_transmute(w->net->n_ionet,gi);
1531 }
1532
1533 FlagRedraw();
1534
1535 return TCL_OK;
1536 }
1537
gat_unselectGates(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1538 static int gat_unselectGates(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1539 {
1540 TkgGateWin *gw = TkGate.gw;
1541 EditState *es = gw->parms->circuit->es;
1542
1543 EditState_unselectAll(es);
1544 return TCL_OK;
1545 }
1546
1547 /*****************************************************************************
1548 *
1549 * Repalace a module instance with the current interface for a module and
1550 * attempt to reconnect all ports. If the -all switch is given, then all instance
1551 * of the selected module are updated.
1552 *
1553 * Usage:
1554 * gat_updateInterface [name]
1555 * gat_updateInterface -all
1556 *
1557 *****************************************************************************/
gat_updateInterface(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1558 static int gat_updateInterface(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1559 {
1560 GCElement *g = TkGate.circuit->select;
1561 const char *modName = 0;
1562 GModuleDef *M = 0;
1563
1564
1565 if (argc == 1) {
1566 if (!g) return TCL_OK;
1567 if (GCElement_getType(g) != GC_BLOCK && GCElement_getType(g) != GC_SYMBLOCK) return TCL_OK;
1568 block_updateInterface(g, TkGate.circuit->es->env);
1569
1570 return TCL_OK;
1571 }
1572
1573 if (strcmp(argv[1],"-all") == 0) {
1574 if (DoTcl("tkg_getSelectedBlock") == TCL_OK && Tcl_GetStringResult(tcl)[0] != 0)
1575 modName = Tcl_GetStringResult(tcl);
1576 else if (g && (GCElement_getType(g) == GC_BLOCK || GCElement_getType(g) == GC_SYMBLOCK))
1577 modName = g->u.block.moduleName;
1578 else
1579 return TCL_OK;
1580 } else {
1581 modName = TkGate.circuit->es->env->m_name;
1582 }
1583
1584 M = env_findModule(modName);
1585 if (!M) return TCL_OK;
1586
1587 DoTcl("yesno [format [m circ.reallyupdate] %s]",GModuleDef_getName(M));
1588
1589
1590 /*
1591 * Scan circuit for instance of module M and update their interfaces.
1592 */
1593 if (strcmp(Tcl_GetStringResult(tcl),"yes") == 0) {
1594 Circuit *C = TkGate.circuit;
1595 HashElem *he;
1596 for (he = Hash_first(C->moduleTable);he;he = Hash_next(C->moduleTable,he)) {
1597 GModuleDef *PM = (GModuleDef*)HashElem_obj(he);
1598 HashElem *ghe;
1599 for (ghe = Hash_first(PM->m_gates);ghe;ghe = Hash_next(PM->m_gates,ghe)) {
1600 g = (GCElement*)HashElem_obj(ghe);
1601 if ((GCElement_getType(g) == GC_BLOCK || GCElement_getType(g) == GC_SYMBLOCK) &&
1602 strcmp(g->u.block.moduleName,GModuleDef_getName(M)) == 0) {
1603 block_updateInterface(g, PM);
1604 }
1605 }
1606 }
1607 }
1608
1609 return TCL_OK;
1610 }
1611
gat_updateModuleTree(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1612 static int gat_updateModuleTree(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1613 {
1614 SetModified(MF_MODULE);
1615 SynchronizeInterface();
1616 #if 0
1617 /* We now do this indirectly */
1618 env_updateMTCircuit();
1619 #endif
1620
1621 return TCL_OK;
1622 }
1623
gat_updateMenuState(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1624 static int gat_updateMenuState(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1625 {
1626 sel_updateMenuState();
1627 return TCL_OK;
1628 }
1629
1630
1631
1632
gat_setBlockDesc(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1633 static int gat_setBlockDesc(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1634 {
1635 GCElement *g = TkGate.circuit->select;
1636
1637 if (tkgate_currentMode() != MM_EDIT) {
1638 message(0,msgLookup("err.editonly"));
1639 return TCL_OK;
1640 }
1641
1642 if (g && g->typeinfo->code == GC_BLOCK) {
1643 GModuleDef *M = env_findAdd(g->u.block.moduleName,0);
1644 if (modint_setInterface(M,g) == 0)
1645 message(0,msgLookup("msg.setinterface"),g->u.block.moduleName);/* Set module interface for '%s'. */
1646 } else
1647 message(0,msgLookup("msg.needsel")); /* Please select a module instance. */
1648
1649 return TCL_OK;
1650 }
1651
1652 /*****************************************************************************
1653 *
1654 * Begin interface edit mode
1655 *
1656 * If no argument are given, the current module is opened. If a module name
1657 * is given then that interface is opened.
1658 *
1659 *****************************************************************************/
gat_editBlockDesc(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1660 static int gat_editBlockDesc(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1661 {
1662 TkgGateWin *gw = TkGate.gw;
1663 EditState **es = &gw->parms->circuit->es;
1664 GModuleDef *M = 0;
1665
1666 if (argc > 1) {
1667 M = env_findAdd(argv[1],0);
1668 } else {
1669 M = (TkGate.circuit->root_mod == (*es)->env) ? 0 : (*es)->env;
1670 }
1671
1672 if (tkgate_currentMode() == MM_EDIT && !TkGate.circuit->es->isInterface && hdl_checkSave(0) < 0)
1673 return TCL_OK;
1674
1675 ob_touch(TkGate.circuit);
1676
1677 modint_edit(es,M);
1678
1679 return TCL_OK;
1680 }
1681
gat_moveGate(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1682 static int gat_moveGate(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1683 {
1684 TkgGateWin *gw = TkGate.gw;
1685 EditState *es = gw->parms->circuit->es;
1686 int dx = 0,dy =0;
1687
1688 assert(argc == 3);
1689
1690 sscanf(argv[1],"%d",&dx);
1691 sscanf(argv[2],"%d",&dy);
1692
1693 sel_draw(es);
1694 sel_move(es,dx,dy);
1695 sel_draw(es);
1696
1697 return TCL_OK;
1698 }
1699
gat_editNet(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1700 static int gat_editNet(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1701 {
1702 GNet *net;
1703 char buf[STRMAX],*p;
1704
1705 if (tkgate_currentMode() != MM_EDIT) return TCL_OK;
1706
1707 strcpy(buf,argv[1]);
1708 if ((p = strchr(buf,'['))) *p = 0;
1709 if ((p = strchr(buf,'@'))) *p = 0;
1710
1711 net = GModuleDef_findNet(TkGate.circuit->es->env,buf);
1712 if (net && net->n_driver)
1713 net_editProps(net,net->n_driver->nodes->x,net->n_driver->nodes->y);
1714
1715 return TCL_OK;
1716 }
1717
1718 /****************************************************************************
1719 *
1720 * Get the selected object, append it to the cut buffer and delete the object
1721 * in the edit window. Only usable for HDL.
1722 *
1723 * Usage: gat_CutToBufAppend
1724 *
1725 *****************************************************************************/
gat_cutToBufAppend(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1726 static int gat_cutToBufAppend(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1727 {
1728 TkgGateWin *gw = TkGate.gw;
1729 EditState *es = gw->parms->circuit->es;
1730
1731 if (es->isInterface) {
1732 sel_interfaceReset(es);
1733 } else {
1734 sel_killAppend(es);
1735 FlagRedraw();
1736 }
1737
1738 return TCL_OK;
1739 }
1740
1741 /****************************************************************************
1742 *
1743 * Get the selected object, copy it to the cut buffer and delete the object
1744 * in the edit window.
1745 *
1746 * Usage: gat_cutToBuf
1747 *
1748 *****************************************************************************/
gat_cutToBuf(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1749 static int gat_cutToBuf(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1750 {
1751 TkgGateWin *gw = TkGate.gw;
1752 EditState *es = gw->parms->circuit->es;
1753
1754 if (es->isInterface) {
1755 sel_interfaceReset(es);
1756 } else {
1757 sel_kill(es);
1758 FlagRedraw();
1759 }
1760
1761 return TCL_OK;
1762 }
1763
1764 /****************************************************************************
1765 *
1766 * Get the selected object and copy it to the cut buffer
1767 *
1768 * Usage: gat_copyToBuf
1769 *
1770 *****************************************************************************/
gat_copyToBuf(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1771 static int gat_copyToBuf(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1772 {
1773 TkgGateWin *gw = TkGate.gw;
1774 EditState *es = gw->parms->circuit->es;
1775
1776 if (!es->isInterface)
1777 sel_copy(es);
1778
1779 return TCL_OK;
1780 }
1781
1782 /****************************************************************************
1783 *
1784 * Yank the object(s) from the cut buffer and paste it into the current module.
1785 *
1786 * Usage: gat_yankFromBuf [dx] [dy]
1787 *
1788 *
1789 *****************************************************************************/
gat_yankFromBuf(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1790 static int gat_yankFromBuf(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1791 {
1792 TkgGateWin *gw = TkGate.gw;
1793 EditState *es = gw->parms->circuit->es;
1794 /**
1795 * @TODO to remove
1796 */
1797 /* GModuleDef *m = es->env; */
1798 int dx,dy;
1799
1800 if (!modifyOK(es,0)) return TCL_OK;
1801
1802 if (hdl_isactive) {
1803 sel_hdlyank(es);
1804 } else {
1805 if (argc >= 3) {
1806 sscanf(argv[1],"%d",&dx);
1807 sscanf(argv[2],"%d",&dy);
1808
1809 if (TkGate.circuit->cut_buffer) {
1810 mark_unpost();
1811 TkGate.ed->tx = TkGate.circuit->cut_buffer->cb_ctrx + dx;
1812 TkGate.ed->ty = TkGate.circuit->cut_buffer->cb_ctry + dy;
1813 }
1814 }
1815 sel_yank(es);
1816 FlagRedraw();
1817 }
1818
1819
1820 return TCL_OK;
1821 }
1822
1823 /*****************************************************************************
1824 *
1825 * Usage: gat_selectAll
1826 *
1827 * Select all gates in the current module
1828 *
1829 *****************************************************************************/
gat_selectAll(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1830 static int gat_selectAll(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1831 {
1832 TkgGateWin *gw = TkGate.gw;
1833 EditState *es = gw->parms->circuit->es;
1834
1835 mark_unpost();
1836 sel_clear(es,1);
1837 sel_selectAll(es);
1838
1839 EditState_setRotation(MODE_MOVESEL);
1840 return TCL_OK;
1841 }
1842
1843
1844 /*****************************************************************************
1845 *
1846 * Usage: gat_selectNet [name]
1847 *
1848 * Select the specified net in the current module
1849 *
1850 *****************************************************************************/
gat_selectNet(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1851 static int gat_selectNet(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1852 {
1853 TkgGateWin *gw = TkGate.gw;
1854 EditState *es = gw->parms->circuit->es;
1855 GModuleDef *m = es->env;
1856 GNet *n;
1857
1858 if (argc != 2) {
1859 return TCL_OK;
1860 }
1861
1862 n = GModuleDef_findNet(m,argv[1]);
1863 if (n) {
1864 net_select(n,1);
1865 }
1866
1867 return TCL_OK;
1868 }
1869
1870 /*****************************************************************************
1871 *
1872 * Usage: gat_rotate
1873 *
1874 * Rotates the gates in the selection.
1875 *
1876 *****************************************************************************/
gat_rotate(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1877 static int gat_rotate(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1878 {
1879 TkgGateWin *gw = TkGate.gw;
1880 EditState *es = gw->parms->circuit->es;
1881 int rdir = 1;
1882
1883 if (argc >= 2) {
1884 sscanf(argv[1],"%d",&rdir);
1885 if (rdir < 0)
1886 rdir = -1;
1887 else
1888 rdir = 1;
1889 }
1890
1891 if (!modifyOK(es,0)) return TCL_OK;
1892 if (tkgate_currentMode() != MM_EDIT) return TCL_OK;
1893 if (es->isInterface) return TCL_OK;
1894
1895 sel_refinish(es);
1896
1897 sel_draw(es);
1898 sel_rotate(es,rdir);
1899 sel_draw(es);
1900
1901 return TCL_OK;
1902 }
1903
1904
1905 /*
1906 Check to see if breakpoint expression is valid.
1907
1908 The first argument specifies the breakpoint operation to perform.
1909
1910 -load Load breakpoints into tk listbox
1911 -clear Clear all breakpoints
1912 -replace n bp Replace a breakpoint
1913 -insert n bp Insert a breakpoint
1914 -delete n Delete a breakpoint
1915
1916 The 'replace' and 'insert' commands will return a negative value on error.
1917 Otherwise they will return the id number of the breakpoint.
1918 */
gat_breakpoint(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1919 static int gat_breakpoint(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1920 {
1921 NHash *bpm = TkGate.circuit->c_breakpoints;
1922 int i,r;
1923
1924 r = 0;
1925
1926 #if 0
1927 {
1928 for (i = 0;i < argc;i++)
1929 printf("%s ",argv[i]);
1930 printf("\n");
1931 }
1932 #endif
1933
1934
1935 if (strcmp(argv[1],"-load") == 0) {
1936 /*
1937 * Load breakpoints from internal state
1938 */
1939 BrkPtTable_loadInterface(bpm);
1940 r = 0;
1941 } else if (strcmp(argv[1],"-clear") == 0) {
1942 /*
1943 * Clear all breakpoints from internal state
1944 */
1945 BrkPtTable_clearStop(bpm);
1946 } else if (strcmp(argv[1],"-replace") == 0) {
1947 /*
1948 * Clear all breakpoints from internal state
1949 */
1950 if (sscanf(argv[2],"%d",&i) != 1) return -1;
1951 BrkPtTable_delete(bpm,i);
1952 r = BrkPtTable_insert(bpm,i,argv[3]);
1953 } else if (strcmp(argv[1],"-insert") == 0) {
1954 /*
1955 * Insert a new breakpoint
1956 */
1957 if (sscanf(argv[2],"%d",&i) != 1) return -1;
1958 r = BrkPtTable_insert(bpm,i,argv[3]);
1959 } else if (strcmp(argv[1],"-delete") == 0) {
1960 /*
1961 * Delete a new breakpoint
1962 */
1963 if (sscanf(argv[2],"%d",&i) != 1) return -1;
1964 BrkPtTable_delete(bpm,i);
1965 r = 0;
1966 } else if (strcmp(argv[1],"-enable") == 0) {
1967 /*
1968 * Delete a new breakpoint
1969 */
1970 if (sscanf(argv[2],"%d",&i) != 1) return -1;
1971 BrkPtTable_enable(bpm,i);
1972 r = 0;
1973 } else if (strcmp(argv[1],"-disable") == 0) {
1974 /*
1975 * Delete a new breakpoint
1976 */
1977 if (sscanf(argv[2],"%d",&i) != 1) return -1;
1978 BrkPtTable_disable(bpm,i);
1979 r = 0;
1980 }
1981
1982 Tcl_SetObjResult(tcl, Tcl_NewIntObj(r));
1983 return TCL_OK;
1984 }
1985
gat_simSelected(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])1986 static int gat_simSelected(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
1987 {
1988 GCElement *g = TkGate.circuit->select;
1989 int i;
1990 int match = 0;
1991
1992 if (!g) {
1993 Tcl_ResetResult(tcl);
1994 return TCL_OK;
1995 }
1996
1997 if (argc == 1)
1998 match = 1;
1999 else {
2000 for (i = 1;i < argc;i++)
2001 if (g->typeinfo == GGateInfo_vlookup(argv[i])) {
2002 match = 1;
2003 break;
2004 }
2005 }
2006
2007 if (!match) {
2008 Tcl_ResetResult(tcl);
2009 return TCL_OK;
2010 }
2011
2012 GSimModule_getFullPath(TkGate.circuit->es->smod,g,(char *)Tcl_GetStringResult(tcl));
2013
2014 return TCL_OK;
2015 }
2016
gat_print(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2017 static int gat_print(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2018 {
2019 int i;
2020 GPrintOpt PO;
2021
2022 GPrintOpt_init(&PO);
2023
2024 for (i = 1;i < argc;i+=2) {
2025 if (i+1 >= argc) break;
2026 if (strcmp(argv[i],"-printer") == 0)
2027 PO.po_cmd = argv[i+1];
2028 else if (strcmp(argv[i],"-file") == 0)
2029 PO.po_file = argv[i+1];
2030 else if (strcmp(argv[i],"-paper") == 0)
2031 PO.po_paper = argv[i+1];
2032 else if (strcmp(argv[i],"-orient") == 0)
2033 PO.po_orient = argv[i+1];
2034 else if (strcmp(argv[i],"-style") == 0)
2035 PO.po_style = argv[i+1];
2036 else if (strcmp(argv[i],"-select") == 0)
2037 PO.po_select = argv[i+1];
2038 else if (strcmp(argv[i],"-modlist") == 0)
2039 PO.po_modlist = argv[i+1];
2040 else if (strcmp(argv[i],"-index") == 0)
2041 PO.po_index = argv[i+1];
2042 else if (strcmp(argv[i],"-graph") == 0)
2043 PO.po_graph = argv[i+1];
2044 else if (strcmp(argv[i],"-epsf") == 0)
2045 PO.po_epsf = argv[i+1];
2046 else if (strcmp(argv[i],"-merge") == 0)
2047 PO.po_4up = argv[i+1];
2048 else if (strcmp(argv[i],"-duplex") == 0)
2049 PO.po_isDuplex = argv[i+1];
2050 else if (strcmp(argv[i],"-inclib") == 0)
2051 PO.po_incLib = argv[i+1];
2052 }
2053
2054 GPrintOpt_print(&PO);
2055
2056 return TCL_OK;
2057 }
2058
gat_cleanUp(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2059 static int gat_cleanUp(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2060 {
2061 gateCleanUp();
2062 return TCL_OK;
2063 }
2064
2065
gat_tracePrint(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2066 static int gat_tracePrint(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2067 {
2068 int i;
2069 GPrintOpt PO;
2070
2071 GPrintOpt_init(&PO);
2072
2073 for (i = 1;i < argc;i+=2) {
2074 if (i+1 >= argc) break;
2075 if (strcmp(argv[i],"-printer") == 0)
2076 PO.po_cmd = argv[i+1];
2077 else if (strcmp(argv[i],"-file") == 0)
2078 PO.po_file = argv[i+1];
2079 else if (strcmp(argv[i],"-paper") == 0)
2080 PO.po_paper = argv[i+1];
2081 else if (strcmp(argv[i],"-orient") == 0)
2082 PO.po_orient = argv[i+1];
2083 else if (strcmp(argv[i],"-epsf") == 0)
2084 PO.po_epsf = argv[i+1];
2085 else if (strcmp(argv[i],"-duplex") == 0)
2086 PO.po_isDuplex = argv[i+1];
2087 else if (strcmp(argv[i],"-start") == 0)
2088 PO.po_start = argv[i+1];
2089 else if (strcmp(argv[i],"-end") == 0)
2090 PO.po_end = argv[i+1];
2091 else if (strcmp(argv[i],"-scalelength") == 0)
2092 PO.po_scaleLength = argv[i+1];
2093 }
2094
2095 GPrintOpt_tracePrint(&PO);
2096
2097 return TCL_OK;
2098 }
2099
2100 /*
2101 * Get trace range data. Returns a tripple of the form {sel_start sel_end trace_end}.
2102 */
gat_getTraceData(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2103 static int gat_getTraceData(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2104 {
2105 extern GScope *Scope;
2106 simtime_t start;
2107 simtime_t stop;
2108 simtime_t first = 0;
2109 int i;
2110 int did_first_set = 0;
2111 double timeCorrection;
2112
2113 if (!Scope) {
2114 Tcl_SetResult(tcl, "0 0 0 0 ns 0", TCL_STATIC);
2115 return TCL_OK;
2116 }
2117
2118 for (i = 0;i < Scope->NumTraces;i++) {
2119 GateValue *v;
2120 for (v = Scope->Traces[i]->t_first;v;v = v->v_next)
2121 if (v->v_code != VC_UNRECORDED)
2122 break;
2123 if (v && (v->v_time < first || !did_first_set)) {
2124 first = v->v_time;
2125 did_first_set = 1;
2126 }
2127 }
2128
2129
2130 if (Scope->mark_count == 2) {
2131 start = Scope->mark_val[0];
2132 stop = Scope->mark_val[1];
2133 } else {
2134 start = Scope->s_leftTime;
2135 stop = Scope->s_leftTime+Scope->s_range;
2136 }
2137
2138 if (start < first) start = first;
2139
2140 if (stop < start) { int x = start; start = stop; stop = x; }
2141
2142 start = imax(start,0);
2143 stop = imin(stop,Scope->s_time);
2144
2145 timeCorrection = TkGate.circuit->simulator.si_tsmult/(double)Scope->s_precision;
2146
2147 char res[128];
2148 sprintf(res,"%llu %llu %llu %lf %s %llu %llu",
2149 start,
2150 stop,
2151 Scope->s_range,
2152 timeCorrection,
2153 SimInterface_unitsToStr(TkGate.circuit->simulator.si_units),
2154 first,
2155 Scope->s_time);
2156 Tcl_SetResult(tcl, res, TCL_VOLATILE);
2157
2158 return TCL_OK;
2159 }
2160
gat_traceLPPEst(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2161 static int gat_traceLPPEst(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2162 {
2163 char paper[STRMAX];
2164 int i;
2165 const char *orient = "landscape";
2166 double lpp;
2167
2168 for (i = 1;i < argc;i+=2) {
2169 if (i+1 >= argc) break;
2170
2171 if (strcmp(argv[i],"-paper") == 0)
2172 sscanf(argv[i+1],"%s",paper);
2173 else if (strcmp(argv[i],"-orient") == 0)
2174 orient = argv[i+1];
2175 }
2176
2177 lpp = traceLinesPerPage(orient, paper);
2178 Tcl_SetObjResult(tcl, Tcl_NewDoubleObj(lpp));
2179
2180 return TCL_OK;
2181 }
2182
2183
gat_setCircProp(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2184 static int gat_setCircProp(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2185 {
2186 if (argc == 1) return TCL_OK;
2187
2188 ob_touch(TkGate.circuit);
2189 ob_touch(TkGate.circuit->initScripts);
2190
2191 if (strcmp(argv[1],"-clear") == 0) {
2192 int i;
2193
2194 for (i = 0;i < TkGate.circuit->numInitScripts;i++)
2195 ob_free(TkGate.circuit->initScripts[i]);
2196 if (TkGate.circuit->initScripts)
2197 ob_free(TkGate.circuit->initScripts);
2198 TkGate.circuit->numInitScripts = 0;
2199 TkGate.circuit->initScripts = 0;
2200
2201 } else if (strcmp(argv[1],"-script") == 0 && argc > 2) {
2202 if (TkGate.circuit->numInitScripts) {
2203 TkGate.circuit->initScripts = (char**) ob_realloc(TkGate.circuit->initScripts,sizeof(char*)*(TkGate.circuit->numInitScripts+1));
2204 } else
2205 TkGate.circuit->initScripts = (char**) ob_malloc(sizeof(char*),"char*");
2206 TkGate.circuit->initScripts[TkGate.circuit->numInitScripts++] = ob_strdup(argv[2]);
2207 } else if (strcmp(argv[1],"-vlib") == 0 && argc > 2) {
2208 } else if (strcmp(argv[1],"-top") == 0 && argc > 2) {
2209 GModuleDef *M = env_findModule(argv[2]);
2210 if (M)
2211 TkGate.circuit->root_mod = M;
2212 }
2213
2214 return TCL_OK;
2215 }
2216
gat_getCircProp(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2217 static int gat_getCircProp(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2218 {
2219 Tcl_ResetResult(tcl);
2220
2221 if (strcmp(argv[1],"-script") == 0 && argc > 2) {
2222 int i;
2223
2224 if (sscanf(argv[2],"%d",&i) != 1) return TCL_OK;
2225 if (i >= TkGate.circuit->numInitScripts) return TCL_OK;
2226 Tcl_SetResult(tcl, TkGate.circuit->initScripts[i], TCL_STATIC);
2227 }
2228
2229 return TCL_OK;
2230 }
2231
2232 /*****************************************************************************
2233 *
2234 * Get list of available locales
2235 *
2236 * Usage: gat_getLocales
2237 *
2238 * Returns a list of the form: {{English en} {Japanese ja} ... }
2239 *
2240 *****************************************************************************/
gat_getLocales(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2241 static int gat_getLocales(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2242 {
2243 int i;
2244 HashElem *he;
2245
2246 Tcl_ResetResult(tcl);
2247
2248 for (he = Hash_first(TkGate.localeTable), i = 0;he;he = Hash_next(TkGate.localeTable,he), i++) {
2249 char buf[STRMAX],buf2[STRMAX];
2250 Locale *l = (Locale*) HashElem_obj(he);
2251
2252 sprintf(buf,"\"%s\" %s",quoteChars(buf2,l->l_name,TCL_SPECIALCHARS),l->l_code);
2253 Tcl_AppendElement(tcl,buf);
2254 }
2255
2256 return TCL_OK;
2257 }
2258
2259 /*****************************************************************************
2260 *
2261 * Set the value of a dip switch in simulation mode.
2262 *
2263 *****************************************************************************/
gat_setDip(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2264 static int gat_setDip(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2265 {
2266 GCElement *g;
2267 GSimSwitch *ss;
2268 GSimModule *M;
2269
2270 if (argc != 3) return TCL_OK;
2271
2272 char res[128];
2273 if (SimInterface_lookupGate(&TkGate.circuit->simulator,argv[1],&M,&g,&ss) == 0) {
2274
2275 if (M == TkGate.circuit->es->smod) gate_draw(g,0);
2276
2277 ob_touch(g);
2278 if (sscanf(argv[2],"%x",&g->u.sw.dipval) != 1) {
2279 g->u.sw.dipval = 0;
2280 }
2281
2282 g->u.sw.dipval &= nmask(g->wires[DIP_OUT]->net->n_nbits);
2283
2284 if (M == TkGate.circuit->es->smod) gate_draw(g,0);
2285
2286 DoTcl("tkg_simNetSet %s %d'h%x",
2287 ss->name,
2288 g->wires[0]->net->n_nbits,
2289 g->u.sw.dipval);
2290
2291 sprintf(res,"%x",g->u.sw.dipval);
2292 } else {
2293 sprintf(res,"0");
2294 }
2295
2296 Tcl_SetResult(tcl, res, TCL_VOLATILE);
2297
2298
2299 return TCL_OK;
2300 }
2301
2302 /*****************************************************************************
2303 *
2304 * Tcl procedure to do a text search
2305 *
2306 * Tcl syntax:
2307 *
2308 * gat_find cmd [options]
2309 *
2310 * Commands are one of:
2311 * search Search for the next occurence of the target in the current context
2312 * list List all matches
2313 * goto Goto a specific match
2314 *
2315 *****************************************************************************/
gat_find(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2316 static int gat_find(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2317 {
2318 int mode = 0;
2319 int qualifier = 0;
2320 const char *target = 0;
2321 const char *command = 0;
2322 const char *variable = 0;
2323 int i;
2324
2325 if (argc < 2) return TCL_ERROR;
2326
2327 command = argv[1];
2328
2329 for (i = 2;i < argc;i++)
2330 if (strcmp(argv[i],"-type") == 0 && i+1 < argc)
2331 sscanf(argv[++i],"%d",&mode);
2332 else if (strcmp(argv[i],"-qualifier") == 0 && i+1 < argc)
2333 sscanf(argv[++i],"%d",&qualifier);
2334 else if (strcmp(argv[i],"-target") == 0 && i+1 < argc)
2335 target = argv[++i];
2336 else if (strcmp(argv[i],"-variable") == 0 && i+1 < argc)
2337 variable = argv[++i];
2338
2339 if (strcmp(command,"search") == 0) {
2340 if (!target) return TCL_OK;
2341 GSearchContext_find(TkGate.circuit->search,target,mode,qualifier);
2342 } else if (strcmp(command,"list") == 0) {
2343 if (!target || !variable) return TCL_OK;
2344 GSearchContext_list(TkGate.circuit->search,target,mode,qualifier,variable);
2345 } else if (strcmp(command,"goto") == 0) {
2346 if (argc > 2)
2347 GSearchContext_goto(argv[2]);
2348 }
2349
2350 return TCL_OK;
2351 }
2352
2353 /*****************************************************************************
2354 *
2355 * Format a time in epochs to use units (simulator must be active to use this)
2356 *
2357 * Tcl syntax:
2358 *
2359 * gat_formatTime <time>
2360 *
2361 *****************************************************************************/
gat_formatTime(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2362 static int gat_formatTime(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2363 {
2364 simtime_t t;
2365 SimInterface *si = &TkGate.circuit->simulator;
2366
2367 if (argc != 2) return TCL_ERROR;
2368 if (sscanf(argv[1],"%llu",&t) != 1) return TCL_ERROR;
2369
2370 if (tkgate_currentMode() == MM_SIMULATE)
2371 SimInterface_formatTime(si, (char *)Tcl_GetStringResult(tcl), t);
2372 else
2373 Tcl_SetObjResult(tcl, Tcl_NewLongObj(t));
2374
2375 return TCL_OK;
2376 }
2377
2378
gat_anchor(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2379 static int gat_anchor(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2380 {
2381 TkgGateWin *gw = TkGate.gw;
2382 EditState *es = gw->parms->circuit->es;
2383 int mode = 0;
2384 int old_mode;
2385
2386 if (GModuleDef_isDataProtected(TkGate.circuit->es->env)) {
2387 message(0,msgLookup("err.protdata"));
2388 return TCL_OK;
2389 }
2390
2391 if (TkGate.circuit->select)
2392 old_mode = TkGate.circuit->select->anchored;
2393 else if (TkGate.circuit->mg_selection)
2394 old_mode = TkGate.circuit->mg_selection->s_hasAnchored;
2395 else
2396 old_mode = 0;
2397
2398 Tcl_SetObjResult(tcl, Tcl_NewIntObj(old_mode));
2399
2400 if (argc > 1) {
2401 sscanf(argv[1],"%d",&mode);
2402 sel_anchor(es,mode);
2403 }
2404
2405 return TCL_OK;
2406 }
2407
gat_setcolors(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2408 static int gat_setcolors(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2409 {
2410 setGCcolors();
2411 FlagRedraw();
2412 if (tkgate_currentMode() == MM_SIMULATE)
2413 ReqScopeRedisplay();
2414
2415 return TCL_OK;
2416 }
2417
gat_scopeMotion(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2418 static int gat_scopeMotion(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2419 {
2420 int x = 0,y = 0,state = 0,n=1;
2421 int px =0,py = 0;
2422
2423 if (argc < 7) return TCL_OK;
2424
2425 sscanf(argv[1],"%d",&x);
2426 sscanf(argv[2],"%d",&y);
2427 sscanf(argv[3],"%d",&px);
2428 sscanf(argv[4],"%d",&py);
2429 sscanf(argv[5],"%d",&n);
2430 sscanf(argv[6],"%d",&state);
2431
2432 scopeButtonMotion(x,y,px,py,n,state);
2433
2434 return TCL_OK;
2435 }
2436
gat_scopeButton(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2437 static int gat_scopeButton(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2438 {
2439 int x = 0,y = 0,state = 0,n=1;
2440 int px =0,py = 0;
2441
2442 if (argc < 7) return TCL_OK;
2443
2444 sscanf(argv[1],"%d",&x);
2445 sscanf(argv[2],"%d",&y);
2446 sscanf(argv[3],"%d",&px);
2447 sscanf(argv[4],"%d",&py);
2448 sscanf(argv[5],"%d",&n);
2449 sscanf(argv[6],"%d",&state);
2450
2451 scopeButtonPress(x,y,px,py,n,state);
2452
2453 return TCL_OK;
2454 }
2455
gat_scopeRelease(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2456 static int gat_scopeRelease(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2457 {
2458 int x = 0,y = 0,state = 0,n=1;
2459 int px =0,py = 0;
2460
2461 if (argc < 7) return TCL_OK;
2462
2463 sscanf(argv[1],"%d",&x);
2464 sscanf(argv[2],"%d",&y);
2465 sscanf(argv[3],"%d",&px);
2466 sscanf(argv[4],"%d",&py);
2467 sscanf(argv[5],"%d",&n);
2468 sscanf(argv[6],"%d",&state);
2469
2470 scopeButtonRelease(x,y,px,py,n,state);
2471
2472 return TCL_OK;
2473 }
2474
2475 /*****************************************************************************
2476 *
2477 * Tcl procedure to change the zoom level.
2478 *
2479 * Tcl syntax:
2480 *
2481 * gat_zoom <zoom-change>
2482 *
2483 *****************************************************************************/
gat_zoom(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2484 static int gat_zoom(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2485 {
2486 int zoom = 0;
2487 int old_zf;
2488 int org_x, org_y;
2489
2490 if (argc < 2) return TCL_OK;
2491
2492 sscanf(argv[1],"%d",&zoom);
2493
2494 old_zf = TkGate.circuit->zoom_factor;
2495 zoom = TkGate.circuit->zoom_factor + zoom; /* The new zoom factor */
2496
2497 if (zoom < 1 || zoom > ZOOM_MAX || zoom == TkGate.circuit->zoom_factor)
2498 return TCL_OK;
2499
2500 ob_touch(TkGate.circuit);
2501 TkGate.circuit->zoom_factor = zoom;
2502 if (zoom == 1) {
2503 DoTcl("ToolBar::toolConfigure Zoom zoomout -state disabled");
2504 DoTcl("ToolBar::toolConfigure Zoom zoomin -state normal");
2505 } else if (zoom == ZOOM_MAX) {
2506 DoTcl("ToolBar::toolConfigure Zoom zoomout -state normal");
2507 DoTcl("ToolBar::toolConfigure Zoom zoomin -state disabled");
2508 } else {
2509 DoTcl("ToolBar::toolConfigure Zoom zoomout -state normal");
2510 DoTcl("ToolBar::toolConfigure Zoom zoomin -state normal");
2511 }
2512
2513 org_x = TkGate.circuit->org_x - (TkGate.width/old_zf/2 - TkGate.width/TkGate.circuit->zoom_factor/2);
2514 org_y = TkGate.circuit->org_y - (TkGate.height/old_zf/2 - TkGate.height/TkGate.circuit->zoom_factor/2);
2515
2516 #if 0
2517 printf("@zoom %dx%d old=(%d,%d) new=(%d,%d)\n",TkGate.width,TkGate.height,TkGate.circuit->org_x,TkGate.circuit->org_y,org_x,org_y);
2518 #endif
2519
2520 TkGate_setOrigin(org_x,org_y);
2521
2522
2523 if (TkGate.circuit->zoom_factor > 1) {
2524 XSetLineAttributes(TkGate.D,TkGate.moduleGC,TkGate.circuit->zoom_factor,LineSolid,CapButt,JoinMiter);
2525 XSetLineAttributes(TkGate.D,TkGate.instGC,TkGate.circuit->zoom_factor,LineSolid,CapButt,JoinMiter);
2526 } else {
2527 XSetLineAttributes(TkGate.D,TkGate.moduleGC,0,LineSolid,CapButt,JoinMiter);
2528 XSetLineAttributes(TkGate.D,TkGate.instGC,0,LineSolid,CapButt,JoinMiter);
2529 }
2530
2531 XSetFont(TkGate.D, TkGate.instGC, TkGate.textXF[zoom]->fid);
2532 XSetFont(TkGate.D, TkGate.moduleGC, TkGate.textXF[zoom]->fid);
2533 XSetFont(TkGate.D, TkGate.modportGC, TkGate.textXF[zoom]->fid);
2534 XSetFont(TkGate.D, TkGate.frameGC, TkGate.textXF[zoom]->fid);
2535 XSetFont(TkGate.D, GatePainterContext_gc(TkGate.commentContext),TkGate.textXF[zoom]->fid);
2536 XSetFont(TkGate.D, TkGate.hyperlinkGC, TkGate.textXF[zoom]->fid);
2537 XSetFont(TkGate.D, TkGate.wireGC, TkGate.stextXF[zoom]->fid);
2538 XSetFont(TkGate.D, TkGate.busGC, TkGate.stextXF[zoom]->fid);
2539 XSetFont(TkGate.D, TkGate.selWireGC, TkGate.stextbXF[zoom]->fid);
2540 XSetFont(TkGate.D, TkGate.selBusGC, TkGate.stextbXF[zoom]->fid);
2541 XSetFont(TkGate.D, TkGate.toolGC, TkGate.textXF[zoom]->fid);
2542 XSetFont(TkGate.D, TkGate.cpathGC, TkGate.textXF[zoom]->fid);
2543 if (TkGate.japaneseMode) {
2544 XSetFont(TkGate.D, TkGate.kanjiGC, TkGate.ktextXF[zoom]->fid);
2545 }
2546
2547 FlagRedraw();
2548
2549 return TCL_OK;
2550 }
2551
gat_align(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2552 static int gat_align(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2553 {
2554 TkgGateWin *gw = TkGate.gw;
2555 EditState *es = gw->parms->circuit->es;
2556 int x = 0;
2557
2558 if (argc < 2) return TCL_OK;
2559
2560 sscanf(argv[1],"%d",&x);
2561
2562 if (x)
2563 sel_alignHorz(es);
2564 else
2565 sel_alignVert(es);
2566
2567 return TCL_OK;
2568 }
2569
2570 /*****************************************************************************
2571 *
2572 * Set location for a popup menu
2573 *
2574 * Tcl Syntax:
2575 *
2576 * get_setpop x y
2577 *
2578 * Get ready to open a popup menu in the main edit window and return the type of
2579 * popup we should use based on the context.
2580 *
2581 *****************************************************************************/
gat_setpop(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2582 static int gat_setpop(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2583 {
2584 int x,y,cx,cy;
2585 GCElement *g = TkGate.circuit->select;
2586
2587 x = y = 0;
2588 if (argc > 1) sscanf(argv[1],"%d",&x);
2589 if (argc > 2) sscanf(argv[2],"%d",&y);
2590
2591 TkGate.popstate.g = g;
2592 TkGate.popstate.net = TkGate.circuit->nsel;
2593 TkGate.popstate.w = TkGate.circuit->wsel;
2594 TkGate.popstate.n = TkGate.circuit->wnsel;
2595 TkGate.popstate.wx = wtoc_x(x);
2596 TkGate.popstate.wy = wtoc_y(y);
2597 TkGate.popstate.x = wtoc_x(x/TkGate.circuit->zoom_factor);
2598 TkGate.popstate.y = wtoc_y(y/TkGate.circuit->zoom_factor);
2599
2600
2601 cx = TkGate.popstate.x;
2602 cy = TkGate.popstate.y;
2603
2604 /*
2605 * If we are in simulate mode, use one of the simulate popups
2606 */
2607 if (tkgate_currentMode() == MM_SIMULATE) {
2608 if (g && GCElement_isModule(g))
2609 Tcl_SetResult(tcl, "blksimu", TCL_STATIC);
2610 else if (TkGate.popstate.n)
2611 Tcl_SetResult(tcl, "wiresimu", TCL_STATIC);
2612 else
2613 Tcl_SetResult(tcl, "simu", TCL_STATIC);
2614 return TCL_OK;
2615 }
2616
2617 /*
2618 * If we are in analysis mode, use one of the analysis popups
2619 */
2620 if (tkgate_currentMode() == MM_ANALYZE) {
2621 if (g && GCElement_isModule(g))
2622 Tcl_SetResult(tcl, "blkanal", TCL_STATIC);
2623 else
2624 Tcl_SetResult(tcl, "anal", TCL_STATIC);
2625 return TCL_OK;
2626 }
2627
2628 /*
2629 * If we are on the edit interfaces screen, use an edit interfaces popup
2630 */
2631 if (TkGate.circuit->es->isInterface) {
2632 if (g && GCElement_getType(g) == GC_BLOCK) {
2633 if (block_hitPort(g,cx,cy))
2634 Tcl_SetResult(tcl, "intfblockport", TCL_STATIC);
2635 else if (block_edgehit(g,x,y))
2636 Tcl_SetResult(tcl, "intfblockedge", TCL_STATIC);
2637 else
2638 Tcl_SetResult(tcl, "intfblock", TCL_STATIC);
2639 } else if (g && GCElement_getType(g) == GC_SYMBLOCK) {
2640 Tcl_SetResult(tcl, "intfblock", TCL_STATIC);
2641 } else
2642 Tcl_SetResult(tcl, "intf", TCL_STATIC);
2643
2644 return TCL_OK;
2645 }
2646
2647
2648 if (EditState_getMode() != MODE_MOVE && EditState_getMode() != MODE_MOVESEL) {
2649 Tcl_SetResult(tcl, "notmove", TCL_STATIC);
2650 return TCL_OK;
2651 }
2652
2653 if (TkGate.circuit->mg_selection && !g)
2654 Tcl_SetResult(tcl, "multi", TCL_STATIC);
2655 else if (g) {
2656 int N = GCElement_numPads(g);
2657 int can_add = 0;
2658 int i;
2659
2660 for (i = 0;i < N;i++)
2661 if (GCElement_getPadCanAdd(g,i))
2662 can_add = 1;
2663
2664 if (g->typeinfo->code == GC_BLOCK) {
2665 if (block_hitPort(g,cx,cy))
2666 Tcl_SetResult(tcl, "blockport", TCL_STATIC);
2667 else if (block_edgehit(g,cx,cy))
2668 Tcl_SetResult(tcl, "blockedge", TCL_STATIC);
2669 else
2670 Tcl_SetResult(tcl, "block", TCL_STATIC);
2671 } else if (g->typeinfo->code == GC_SYMBLOCK) {
2672 Tcl_SetResult(tcl, "block", TCL_STATIC);
2673 } else if (g->typeinfo->code == GC_JOINT) {
2674 if (!g->wires[0] || !g->wires[1] || !g->wires[2] || !g->wires[3])
2675 Tcl_SetResult(tcl, "joint3", TCL_STATIC);
2676 else
2677 Tcl_SetResult(tcl, "joint4", TCL_STATIC);
2678 } else if (can_add)
2679 Tcl_SetResult(tcl, "MIgate", TCL_STATIC);
2680 else
2681 Tcl_SetResult(tcl, "gate", TCL_STATIC);
2682 } else if (TkGate.popstate.n) {
2683 char *labelCode = TkGate.popstate.n->isLabeled ? "L" : "";
2684 char *sizeCode = TkGate.popstate.n->showSize ? "S" : "";
2685
2686 if (TkGate.popstate.net && TkGate.popstate.net->n_nbits > 1)
2687 Tcl_AppendResult(tcl, "mbwire", labelCode, sizeCode, NULL);
2688 else
2689 Tcl_AppendResult(tcl, "wire", labelCode, NULL);
2690 }
2691 else
2692 Tcl_SetResult(tcl, "canv", TCL_STATIC);
2693
2694 /* ob_touch(TkGate.popstate); (popstate may need to be made undoable?) */
2695
2696 return TCL_OK;
2697 }
2698
2699 /*****************************************************************************
2700 *
2701 * Tcl procedure to set the tkgate major mode.
2702 *
2703 * Parameters:
2704 * _d Client data (unused)
2705 * tcl Tcl interpreter
2706 * argc Number of arguments
2707 * argv Vector of arguments
2708 *
2709 * Returns: Tcl status
2710 *
2711 * Tcl forms:
2712 *
2713 * gat_setMajorMode <mode>
2714 *
2715 *****************************************************************************/
gat_setMajorMode(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2716 static int gat_setMajorMode(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2717 {
2718 int target_mode;
2719 int has_plus = 0;
2720
2721 if (argc < 2) {
2722 Tcl_SetResult(tcl, "bad mode", TCL_STATIC);
2723 return TCL_ERROR;
2724 }
2725
2726 if (!TkGate.circuit || !TkGate.circuit->es) return TCL_OK;
2727
2728 if (strcmp(argv[1],"simulate") == 0) {
2729 target_mode = MM_SIMULATE;
2730 } else if (strcmp(argv[1],"+edit") == 0) {
2731 target_mode = MM_EDIT;
2732 has_plus = 1;
2733 } else if (strcmp(argv[1],"edit") == 0) {
2734 target_mode = MM_EDIT;
2735 } else if (strcmp(argv[1],"analyze") == 0) {
2736 target_mode = MM_ANALYZE;
2737 } else {
2738 Tcl_SetResult(tcl, "bad mode", TCL_STATIC);
2739 return TCL_ERROR;
2740 }
2741
2742
2743 /*
2744 * If we are in normal edit mode, do an HDL save with checks before changing modes.
2745 */
2746 #if 0
2747 if (tkgate_currentMode() == MM_EDIT && target_mode != MM_EDIT
2748 && !TkGate.circuit->es->isInterface && hdl_checkSave(0) < 0)
2749 return TCL_OK;
2750 #endif
2751
2752 tkgate_setMajorMode(target_mode);
2753 if (has_plus && TkGate.circuit->es->isInterface) {
2754 modint_close();
2755 }
2756
2757 return TCL_OK;
2758 }
2759
2760 /*****************************************************************************
2761 *
2762 * Tcl procedure to get the tkgate major mode.
2763 *
2764 * Parameters:
2765 * _d Client data (unused)
2766 * tcl Tcl interpreter
2767 * argc Number of arguments
2768 * argv Vector of arguments
2769 *
2770 * Returns: Tcl status
2771 *
2772 * Tcl forms:
2773 *
2774 * gat_getMajorMode
2775 *
2776 * Tcl Return: name of the major mode
2777 *
2778 *****************************************************************************/
gat_getMajorMode(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2779 static int gat_getMajorMode(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2780 {
2781 if (argc != 1) {
2782 Tcl_SetResult(tcl, "illegal argument.", TCL_STATIC);
2783 return TCL_ERROR;
2784 }
2785
2786 if (!TkGate.circuit || !TkGate.circuit->es) return TCL_OK;
2787
2788 switch (tkgate_currentMode()) {
2789 case MM_SIMULATE :
2790 Tcl_SetResult(tcl, "simulate", TCL_STATIC);
2791 break;
2792 case MM_EDIT :
2793 if (editstate_isInterfaceMode())
2794 Tcl_SetResult(tcl, "interface", TCL_STATIC);
2795 else
2796 Tcl_SetResult(tcl, "edit", TCL_STATIC);
2797 break;
2798 case MM_ANALYZE :
2799 Tcl_SetResult(tcl, "analyze", TCL_STATIC);
2800 break;
2801 }
2802 return TCL_OK;
2803 }
2804
gat_gotoCPathNet(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2805 static int gat_gotoCPathNet(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2806 {
2807 const char *p;
2808 GNet *n;
2809 int x,y;
2810 GWireNode *wn1,*wn2;
2811
2812 if (argc < 2) {
2813 Tcl_SetResult(tcl, "bad cpath", TCL_STATIC);
2814 return TCL_ERROR;
2815 }
2816
2817 Error_navigateToModule(&TkGate.circuit->es,argv[1]);
2818 editstate_setCurrent(TkGate.circuit->es);
2819 FlagRedraw();
2820
2821 p = strrchr (argv[1],'.');
2822 if (p)
2823 p++;
2824 else
2825 p = argv[1];
2826
2827 n = GModuleDef_findNet(TkGate.circuit->es->env,p);
2828 if (!n) {
2829 Tcl_AppendResult(tcl, "net '", p, "' not found.", NULL);
2830 return TCL_ERROR;
2831 }
2832
2833 wn1 = n->n_driver->nodes;
2834 wn2 = wn1->out ? wn1->out : wn1->in;
2835 x = (wn1->x + wn2->x)/2;
2836 y = (wn1->y + wn2->y)/2;
2837
2838 TkGate_setOrigin(TkGate.width/2 - x,TkGate.height/2 - y);
2839 ob_touch(TkGate.circuit->es);
2840 editstate_saveOrig(TkGate.circuit->es);
2841 SetErrorPosition(x,y);
2842
2843 return TCL_OK;
2844 }
2845
2846 /*****************************************************************************
2847 *
2848 * Handle commands changeing properties of a port on a block edge, or add a
2849 * port to a block edge.
2850 *
2851 * Usage: gat_popupPortCmd command [arg]
2852 *
2853 * Command List:
2854 * add-in Add an input port
2855 * add-out Add an output port
2856 * add-inout Add an inout port
2857 * change-in Change port type to input
2858 * change-out Change port type to output
2859 * change-inout Change port type to inout
2860 * delete Delete a port
2861 * size n Set bit size
2862 *
2863 *****************************************************************************/
gat_popupPortCmd(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2864 static int gat_popupPortCmd(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2865 {
2866 TkgGateWin *gw = TkGate.gw;
2867 EditState *es = gw->parms->circuit->es;
2868 GWire *w = 0;
2869
2870 if (argc < 2) {
2871 Tcl_SetResult(tcl, "bad popup", TCL_STATIC);
2872 return TCL_ERROR;
2873 }
2874
2875 #if TOUCH_XGATE_ED
2876 ob_touch(TkGate.ed);
2877 #endif
2878 TkGate.ed->tx = TkGate.popstate.x;
2879 TkGate.ed->ty = TkGate.popstate.y;
2880
2881 /*
2882 * These commands are not applied to an existing port
2883 */
2884 if (strncmp(argv[1],"add-",4) == 0) {
2885 int iotype = strIOType(argv[1]+4);
2886 if (iotype >= 0)
2887 block_newport(es,iotype);
2888 return TCL_OK;
2889 }
2890
2891 /*
2892 * All other command must be applied to a port. Go try to find it.
2893 */
2894 if (TkGate.circuit->select && TkGate.circuit->select->typeinfo->code == GC_BLOCK)
2895 w = block_hitPort(TkGate.circuit->select,TkGate.ed->tx,TkGate.ed->ty);
2896
2897 /*
2898 * Do nothing if we could not find a port (popup menu context testing should
2899 * prevent this from happening.
2900 */
2901 if (!w)
2902 return TCL_OK;
2903
2904
2905 if (strcmp(argv[1],"change-in") == 0) {
2906 block_setdir(w->nodes,es,IN);
2907 } else if (strcmp(argv[1],"change-out") == 0) {
2908 block_setdir(w->nodes,es,OUT);
2909 } else if (strcmp(argv[1],"change-inout") == 0) {
2910 block_setdir(w->nodes,es,TRI);
2911 } else if (strcmp(argv[1],"change") == 0) {
2912 block_changedir(w->nodes,es);
2913 } else if (strcmp(argv[1],"size") == 0) {
2914 int size;
2915 if (argc < 3 || sscanf(argv[2],"%d",&size) != 1) {
2916 Tcl_SetResult(tcl, "bad port size", TCL_STATIC);
2917 return TCL_ERROR;
2918 }
2919 GNet_draw(w->net);
2920 net_setSize(w->net,size);
2921 GNet_draw(w->net);
2922 SetModified(MF_INTERFACE);
2923 SynchronizeInterface();
2924 } else if (strcmp(argv[1],"delete") == 0) {
2925 if (w->gate && (w->gate->typeinfo->code == GC_BLOCK)) {
2926 SetModified(MF_NET);
2927 net_unselect(1);
2928 wire_cut(w->nodes->x,w->nodes->y,w->nodes, es->env);
2929 ob_touch(TkGate.circuit);
2930 TkGate.circuit->wsel = NULL;
2931 TkGate.circuit->wnsel = NULL;
2932 }
2933 SetModified(MF_INTERFACE);
2934 SynchronizeInterface();
2935 } else {
2936 Tcl_SetResult(tcl, "illegal port command.", TCL_STATIC);
2937 return TCL_ERROR;
2938 }
2939
2940 return TCL_OK;
2941 }
2942
gat_popupSetState(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2943 static int gat_popupSetState(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2944 {
2945 if (argc > 1)
2946 sscanf(argv[1],"%d",&TkGate.popstate.isSet);
2947 else
2948 Tcl_SetObjResult(tcl, Tcl_NewIntObj(TkGate.popstate.isSet));
2949
2950 return TCL_OK;
2951 }
2952
gat_popupWireProps(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2953 static int gat_popupWireProps(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2954 {
2955 GNet *net;
2956
2957 net = TkGate.popstate.w->net;
2958 if (net) {
2959 #if TOUCH_XGATE_ED
2960 ob_touch(TkGate.ed);
2961 #endif
2962 TkGate.ed->tx = TkGate.popstate.wx;
2963 TkGate.ed->ty = TkGate.popstate.wy;
2964 net_editProps(net,TkGate.ed->tx,TkGate.ed->ty);
2965 }
2966
2967 return TCL_OK;
2968 }
2969
gat_popupWireAddStub(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2970 static int gat_popupWireAddStub(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2971 {
2972 TkgGateWin *gw = TkGate.gw;
2973 EditState *es = gw->parms->circuit->es;
2974
2975 if (TkGate.popstate.g) {
2976 if (TkGate.popstate.g->typeinfo->code == GC_JOINT)
2977 joint_addstub(TkGate.popstate.g,es);
2978 } else
2979 wire_addstub(es,TkGate.popstate.x,TkGate.popstate.y);
2980
2981 return TCL_OK;
2982 }
2983
2984 /*****************************************************************************
2985 *
2986 * Hide or show the bit size on a wire segment
2987 *
2988 *****************************************************************************/
gat_popupWireSize(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])2989 static int gat_popupWireSize(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
2990 {
2991 if (TkGate.popstate.n && TkGate.popstate.w) {
2992 GWireNode *n = TkGate.popstate.n;
2993 GWire *w = TkGate.popstate.w;
2994
2995 GWire_draw(w);
2996 ob_touch(n);
2997 n->showSize = !n->showSize;
2998 GWire_draw(w);
2999 }
3000
3001
3002 return TCL_OK;
3003 }
3004
3005 /*****************************************************************************
3006 *
3007 * Hide or show the label on a wire segment
3008 *
3009 * Usage:
3010 * gat_popupWireLabel Toggle label
3011 * gat_popupWireLabel -show Show label
3012 * gat_popupWireLabel -hide Hide This Label
3013 * gat_popupWireLabel -hideall Hide All Labels
3014 * gat_popupWireLabel -clearall Remove all labels
3015 *
3016 *****************************************************************************/
gat_popupWireLabel(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3017 static int gat_popupWireLabel(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3018 {
3019 GWireNode *n = TkGate.popstate.n;
3020 GWire *w = TkGate.popstate.w;
3021 GNet *net = TkGate.popstate.net;
3022 int y = TkGate.ed->ty;
3023 int x = TkGate.ed->tx;
3024 int isLabeled;
3025
3026 if (!net || !n || !w)
3027 return TCL_OK;
3028
3029 isLabeled = n->isLabeled;
3030
3031 if (argc > 1) {
3032 if (strcmp(argv[1],"-hideall") == 0) {
3033 GNet_draw(net);
3034 GNet_hideName(net);
3035 GNet_draw(net);
3036 return TCL_OK;
3037 } else if (strcmp(argv[1],"-clearall") == 0) {
3038 GWire *wlist[GNet_numWires(net)];
3039 int count = GNet_getWires(net,wlist,GW_DRIVER);
3040 int i;
3041
3042 GNet_draw(net);
3043 GNet_hideName(net);
3044 for (i = 0;i < count;i++) {
3045 for (n = wlist[i]->nodes;n;n = n->out) {
3046 if (n->isLabeled) {
3047 ob_touch(n);
3048 n->isLabeled = 0;
3049 }
3050 }
3051 }
3052 GNet_draw(net);
3053 return TCL_OK;
3054 } else if (strcmp(argv[1],"-show") == 0)
3055 isLabeled = 1;
3056 else if (strcmp(argv[1],"-hide") == 0)
3057 isLabeled = 0;
3058 else
3059 isLabeled = !isLabeled;
3060 }
3061
3062 GNet_draw(net);
3063 ob_touch(n);
3064
3065 n->isLabeled = isLabeled;
3066 if (n->isLabeled && n->out) {
3067 int offset = 50;
3068
3069 if (n->y != n->out->y) {
3070 offset = 100*(y - n->y)/(n->out->y - n->y);
3071 } else if (n->x != n->out->x) {
3072 offset = 100*(x - n->x)/(n->out->x - n->x);
3073 }
3074 n->offset = offset;
3075
3076 GNet_showName(net);
3077 }
3078 GNet_draw(net);
3079
3080 return TCL_OK;
3081 }
3082
3083
gat_dumpWires(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3084 static int gat_dumpWires(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3085 {
3086 TkgGateWin *gw = TkGate.gw;
3087 EditState *es = gw->parms->circuit->es;
3088
3089 wire_dump(es);
3090
3091 return TCL_OK;
3092 }
3093
gat_getTechList(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3094 static int gat_getTechList(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3095 {
3096 char **techs = GDelayDef_getTechList();
3097 int l,i;
3098
3099 if (!techs) {
3100 Tcl_SetResult(tcl, TKGATE_DEFAULT_TECH, TCL_STATIC);
3101 return TCL_OK;
3102 }
3103
3104 l = 0;
3105 for (i = 0;techs[i];i++)
3106 l += strlen(techs[i])+1;
3107 l++;
3108
3109 for (i = 0;techs[i];i++)
3110 Tcl_AppendResult(tcl, " ", techs[i], NULL);
3111
3112 return TCL_OK;
3113 }
3114
3115 /*
3116 Set the technology for all selected gates.
3117 */
gat_setTech(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3118 static int gat_setTech(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3119 {
3120 TkgGateWin *gw = TkGate.gw;
3121 EditState *es = gw->parms->circuit->es;
3122
3123 if (GModuleDef_isDataProtected(TkGate.circuit->es->env)) {
3124 message(0,msgLookup("err.protdata")); /* "Can not edit library module." */
3125 return TCL_OK;
3126 }
3127
3128 if (argc > 1) {
3129 ob_begin_frame("SetTech");
3130 sel_setTech(es,argv[1]);
3131 ob_end_frame();
3132 }
3133
3134 return TCL_OK;
3135 }
3136
3137 /*
3138 Get the technology of the selected gate
3139 */
gat_getTech(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3140 static int gat_getTech(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3141 {
3142 char *tech = 0;
3143
3144 if (TkGate.circuit->select) {
3145 tech = TkGate.circuit->select->tech;
3146 } else if (TkGate.circuit->mg_selection) {
3147 HashElem *E;
3148 char *s_tech = 0;
3149
3150 for (E = Hash_first(TkGate.circuit->mg_selection->s_gates);E;E = Hash_next(TkGate.circuit->mg_selection->s_gates,E)) {
3151 GCElement *g = (GCElement*) HashElem_obj(E);
3152 s_tech = g->tech ? g->tech : "";
3153 if (!tech)
3154 tech = s_tech;
3155 else {
3156 if (strcmp(tech,s_tech) != 0) {
3157 tech = "";
3158 break;
3159 }
3160 }
3161 }
3162 }
3163
3164 if (!tech) tech = "";
3165 Tcl_SetResult(tcl, tech, TCL_STATIC);
3166
3167 return TCL_OK;
3168 }
3169
gat_makeMakeMenu(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3170 static int gat_makeMakeMenu(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3171 {
3172 if (argc != 2) {
3173 Tcl_SetResult(tcl, "bad make menu", TCL_STATIC);
3174 return TCL_ERROR;
3175 }
3176
3177 makeMakeMenu(argv[1]);
3178
3179 return TCL_OK;
3180 }
3181
3182 /*****************************************************************************
3183 *
3184 * Validate the suggested name of a port.
3185 *
3186 * gat_validatePortName module name orient dir nbits
3187 * gat_validatePortName module name orient dir nbits
3188 *
3189 *
3190 *****************************************************************************/
3191 int igen_strToSide(const char *side);
3192 void guessPortName(char *buf,GCElement *g,int orient,int dir,int nbits);
gat_validatePortName(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3193 static int gat_validatePortName(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3194 {
3195 /**
3196 * @TODO to remove
3197 */
3198 /*
3199 TkgGateWin *gw = TkGate.gw;
3200 EditState **es = &gw->parms->circuit->es;
3201 */
3202 GModuleDef *m = 0;
3203 const char *modName = 0;
3204 const char *oldPortName = 0;
3205 const char *newPortName = 0;
3206 char validName[STRMAX];
3207 SHash *curPorts = 0;
3208 int orient = 0;
3209 int dir = 0;
3210 int nbits = 0;
3211 const char *s;
3212
3213 if (argc < 3) {
3214 Tcl_SetResult(tcl, "wrong number of parameters.", TCL_STATIC);
3215 return TCL_ERROR;
3216 }
3217
3218 modName = argv[1];
3219 newPortName = argv[2];
3220 oldPortName = seekOption("-old",argv+3,argc-3);
3221
3222 if ((s = seekOption("-dir",argv+3,argc-3))) {
3223 dir = strIOType(s);
3224 }
3225
3226 if ((s = seekOption("-bits",argv+3,argc-3)))
3227 sscanf(s,"%d",&nbits);
3228
3229 if ((s = seekOption("-orient",argv+3,argc-3))) {
3230 orient = igen_strToSide(s);
3231 }
3232
3233 if (*modName)
3234 m = env_findModule(modName);
3235
3236 if (m && m->m_interface) {
3237 GCElement *g = m->m_interface;
3238
3239 if (g) {
3240 if (GCElement_getType(g) == GC_BLOCK) {
3241 int N = GCElement_numPads(g);
3242 GWire *w;
3243 int i;
3244
3245 curPorts = new_SHash_noob();
3246 for (i = 0;i < N;i++) {
3247 for (w = g->wires[i];w;w = w->next) {
3248 if (!oldPortName || strcmp(w->name,oldPortName) != 0) {
3249 SHash_insert(curPorts,w->name,w);
3250 }
3251 }
3252 }
3253 } else if (GCElement_getType(g) == GC_SYMBLOCK) {
3254 int N = GCElement_numPads(g);
3255 GWire *w;
3256 int i;
3257
3258 curPorts = new_SHash_noob();
3259 for (i = 0;i < N;i++) {
3260 for (w = g->wires[i];w;w = w->next) {
3261 if (!oldPortName || strcmp(w->name,oldPortName) != 0) {
3262 SHash_insert(curPorts,w->name,w);
3263 }
3264 }
3265 }
3266 }
3267 if (strcmp(newPortName,DEFAULT_PORT_NAME) == 0 || !*newPortName) {
3268 guessPortName(validName,g,orient,dir,nbits);
3269 newPortName = validName;
3270 }
3271 }
3272 }
3273
3274 pickValidName(validName,newPortName,"P",curPorts);
3275
3276 Tcl_SetResult(tcl, validName, TCL_VOLATILE);
3277
3278 if (curPorts)
3279 delete_SHash(curPorts);
3280
3281 return TCL_OK;
3282 }
3283
3284
gat_makeMakeShortcuts(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3285 static int gat_makeMakeShortcuts(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3286 {
3287 makeMakeShortcuts();
3288 return TCL_OK;
3289 }
3290
gat_showPath(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3291 static int gat_showPath(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3292 {
3293 cpath_show(argc-1,argv+1);
3294 FlagRedraw();
3295 return TCL_OK;
3296 }
3297
gat_clearPath(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3298 static int gat_clearPath(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3299 {
3300 cpath_clear();
3301 cpath_flush();
3302 FlagRedraw();
3303 return TCL_OK;
3304 }
3305
gat_cpathFlash(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3306 static int gat_cpathFlash(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3307 {
3308 cpath_flash();
3309 return TCL_OK;
3310 }
3311
gat_refreshScreen(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3312 static int gat_refreshScreen(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3313 {
3314 FlagRedraw();
3315 return TCL_OK;
3316 }
3317
3318
3319 /*
3320 * Verify that internal data structures are correct.
3321 */
gat_verify(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3322 static int gat_verify(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3323 {
3324 verify_circuit();
3325 return TCL_OK;
3326 }
3327
3328 /*
3329 * Toggle the existence of a probe on the selected net.
3330 */
gat_toggleProbe(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3331 static int gat_toggleProbe(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3332 {
3333 char buf[STRMAX];
3334 char *netName = 0;
3335 SimInterface *si = &TkGate.circuit->simulator;
3336 GSimModule *SM;
3337 GWire *w;
3338 GNet *net;
3339 int x,y;
3340
3341 if (tkgate_currentMode() != MM_SIMULATE)
3342 return TCL_OK;
3343
3344 if (argc > 1) {
3345 GSimModule_getPathPrefix(TkGate.circuit->es->smod,buf);
3346 strcat(buf,argv[1]);
3347 netName = buf;
3348 } else if (TkGate.circuit->nsel) {
3349 GSimModule_getNetPathName(TkGate.circuit->es->smod,TkGate.circuit->nsel,buf);
3350 netName = buf;
3351 }
3352
3353 if (!netName) {
3354 return TCL_OK;
3355 }
3356
3357 if (SimInterface_lookupWire(si,netName,&SM,&w,&net) == 0) {
3358 if (w) {
3359 x = w->nodes->x;
3360 y = w->nodes->y;
3361 if (TkGate.popstate.isSet) {
3362 x = TkGate.popstate.x;
3363 y = TkGate.popstate.y;
3364 GWire_pickProbePosition(TkGate.popstate.w,&x,&y);
3365 }
3366 SimInterface_addDelProbe(si,TkGate.circuit->es->smod,buf,w,w->nodes,x,y);
3367 } else {
3368 SimInterface_addDelHDLProbe(si,TkGate.circuit->es->smod,buf,net);
3369 }
3370 } else
3371 message(0,msgLookup("err.sim.nonet"),netName);
3372
3373 return TCL_OK;
3374 }
3375
gat_delScopeProbe(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3376 static int gat_delScopeProbe(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3377 {
3378 extern GScope *Scope;
3379 GScope_deleteSelectedTrace(Scope);
3380 return TCL_OK;
3381 }
3382
3383 /*
3384 * Undo the last edit
3385 */
gat_undo(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3386 static int gat_undo(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3387 {
3388 int n = 1;
3389
3390 if (argc > 1)
3391 sscanf(argv[1],"%d",&n);
3392
3393 ob_undo(n);
3394 FlagRedraw();
3395 return TCL_OK;
3396 }
3397
3398 /*
3399 * Redo the last undone edit
3400 */
gat_redo(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3401 static int gat_redo(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3402 {
3403 int n = 1;
3404
3405 if (argc > 1)
3406 sscanf(argv[1],"%d",&n);
3407
3408 ob_redo(n);
3409 FlagRedraw();
3410 return TCL_OK;
3411 }
3412
gat_obBeginFrame(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3413 static int gat_obBeginFrame(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3414 {
3415 unsigned flags = 0;
3416
3417 if (ob_get_mode() == OM_DISABLED) {
3418 Tcl_SetResult(tcl, "0", TCL_STATIC);
3419 return TCL_OK;
3420 }
3421
3422 if (argc < 2) {
3423 abort();
3424 return TCL_OK;
3425 }
3426
3427 if (argc > 2)
3428 sscanf(argv[2],"%u",&flags);
3429
3430 if (strcmp(argv[1],"-") == 0)
3431 ob_begin_framef(0,flags);
3432 else
3433 ob_begin_framef(argv[1],flags);
3434
3435 Tcl_SetResult(tcl, "1", TCL_STATIC);
3436
3437 return TCL_OK;
3438 }
3439
gat_obAppendFrame(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3440 static int gat_obAppendFrame(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3441 {
3442 if (argc != 2) return TCL_OK;
3443 if (strcmp(argv[1],"-") == 0)
3444 ob_append_frame(0);
3445 else
3446 ob_append_frame(argv[1]);
3447 return TCL_OK;
3448 }
3449
gat_obEndFrame(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3450 static int gat_obEndFrame(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3451 {
3452 ob_end_frame();
3453 return TCL_OK;
3454 }
3455
gat_getUndoList(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3456 static int gat_getUndoList(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3457 {
3458 const char *undoList[1024];
3459 int N,i;
3460
3461 N = ob_getUndoList(undoList,1024);
3462
3463 for (i = 0;i < N;i++)
3464 Tcl_AppendResult(tcl, " ", undoList[i], NULL);
3465
3466 return TCL_OK;
3467 }
3468
gat_getRedoList(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3469 static int gat_getRedoList(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3470 {
3471 const char *redoList[1024];
3472 int N,i;
3473
3474 N = ob_getRedoList(redoList,1024);
3475
3476 for (i = 0;i < N;i++)
3477 Tcl_AppendResult(tcl, " ", redoList[i], NULL);
3478
3479 return TCL_OK;
3480 }
3481
3482 /*****************************************************************************
3483 *
3484 * Return the current selection in the edit window.
3485 *
3486 * Parameters:
3487 * _d Client data (unused)
3488 * tcl Tcl interpreter
3489 * argc Number of arguments
3490 * argv Vector of arguments
3491 *
3492 * Returns: Tcl status
3493 *
3494 * Tcl syntax:
3495 *
3496 * gat_getSelected gates Returns list of all selected element names
3497 *
3498 * gat_getSelected module Returns the selected module name if it is the only selection.
3499 *
3500 * gat_getSelected Same as "gates" option
3501 *
3502 *****************************************************************************/
gat_getSelected(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3503 static int gat_getSelected(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3504 {
3505 HashElem *E;
3506 GSelection *gs = TkGate.circuit->mg_selection;
3507 const char *what = "gates";
3508
3509 if (argc > 1) what = argv[1];
3510
3511 if (strcmp(what,"gates") == 0) {
3512 /*
3513 * WARNING: This function may not work correctly if there are a lot of gates
3514 * selected since the tcl->result buffer is not expanded as necessary. However,
3515 * this features is not currently used, so it should not matter for now.
3516 */
3517 for (E = Hash_first(gs->s_gates);E;E = Hash_next(gs->s_gates,E)) {
3518 GCElement *g = (GCElement*) HashElem_obj(E);
3519 Tcl_AppendResult(tcl, " ", g->ename, NULL);
3520 }
3521 } else {
3522 if (sel_num(TkGate.circuit->es) == 1) {
3523 GCElement *g = TkGate.circuit->select;
3524
3525 if (g && GCElement_isModule(g)) {
3526 Tcl_SetResult(tcl, g->u.block.moduleName, TCL_VOLATILE);
3527 }
3528 }
3529 }
3530
3531 return TCL_OK;
3532 }
3533
gat_obMode(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3534 static int gat_obMode(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3535 {
3536 ob_OMMode_t m = OM_ENABLED;
3537
3538 if (argc == 1) {
3539 m = ob_get_mode();
3540 Tcl_SetObjResult(tcl, Tcl_NewIntObj(m));
3541 } else {
3542 sscanf(argv[1],"%d",(int*)&m);
3543 ob_set_mode(m);
3544 }
3545
3546 return TCL_OK;
3547 }
3548
gat_obFlush(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3549 static int gat_obFlush(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3550 {
3551 ob_clear();
3552 return TCL_OK;
3553 }
3554
gat_obUnstick(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3555 static int gat_obUnstick(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3556 {
3557 ob_unstick();
3558 return TCL_OK;
3559 }
3560
gat_setShowXHairState(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3561 static int gat_setShowXHairState(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3562 {
3563 int n;
3564
3565 assert(argc == 2);
3566 sscanf(argv[1],"%d",&n);
3567
3568 GScope_setShowXHairState(n);
3569
3570 return TCL_OK;
3571 }
3572
3573 /*****************************************************************************
3574 *
3575 * Called at the end of an editing action to cause internal circuit data to
3576 * be resynchronized with tcl interface data.
3577 *
3578 *****************************************************************************/
gat_syncInterface(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3579 static int gat_syncInterface(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3580 {
3581 SynchronizeInterface();
3582 return TCL_OK;
3583 }
3584
gat_modintCenter(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3585 static int gat_modintCenter(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3586 {
3587 modint_center();
3588 return TCL_OK;
3589 }
3590
3591
3592 static int bit_width = 0;
3593 static int bit_height = 0;
3594 static unsigned **bit_data = 0;
3595
3596 /*
3597 * Basic word size/byte size declarations.
3598 */
3599 #define SSWORDSIZE TKGATE_WORDSIZE /* # bits in an unsigned */
3600 #define SSWORDMASK ((unsigned)~0) /* Word with all bits set */
3601 #if (SSWORDSIZE == 32)
3602 #define SSBITMASK 0x1f /* Mask to get bit in word */
3603 #define SSWORDSHIFT 5 /* Shift to get word index */
3604 #define SSWORDBYTES 4 /* Number of bytes per word */
3605 #define SSHALFWORDMASK 0xffff /* Mask for a half word */
3606 #elif (SSWORDSIZE == 64)
3607 #define SSBITMASK 0x3f /* Mask to get bit in word */
3608 #define SSWORDSHIFT 6 /* Shift to get word index */
3609 #define SSWORDBYTES 8 /* Number of bytes per word */
3610 #define SSHALFWORDMASK 0xffffffff /* Mask for a half word */
3611 #else
3612 #error Unsupported word size.
3613 #endif
3614
Bit_extend(int x,int y)3615 static void Bit_extend(int x,int y)
3616 {
3617 x++; y++;
3618
3619 if (x > bit_width) {
3620 int i;
3621
3622 bit_width = x;
3623 for (i = 0;i < bit_height;i++)
3624 bit_data[i] = ob_realloc(bit_data[i],bit_width*sizeof(unsigned));
3625 }
3626
3627 if (y > bit_height) {
3628 int i;
3629
3630 if (bit_data)
3631 bit_data = ob_realloc(bit_data,y*sizeof(unsigned*));
3632 else
3633 bit_data = ob_malloc(y*sizeof(unsigned*),"unsigned*");
3634
3635 for (i = bit_height;i < y;i++)
3636 bit_data[i] = ob_malloc(bit_width*sizeof(unsigned),"unsigned");
3637 bit_height = y;
3638 }
3639 }
3640
3641 /*****************************************************************************
3642 *
3643 * Get bit data from bit buffer
3644 *
3645 * set data [gat_getBit x y]
3646 *
3647 *****************************************************************************/
gat_getBit(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3648 static int gat_getBit(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3649 {
3650 int x,y;
3651
3652 sscanf(argv[1],"%d",&x);
3653 sscanf(argv[2],"%d",&y);
3654
3655 Bit_extend(x,y);
3656
3657 if ((bit_data[y][(x>>SSWORDSHIFT)] & (1 << (x & SSBITMASK))))
3658 Tcl_SetResult(tcl,"1",TCL_STATIC);
3659 else
3660 Tcl_SetResult(tcl,"0",TCL_STATIC);
3661
3662 return TCL_OK;
3663 }
3664
3665 /*****************************************************************************
3666 *
3667 * Set bit data in bit buffer
3668 *
3669 * gat_setBit x y d
3670 *
3671 *****************************************************************************/
gat_setBit(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3672 static int gat_setBit(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3673 {
3674 int x,y,d;
3675
3676 sscanf(argv[1],"%d",&x);
3677 sscanf(argv[2],"%d",&y);
3678 sscanf(argv[3],"%d",&d);
3679
3680 Bit_extend(x,y);
3681
3682 if (d)
3683 bit_data[y][(x>>SSWORDSHIFT)] |= (1 << (x & SSBITMASK));
3684 else
3685 bit_data[y][(x>>SSWORDSHIFT)] &= ~(1 << (x & SSBITMASK));
3686
3687 return TCL_OK;
3688 }
3689
3690 /*****************************************************************************
3691 *
3692 * Exit tkgate
3693 *
3694 *****************************************************************************/
gat_exit(ClientData _d,Tcl_Interp * tcl,int argc,const char * argv[])3695 static int gat_exit(ClientData _d,Tcl_Interp *tcl,int argc,const char *argv[])
3696 {
3697 extern int exit_flag;
3698
3699 exit_flag = 1;
3700
3701 DoTcl("exit");
3702 return TCL_OK;
3703 }
3704
3705
3706 /*****************************************************************************
3707 *
3708 * Table of command names and handler functions for tkgate.
3709 *
3710 *****************************************************************************/
3711 static Tkg_Command tkg_procTable[] = {
3712 {"gat_addPort", gat_addPort},
3713 {"gat_align", gat_align},
3714 {"gat_analyzerCommand", gat_analyzerCommand},
3715 {"gat_anchor", gat_anchor},
3716 {"gat_batInc", gat_batInc},
3717 {"gat_breakpoint", gat_breakpoint},
3718 {"gat_changeNet", gat_changeNet},
3719 {"gat_changePinDir", gat_changePinDir},
3720 {"gat_claimBlock", gat_claimBlock},
3721 {"gat_cleanUp", gat_cleanUp},
3722 {"gat_clearPath", gat_clearPath},
3723 {"gat_closeBox", gat_closeBox},
3724 {"gat_computestrhash", gat_computestrhash},
3725 {"gat_copyBlock", gat_copyBlock},
3726 {"gat_copyToBuf", gat_copyToBuf},
3727 {"gat_cpathFlash", gat_cpathFlash},
3728 {"gat_cutToBuf", gat_cutToBuf},
3729 {"gat_cutToBufAppend", gat_cutToBufAppend},
3730 {"gat_debug", gat_debug},
3731 {"gat_delScopeProbe", gat_delScopeProbe},
3732 {"gat_deleteBlock", gat_deleteBlock},
3733 {"gat_deleteSelected", gat_deleteSelected},
3734 {"gat_dohyperlink", gat_dohyperlink},
3735 {"gat_dumpWires", gat_dumpWires},
3736 {"gat_editBlockDesc", gat_editBlockDesc},
3737 {"gat_editNet", gat_editNet},
3738 {"gat_editProps", gat_editProps},
3739 {"gat_editModProps", gat_editModProps},
3740 {"gat_editCircProps", gat_editCircProps},
3741 {"gat_errBoxReport", gat_errBoxReport},
3742 {"gat_exit", gat_exit},
3743 {"gat_find", gat_find},
3744 {"gat_formatTime", gat_formatTime},
3745 {"gat_getBit", gat_getBit},
3746 {"gat_getCircProp", gat_getCircProp},
3747 {"gat_getLocales", gat_getLocales},
3748 {"gat_getMajorMode", gat_getMajorMode},
3749 {"gat_getPrinterList", gat_getPrinterList},
3750 {"gat_getRedoList", gat_getRedoList},
3751 {"gat_getSelected", gat_getSelected},
3752 {"gat_getTech", gat_getTech},
3753 {"gat_getTechList", gat_getTechList},
3754 {"gat_getTraceData", gat_getTraceData},
3755 {"gat_getUndoList", gat_getUndoList},
3756 {"gat_gotoCPathNet", gat_gotoCPathNet},
3757 {"gat_hdl", gat_hdl},
3758 {"gat_init", gat_init},
3759 {"gat_interface", gat_interface},
3760 {"gat_libIsLoaded", gat_libIsLoaded},
3761 {"gat_load", gat_load},
3762 {"gat_loadLibrary", gat_loadLibrary},
3763 {"gat_loadMore", gat_loadMore},
3764 {"gat_make", gat_make},
3765 {"gat_makeMakeMenu", gat_makeMakeMenu},
3766 {"gat_makeMakeShortcuts", gat_makeMakeShortcuts},
3767 {"gat_mode", gat_mode},
3768 {"gat_modintCenter", gat_modintCenter},
3769 {"gat_moveGate", gat_moveGate},
3770 {"gat_new", gat_new},
3771 {"gat_newBlock", gat_newBlock},
3772 {"gat_openBox", gat_openBox},
3773 {"gat_obAppendFrame", gat_obAppendFrame},
3774 {"gat_obBeginFrame", gat_obBeginFrame},
3775 {"gat_obEndFrame", gat_obEndFrame},
3776 {"gat_obFlush", gat_obFlush},
3777 {"gat_obMode", gat_obMode},
3778 {"gat_obUnstick", gat_obUnstick},
3779 {"gat_popupPortCmd", gat_popupPortCmd},
3780 {"gat_popupSetState", gat_popupSetState},
3781 {"gat_popupWireProps", gat_popupWireProps},
3782 {"gat_popupWireAddStub", gat_popupWireAddStub},
3783 {"gat_popupWireLabel", gat_popupWireLabel},
3784 {"gat_popupWireSize", gat_popupWireSize},
3785 {"gat_print", gat_print},
3786 {"gat_redo", gat_redo},
3787 {"gat_refreshScreen", gat_refreshScreen},
3788 {"gat_reinitDelay", gat_reinitDelay},
3789 {"gat_renameBlock", gat_renameBlock},
3790 {"gat_replicate", gat_replicate},
3791 {"gat_reroot", gat_reroot},
3792 {"gat_rotate", gat_rotate},
3793 {"gat_saveCircuit", gat_saveCircuit},
3794 {"gat_scopeButton", gat_scopeButton},
3795 {"gat_scopeCommand", gat_scopeCommand},
3796 {"gat_scopeMotion", gat_scopeMotion},
3797 {"gat_scopeRelease", gat_scopeRelease},
3798 {"gat_selectAll", gat_selectAll},
3799 {"gat_selectNet", gat_selectNet},
3800 {"gat_setBlockDesc", gat_setBlockDesc},
3801 {"gat_setBit", gat_setBit},
3802 {"gat_setCircProp", gat_setCircProp},
3803 {"gat_setcolors", gat_setcolors},
3804 {"gat_setDip", gat_setDip},
3805 {"gat_setGateTechDelays", gat_setGateTechDelays},
3806 {"gat_setMajorMode", gat_setMajorMode},
3807 {"gat_setpop", gat_setpop},
3808 {"gat_setShowXHairState", gat_setShowXHairState},
3809 {"gat_setTech", gat_setTech},
3810 {"gat_setrot", gat_setrot},
3811 {"gat_showPath", gat_showPath},
3812 {"gat_simSelected", gat_simSelected},
3813 {"gat_syncInterface", gat_syncInterface},
3814 {"gat_traceLPPEst", gat_traceLPPEst},
3815 {"gat_tracePrint", gat_tracePrint},
3816 {"gat_toggleProbe", gat_toggleProbe},
3817 {"gat_undo", gat_undo},
3818 {"gat_unloadLibrary", gat_unloadLibrary},
3819 {"gat_unselectGates", gat_unselectGates},
3820 {"gat_updateInterface", gat_updateInterface},
3821 {"gat_updateModuleTree", gat_updateModuleTree},
3822 {"gat_updateMenuState", gat_updateMenuState},
3823 {"gat_validatePortName", gat_validatePortName},
3824 {"gat_verify", gat_verify},
3825 {"gat_yankFromBuf", gat_yankFromBuf},
3826 {"gat_zoom", gat_zoom},
3827 };
3828 static int tkg_procTableLen = sizeof(tkg_procTable)/sizeof(tkg_procTable[0]);
3829
3830 /*****************************************************************************
3831 *
3832 * Tcl handler function initialization.
3833 *
3834 * Parameters:
3835 * tcl tcl interpreter handel
3836 *
3837 * Create entries for all of the tcl commands that are used by tkgate.
3838 *
3839 *****************************************************************************/
init_tclProcs(Tcl_Interp * tcl)3840 void init_tclProcs(Tcl_Interp *tcl)
3841 {
3842 int i;
3843
3844 for (i = 0;i < tkg_procTableLen;i++) {
3845 Tcl_CreateCommand(tcl,tkg_procTable[i].command,tkg_procTable[i].func,0,0);
3846 }
3847 }
3848