2
* Electric(tm) VLSI Design System
5
* Asynchronous Logic Simulator command handler
6
* From algorithms by: Brent Serbin and Peter J. Gallant
7
* Last maintained by: Steven M. Rubin
9
* Copyright (c) 2000 Static Free Software.
11
* Electric(tm) is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
16
* Electric(tm) is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with Electric(tm); see the file COPYING. If not, write to
23
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
24
* Boston, Mass 02111-1307, USA.
26
* Static Free Software
28
* Portola Valley, California 94028
29
* info@staticfreesoft.com
38
#include "usrdiacom.h"
40
/* prototypes for local routines */
41
static void simals_erase_submod(CONPTR);
42
static void simals_print_in_entry(ROWPTR);
43
static void simals_print_out_entry(ROWPTR);
44
static void simals_print_xref_entry(CONPTR, INTBIG);
45
static char *simals_strengthstring(INTSML);
46
static void simals_makeactelmodel(char *name, FILE *io, LIBRARY *lib);
47
static void simals_sdfannotate(CONPTR cellhead);
48
static NODEINST *simals_getcellinstance(char *celltype, char *instance);
49
static void simals_sdfportdelay(CONPTR cellhead, NODEINST *ni, char *path);
50
static INTBIG simals_getportdelayvalue(char *datastring, char *transition, DELAY_TYPES delaytype);
51
static INTBIG simals_getdval(char *tstring, DELAY_TYPES delaytype);
52
static void simals_order_save(void);
53
static void simals_order_restore(char *list);
54
static void simals_update_netlist(void);
55
static char *simals_parent_level(char *child);
56
static INTBIG simals_get_tdindex(char *name);
59
static DELAY_TYPES simals_sdfdelaytype;
60
static char *simals_tnames[] = {"01", "10", "0Z", "Z1", "1Z", "Z0", "0X", "X1", "1X", "X0", "XZ", "ZX"};
62
/****************************** ACTEL MODELS ******************************/
64
typedef enum {inputparam, outputparam, bidirparam, edgesenseinputparam,
65
fourstatebiputparam} PARAMTYPE;
67
typedef struct Iactelparam
72
struct Iactelparam *next;
78
* Name: simals_build_actel_command
81
* This procedure reads an Actel table file and creates a library with
84
void simals_build_actel_command(INTBIG count, char *par[])
87
INTBIG len, i, filecount;
88
char *filename, line[MAXCHRS], **filelist;
89
REGISTER char *pt, *start;
90
static INTBIG filetypeacteltab = -1;
94
ttyputusage("telltool simulation als build-actel-model TABLEFILE");
98
for(i=len-1; i>0; i--) if (par[0][i] == DIRSEP) break;
100
filecount = filesindirectory(par[0], &filelist);
103
ttyputerr(M_("There are no files in directory '%s'"), par[0]);
106
for(i=0; i<filecount; i++)
109
(void)addstringtoinfstr(par[0]);
110
(void)addtoinfstr(DIRSEP);
111
(void)addstringtoinfstr(filelist[i]);
113
if (filetypeacteltab < 0)
114
filetypeacteltab = setupfiletype("tab", "*.tab", MACFSTAG('TEXT'), FALSE, "actel", M_("QuickPartTable"));
115
io = xopen(pt, filetypeacteltab, "", &filename);
118
ttyputerr(M_("Cannot find Actel file %s"), pt);
123
if (xfgets(line, MAXCHRS, io) != 0) break;
125
while (*pt == ' ' || *pt == '\t') pt++;
126
if (*pt == 0 || *pt == '#') continue;
128
if (namesamen(pt, "model ", 6) != 0) continue;
130
while (*pt == ' ' || *pt == '\t') pt++;
132
while (*pt != 0 && *pt != ':') pt++;
133
if (*pt != 0) *pt = 0;
134
simals_makeactelmodel(start, io, el_curlib);
140
void simals_makeactelmodel(char *name, FILE *io, LIBRARY *lib)
143
REGISTER char *pt, *start, save, *facetname;
144
REGISTER NODEPROTO *np;
145
INTBIG statetablestate;
146
BOOLEAN doinginput, edgesense, fourstate;
147
ACTELPARAM *ap, *lastap, *inputlist, *outputlist, *paramlist, *paramtail, *nextap, *newap;
150
sa = newstringarray(sim_tool->cluster);
153
/* dump header information for the model */
155
(void)addstringtoinfstr("# Actel model for ");
156
(void)addstringtoinfstr(name);
157
addtostringarray(sa, returninfstr());
159
inputlist = outputlist = paramlist = 0;
163
if (xfgets(line, MAXCHRS, io) != 0) break;
165
/* find the first keyword */
167
while (*pt == ' ' || *pt == '\t') pt++;
168
if (*pt == '#') continue;
169
if (*pt == 0) continue;
171
/* stop if done with table */
172
if (namesamen(pt, "end", 3) == 0) break;
174
/* see if gathering state table information */
175
if (statetablestate != 0)
177
if (statetablestate == 1)
179
/* get state table header */
185
while (*pt == ' ' || *pt == '\t') pt++;
187
while (*pt != 0 && *pt != ' ' && *pt != '\t' && *pt != ',' && *pt != ';' &&
192
/* search input list for this one */
194
for(ap = inputlist; ap != 0; ap = ap->next)
196
if (strcmp(ap->paramname, start) == 0) break;
201
/* see if it is on the output list */
202
for(ap = outputlist; ap != 0; ap = ap->next)
203
if (strcmp(ap->paramname, start) == 0) break;
206
ttyputerr(M_("In model %s, symbol %s not found in parameter lists"),
210
newap = (ACTELPARAM *)emalloc(sizeof (ACTELPARAM), sim_tool->cluster);
211
if (newap == 0) return;
212
(void)allocstring(&newap->paramname, ap->paramname, sim_tool->cluster);
213
newap->paramtype = ap->paramtype;
214
newap->duplicate = TRUE;
218
if (lastap == 0) inputlist = ap->next; else
219
lastap->next = ap->next;
223
/* search output list for this one */
225
for(ap = outputlist; ap != 0; ap = ap->next)
227
if (strcmp(ap->paramname, start) == 0) break;
232
/* see if it is already on the input list */
233
for(ap = paramlist; ap != 0; ap = ap->next)
234
if (strcmp(ap->paramname, start) == 0) break;
237
ttyputerr(M_("In model %s, symbol %s not found in parameter lists"),
241
newap = (ACTELPARAM *)emalloc(sizeof (ACTELPARAM), sim_tool->cluster);
242
if (newap == 0) return;
243
(void)allocstring(&newap->paramname, ap->paramname, sim_tool->cluster);
244
newap->paramtype = ap->paramtype;
245
newap->duplicate = TRUE;
249
if (lastap == 0) outputlist = ap->next; else
250
lastap->next = ap->next;
254
if (paramtail == 0) paramlist = paramtail = ap; else
256
paramtail->next = ap;
260
while (*pt == ' ' || *pt == '\t') pt++;
261
if (*pt == ';') break;
262
if (*pt == ':') { pt += 2; doinginput = FALSE; continue; }
263
if (*pt == ',') { pt++; continue; }
264
ttyputerr(M_("In model %s, missing comma in Actel symbol list"), name);
268
/* now dump the model header */
270
(void)addstringtoinfstr("gate ");
271
(void)addstringtoinfstr(name);
272
(void)addstringtoinfstr("(");
273
for(ap = paramlist; ap != 0; ap = ap->next)
275
if (ap->duplicate) continue;
276
if (ap != paramlist) (void)addstringtoinfstr(", ");
277
(void)addstringtoinfstr(ap->paramname);
279
(void)addstringtoinfstr(")");
280
addtostringarray(sa, returninfstr());
281
addtostringarray(sa, "t: delta=1.0e-9");
285
/* get state table entry */
288
(void)addstringtoinfstr("i: ");
291
while (*pt == ' ' || *pt == '\t') pt++;
292
(void)addstringtoinfstr(ap->paramname);
293
(void)addstringtoinfstr("=");
296
case '0': (void)addstringtoinfstr("L"); break;
297
case '1': (void)addstringtoinfstr("H"); break;
298
case '?': (void)addstringtoinfstr("X"); break;
299
case '[': (void)addstringtoinfstr("E"); break;
300
case '(': (void)addstringtoinfstr("F"); break;
301
case 'Z': (void)addstringtoinfstr("Z"); break;
302
case 'X': (void)addstringtoinfstr("XX"); break;
303
case '!': (void)addstringtoinfstr("N"); break;
305
(void)addstringtoinfstr(" ");
307
while (*pt != 0 && *pt != ',' && *pt != ';' && *pt != ':') pt++;
308
if (*pt == ';') break;
309
if (*pt == ':') { (void)addstringtoinfstr("o: "); pt++; }
313
addtostringarray(sa, returninfstr());
318
/* handle "edge_sense" prefix */
320
if (namesamen(pt, "edge_sense", 10) == 0)
324
while (*pt == ' ' || *pt == '\t') pt++;
327
/* handle "four_state" prefix */
329
if (namesamen(pt, "four_state", 10) == 0)
333
while (*pt == ' ' || *pt == '\t') pt++;
337
if (namesamen(pt, "input", 5) == 0)
342
while (*pt == ' ' || *pt == '\t') pt++;
344
while (*pt != 0 && *pt != ' ' && *pt != '\t' && *pt != ',' && *pt != ';') pt++;
346
ap = (ACTELPARAM *)emalloc(sizeof (ACTELPARAM), sim_tool->cluster);
348
(void)allocstring(&ap->paramname, start, sim_tool->cluster);
349
if (edgesense) ap->paramtype = edgesenseinputparam; else
350
ap->paramtype = inputparam;
351
ap->duplicate = FALSE;
352
ap->next = inputlist;
355
while (*pt == ' ' || *pt == '\t') pt++;
356
if (*pt == ';') break;
357
if (*pt == ',') { pt++; continue; }
358
ttyputerr(M_("In model %s, missing comma in Actel input list"), name);
365
if (namesamen(pt, "output", 6) == 0)
370
while (*pt == ' ' || *pt == '\t') pt++;
372
while (*pt != 0 && *pt != ' ' && *pt != '\t' && *pt != ',' && *pt != ';') pt++;
374
ap = (ACTELPARAM *)emalloc(sizeof (ACTELPARAM), sim_tool->cluster);
376
(void)allocstring(&ap->paramname, start, sim_tool->cluster);
377
ap->paramtype = outputparam;
378
ap->duplicate = FALSE;
379
ap->next = outputlist;
382
while (*pt == ' ' || *pt == '\t') pt++;
383
if (*pt == ';') break;
384
if (*pt == ',') { pt++; continue; }
385
ttyputerr(M_("In model %s, missing comma in Actel output list"), name);
391
/* gather bidirectionals */
392
if (namesamen(pt, "biput", 5) == 0)
397
while (*pt == ' ' || *pt == '\t') pt++;
399
while (*pt != 0 && *pt != ' ' && *pt != '\t' && *pt != ',' && *pt != ';') pt++;
401
ap = (ACTELPARAM *)emalloc(sizeof (ACTELPARAM), sim_tool->cluster);
403
(void)allocstring(&ap->paramname, start, sim_tool->cluster);
404
if (fourstate) ap->paramtype = fourstatebiputparam; else
405
ap->paramtype = bidirparam;
406
ap->duplicate = FALSE;
407
ap->next = inputlist;
410
while (*pt == ' ' || *pt == '\t') pt++;
411
if (*pt == ';') break;
412
if (*pt == ',') { pt++; continue; }
413
ttyputerr(M_("In model %s, missing comma in Actel biput list"), name);
419
/* start state table */
420
if (namesamen(pt, "state_table", 11) == 0)
427
(void)addstringtoinfstr("load");
428
for(ap = paramlist; ap != 0; ap = nextap)
431
if (ap->paramtype == inputparam || ap->paramtype == edgesenseinputparam)
433
(void)addstringtoinfstr(" ");
434
(void)addstringtoinfstr(ap->paramname);
435
(void)addstringtoinfstr("=1.0");
437
efree(ap->paramname);
440
addtostringarray(sa, returninfstr());
442
/* now put strings onto a facet */
444
(void)addstringtoinfstr(name);
445
(void)addstringtoinfstr("{net-als}");
446
facetname = returninfstr();
447
np = newnodeproto(facetname, lib);
448
if (np == NONODEPROTO)
450
ttyputerr(M_("Cannot create facet %s"), facetname);
453
stringarraytotextfacet(sa, np, TRUE);
455
ttyputmsg(M_("Created %s"), describenodeproto(np));
458
/****************************** CLOCK ******************************/
461
* Name: simals_clock_command
464
* This procedure enters a complex clock vector into the user defined
465
* event list. The user is polled for the node name and timing parameters
466
* before any entry is made into the linklist.
468
void simals_clock_command(INTBIG count, char *par[])
470
double time, totaltime;
473
LINKPTR vectptr1, vectptr2, sethead;
481
if (sim_window_isactive(&np) == 0)
483
ttyputerr(M_("No simulator active"));
488
ttyputusage("telltool simulation als clock NODENAME (freq | period | custom)");
492
simals_convert_to_upper(par[0]);
493
nodehead = simals_find_node(par[0]);
496
ttyputerr(M_("ERROR: Unable to find node %s"), par[0]);
502
count = sim_alsclockdlog(&par[1]) + 1;
503
if (count < 2) return;
506
/* see if there are frequency/period parameters */
508
if (namesamen(par[1], "frequency", l) == 0 || namesamen(par[1], "period", l) == 0)
512
ttyputusage("telltool simulation als clock NODENAME frequency/period PERIOD");
518
ttyputerr(M_("Clock timing parameter must be greater than 0"));
522
if (namesamen(par[1], "frequency", l) == 0) time = 1.0f / time;
524
vectptr2 = simals_alloc_link_mem();
525
if (vectptr2 == 0) return;
526
vectptr2->type = 'N';
527
vectptr2->ptr = (char *)nodehead;
528
vectptr2->state = LOGIC_HIGH;
529
vectptr2->strength = VDD_STRENGTH;
530
vectptr2->priority = 1;
531
vectptr2->time = 0.0;
534
vectptr1 = simals_alloc_link_mem();
535
if (vectptr1 == 0) return;
536
vectptr1->type = 'N';
537
vectptr1->ptr = (char *)nodehead;
538
vectptr1->state = LOGIC_LOW;
539
vectptr1->strength = VDD_STRENGTH;
540
vectptr1->priority = 1;
541
vectptr1->time = time / 2.0f;
542
vectptr1->right = vectptr2;
544
clokhead = (ROWPTR)simals_alloc_mem((INTBIG)sizeof(ROW));
545
if (clokhead == 0) return;
546
clokhead->inptr = (IOPTR)vectptr1;
547
clokhead->outptr = 0;
548
clokhead->delta = (float)time;
549
clokhead->linear = 0.0;
552
clokhead->random = 0.0;
556
sethead = simals_alloc_link_mem();
557
if (sethead == 0) return;
559
sethead->ptr = (char *)clokhead;
561
sethead->priority = 1;
564
simals_insert_set_list(sethead);
566
(void)simals_initialize_simulator(FALSE);
570
if (namesamen(par[1], "custom", l) != 0)
572
ttyputbadusage("telltool simulation als clock");
576
/* handle custom clock specification */
579
ttyputusage("telltool simulation als clock custom RAN STR CY (L D) *");
583
linear = (float)atof(par[2]);
584
strength = (INTSML)simals_atoi(par[3])*2;
585
num = simals_atoi(par[4]);
589
vectptr = (char**) &vectroot;
590
for(i=5; i<count; i += 2)
592
vectptr2 = simals_alloc_link_mem();
593
if (vectptr2 == 0) return;
594
vectptr2->type = 'N';
595
vectptr2->ptr = (char *) nodehead;
596
vectptr2->state = simals_trans_state_to_number(par[i]);
597
vectptr2->strength = strength;
598
vectptr2->priority = 1;
599
vectptr2->time = atof(par[i+1]);
600
totaltime += vectptr2->time;
602
*vectptr = (char*) vectptr2;
603
vectptr = (char**) &(vectptr2->right);
605
vectptr2->time = 0.0;
607
clokhead = (ROWPTR) simals_alloc_mem((INTBIG)sizeof(ROW));
608
if (clokhead == 0) return;
609
clokhead->inptr = (IOPTR) vectroot;
610
clokhead->outptr = 0;
611
clokhead->delta = (float)totaltime;
612
clokhead->linear = linear;
615
clokhead->random = 0.0;
619
sethead = simals_alloc_link_mem();
620
if (sethead == 0) return;
622
sethead->ptr = (char *) clokhead;
623
sethead->state = num;
624
sethead->priority = 1;
627
simals_insert_set_list(sethead);
629
(void)simals_initialize_simulator(FALSE);
632
/****************************** ERASE ******************************/
634
void simals_erase_model(void)
636
MODPTR modptr, nextmodptr;
637
EXPTR exptr, nextexptr;
638
CONPTR conptr, nextconptr;
639
IOPTR ioptr, nextioptr;
640
ROWPTR rowptr, nextrowptr;
641
LOADPTR loadptr, nextloadptr;
643
NODEPTR node, nextnode;
644
STATPTR statptr, nextstatptr;
646
/* reset miscellaneous simulation variables */
647
simals_linkfront = 0;
650
/* loop through all test vectors */
651
simals_clearallvectors(TRUE);
653
/* loop throuth all cells in flattened network */
654
if (simals_cellroot != 0)
656
simals_erase_submod(simals_cellroot);
657
efree((char *)simals_cellroot);
662
/* loop through all nodes in flattened network */
663
for(node = simals_noderoot; node != 0; node = nextnode)
665
nextnode = node->next;
667
/* erase all loads on the nodes */
668
for(loadptr = node->pinptr; loadptr != 0; loadptr = nextloadptr)
670
nextloadptr = loadptr->next;
671
efree((char *)loadptr);
674
/* erase all stats on the nodes */
675
for(statptr = node->statptr; statptr != 0; statptr = nextstatptr)
677
nextstatptr = statptr->next;
678
efree((char *)statptr);
684
/* loop through all primitives in flattened network */
685
for(modptr = simals_primroot; modptr != 0; modptr = nextmodptr)
687
nextmodptr = modptr->next;
688
if (modptr->type == 'F')
690
/* loop through each formal port on the function */
691
for(exptr = modptr->exptr; exptr != 0; exptr = nextexptr)
693
nextexptr = exptr->next;
694
efree((char *)exptr);
697
/* loop through each parameter on the function */
698
funcptr = (FUNCPTR)modptr->ptr;
699
for(exptr = funcptr->inptr; exptr != 0; exptr = nextexptr)
701
nextexptr = exptr->next;
702
efree((char *)exptr);
705
efree((char *)funcptr);
707
if (modptr->type == 'G')
709
/* loop through each row in the gate */
710
for(rowptr = (ROWPTR)modptr->ptr; rowptr != 0; rowptr = nextrowptr)
712
nextrowptr = rowptr->next;
714
/* loop through each input on the row */
715
for(ioptr = rowptr->inptr; ioptr != 0; ioptr = nextioptr)
717
nextioptr = ioptr->next;
718
efree((char *)ioptr);
721
/* loop through each output on the row */
722
for(ioptr = rowptr->outptr; ioptr != 0; ioptr = nextioptr)
724
nextioptr = ioptr->next;
725
efree((char *)ioptr);
727
if (rowptr->delay != 0) efree((char *)rowptr->delay);
728
efree((char *)rowptr);
731
if (modptr->level != 0) efree((char *)modptr->level);
732
efree((char *)modptr);
736
/* loop through each model/gate/function in hierarchical description */
737
for(modptr = simals_modroot; modptr != 0; modptr = nextmodptr)
739
nextmodptr = modptr->next;
740
efree((char *)modptr->name);
742
/* loop through each formal port on the model/gate/function */
743
for(exptr = modptr->exptr; exptr != 0; exptr = nextexptr)
745
nextexptr = exptr->next;
746
efree((char *)exptr->node_name);
747
efree((char *)exptr);
750
/* loop through each "SET" instruction in the model/gate/function */
751
for(ioptr = modptr->setptr; ioptr != 0; ioptr = nextioptr)
753
nextioptr = ioptr->next;
754
efree((char *)ioptr->nodeptr);
755
efree((char *)ioptr);
758
/* special cleanup for functions */
759
if (modptr->type == 'F')
761
funcptr = (FUNCPTR)modptr->ptr;
763
/* loop through each load in the function */
764
for(loadptr = modptr->loadptr; loadptr != 0; loadptr = nextloadptr)
766
nextloadptr = loadptr->next;
767
efree((char *)loadptr->ptr);
768
efree((char *)loadptr);
771
/* loop through each input on the function */
772
for(exptr = funcptr->inptr; exptr != 0; exptr = nextexptr)
774
nextexptr = exptr->next;
775
efree((char *)exptr->node_name);
776
efree((char *)exptr);
778
efree((char *)funcptr);
781
/* special cleanup for models */
782
if (modptr->type == 'M')
784
/* loop through each instance in the model */
785
for(conptr = (CONPTR)modptr->ptr; conptr != 0; conptr = nextconptr)
787
nextconptr = conptr->next;
788
efree((char *)conptr->inst_name);
789
if (conptr->model_name != 0) efree(conptr->model_name);
791
/* loop through each actual port on the instance */
792
for(exptr = conptr->exptr; exptr != 0; exptr = nextexptr)
794
nextexptr = exptr->next;
795
efree((char *)exptr->node_name);
796
efree((char *)exptr);
798
efree((char *)conptr);
802
/* special cleanup for gates */
803
if (modptr->type == 'G')
805
/* loop through each row in the gate */
806
for(rowptr = (ROWPTR)modptr->ptr; rowptr != 0; rowptr = nextrowptr)
808
nextrowptr = rowptr->next;
810
/* loop through each input on the row */
811
for(ioptr = rowptr->inptr; ioptr != 0; ioptr = nextioptr)
813
nextioptr = ioptr->next;
814
efree((char *)ioptr->nodeptr);
815
efree((char *)ioptr);
818
/* loop through each output on the row */
819
for(ioptr = rowptr->outptr; ioptr != 0; ioptr = nextioptr)
821
nextioptr = ioptr->next;
822
efree((char *)ioptr->nodeptr);
823
efree((char *)ioptr);
825
if (rowptr->delay != 0) efree((char *)rowptr->delay);
826
efree((char *)rowptr);
829
/* loop through each load in the gate */
830
for(loadptr = modptr->loadptr; loadptr != 0; loadptr = nextloadptr)
832
nextloadptr = loadptr->next;
833
efree((char *)loadptr->ptr);
834
efree((char *)loadptr);
838
if (modptr->level != 0) efree((char *)modptr->level);
839
efree((char *)modptr);
845
* Routine to clear all test vectors (even the power and ground vectors if "pwrgnd"
848
void simals_clearallvectors(BOOLEAN pwrgnd)
850
LINKPTR thisset, vecthead, nextvec, nextset, lastset;
854
for(thisset = simals_setroot; thisset != 0; thisset = nextset)
856
nextset = thisset->right;
857
if (pwrgnd || thisset->strength != VDD_STRENGTH)
859
if (thisset->type == 'C')
861
clokhead = (ROWPTR)thisset->ptr;
862
for (vecthead = (LINKPTR)clokhead->inptr; vecthead; vecthead = nextvec)
864
nextvec = vecthead->right;
865
simals_free_link_mem(vecthead);
867
efree((char *)clokhead);
869
simals_free_link_mem(thisset);
871
if (lastset == 0) simals_setroot = nextset; else
872
lastset->right = nextset;
880
void simals_erase_submod(CONPTR conhead)
882
CONPTR conptr, nextconptr;
883
EXPTR exptr, nextexptr;
884
REGISTER INTBIG chn, i;
886
for(conptr = conhead->child; conptr != 0; conptr = nextconptr)
888
nextconptr = conptr->next;
889
simals_erase_submod(conptr);
890
for(exptr = conptr->exptr; exptr != 0; exptr = nextexptr)
892
nextexptr = exptr->next;
893
efree((char *)exptr);
895
efree((char *)conptr);
897
if (conhead->display_page != 0)
899
chn = conhead->num_chn + 1;
900
for (i = 1; i < chn; i++)
901
efree((char *)conhead->display_page[i].name);
902
efree((char *)conhead->display_page);
906
/****************************** GO ******************************/
909
* Name: simals_go_command
912
* This procedure parses the command line for the go command from the
913
* keyboard. The maximum execution time must also be specified for the
916
void simals_go_command(INTBIG count, char *par[])
921
if (sim_window_isactive(&np) == 0)
923
ttyputerr(M_("No simulator active"));
928
ttyputerr(M_("Must specify simulation time"));
934
ttyputerr(M_("Simulation time must be greater than 0 seconds"));
937
sim_window_settimerange(0.0, max);
939
(void)simals_initialize_simulator(TRUE);
942
/****************************** HELP ******************************/
945
* Name: simals_help_command
948
* This procedure process the help command and display help information.
950
void simals_help_command(void)
952
(void)us_helpdlog("ALS");
955
/****************************** LEVEL ******************************/
958
* Name: simals_level_up_command
961
* This procedure changes the level of hierarchy up one level.
963
void simals_level_up_command(void)
967
double mintime, maxtime, maintime, exttime;
970
if (sim_window_isactive(&np) == 0)
972
ttyputerr(_("No simulator active"));
976
if (simals_levelptr == 0)
978
ttyputerr(_("No simulation is running"));
981
cellptr = simals_levelptr->parent;
984
ttyputerr(_("ERROR: Currently at top level of hierarchy"));
988
simals_levelptr = cellptr;
990
/* reinitialize simulator while preserving time information */
991
sim_window_gettimerange(&mintime, &maxtime);
992
maintime = sim_window_getmaincursor();
993
exttime = sim_window_getextensioncursor();
994
if (simals_set_current_level()) return;
995
sim_window_settimerange(mintime, maxtime);
996
sim_window_setmaincursor(maintime);
997
sim_window_setextensioncursor(exttime);
999
l = simals_levelptr->num_chn;
1000
sim_window_setlines(l);
1001
sim_window_settopline(0);
1002
(void)simals_initialize_simulator(TRUE);
1006
* Name: simals_level_set_command
1009
* This procedure changes the level of hierarchy to a specified new (lower) level.
1011
void simals_level_set_command(char *instname)
1015
double mintime, maxtime, maintime, exttime;
1019
if (sim_window_isactive(&np) == 0)
1021
ttyputerr(_("No simulator active"));
1025
for(pt = instname; *pt != 0; pt++) if (*pt == ' ') break;
1027
simals_convert_to_upper(instname);
1028
cellptr = simals_find_level(instname);
1031
ttyputerr(M_("ERROR: Unable to find level %s"), instname);
1035
simals_levelptr = cellptr;
1037
/* reinitialize simulator while preserving time information */
1038
sim_window_gettimerange(&mintime, &maxtime);
1039
maintime = sim_window_getmaincursor();
1040
exttime = sim_window_getextensioncursor();
1041
if (simals_set_current_level()) return;
1042
sim_window_settimerange(mintime, maxtime);
1043
sim_window_setmaincursor(maintime);
1044
sim_window_setextensioncursor(exttime);
1046
l = simals_levelptr->num_chn;
1047
sim_window_setlines(l);
1048
sim_window_settopline(0);
1049
(void)simals_initialize_simulator(TRUE);
1052
/****************************** PRINT ******************************/
1055
* routine to print out the display screen status and information
1057
void simals_print_command(INTBIG count, char *par[])
1072
ttyputusage("telltool simulation als print OPTION");
1075
l = strlen(pt = par[0]);
1077
if (namesamen(pt, "size", l) == 0 && l >= 2)
1079
ttyputmsg(M_("Number of Primitive Elements in Database = %ld"), simals_pseq);
1080
ttyputmsg(M_("Number of Nodes in Database = %ld"), simals_nseq);
1084
if (namesamen(pt, "vector", l) == 0 && l >= 1)
1086
linkhead = simals_setroot;
1087
ttyputmsg(M_("** VECTOR LINKLIST **"));
1090
switch (linkhead->type)
1093
nodehead = (NODEPTR)linkhead->ptr;
1094
simals_trans_number_to_state(linkhead->state, s1);
1095
ttyputmsg(M_("***** vector: $N%ld, state = %s, strength = %s, time = %g, priority = %d"),
1096
nodehead->num, s1, simals_strengthstring(linkhead->strength),
1097
linkhead->time, linkhead->priority);
1100
stathead = (STATPTR)linkhead->ptr;
1101
nodehead = stathead->nodeptr;
1102
simals_trans_number_to_state(linkhead->state, s1);
1103
ttyputmsg(M_("***** function: $N%ld, state = %s, strength = %s, time = %g, priority = %d"),
1104
nodehead->num, s1, simals_strengthstring(linkhead->strength),
1105
linkhead->time, linkhead->priority);
1108
ttyputmsg(M_("***** rowptr = %ld, time = %g, priority = %d"),
1109
linkhead->ptr, linkhead->time, linkhead->priority);
1112
ttyputmsg(M_("***** clokptr = %ld, time = %g, priority = %d"),
1113
linkhead->ptr, linkhead->time, linkhead->priority);
1115
linkhead = linkhead->right;
1120
if (namesamen(pt, "netlist", l) == 0 && l >= 1)
1122
ttyputmsg(M_("** NETWORK DESCRIPTION **"));
1123
for (primhead = simals_primroot; primhead; primhead = primhead->next)
1125
if (stopping(STOPREASONDISPLAY)) return;
1126
switch (primhead->type)
1130
(void)formatinfstr(M_("FUNCTION %ld: %s (instance %s) ["), primhead->num, primhead->name,
1131
(primhead->level == NULL) ? M_("null") : primhead->level);
1132
for (exhead = primhead->exptr; exhead; exhead=exhead->next)
1134
if (exhead != primhead->exptr) (void)addstringtoinfstr(", ");
1135
(void)formatinfstr("N%ld", exhead->nodeptr->num);
1137
(void)addstringtoinfstr("]");
1138
ttyputmsg("%s", returninfstr());
1140
(void)addstringtoinfstr(M_(" Event Driving Inputs:"));
1141
funchead = (FUNCPTR)primhead->ptr;
1142
for (exhead = funchead->inptr; exhead; exhead=exhead->next)
1143
(void)formatinfstr(" N%ld", exhead->nodeptr->num);
1144
ttyputmsg("%s", returninfstr());
1146
(void)addstringtoinfstr(M_(" Output Ports:"));
1147
for (exhead = primhead->exptr; exhead; exhead=exhead->next)
1149
if (exhead->node_name)
1150
(void)formatinfstr(" N%ld", ((STATPTR)exhead->node_name)->nodeptr->num);
1152
ttyputmsg("%s", returninfstr());
1153
ttyputmsg(M_(" Timing: D=%g, L=%g, E=%g, R=%g, A=%g"), funchead->delta,
1154
funchead->linear, funchead->exp, funchead->random, funchead->abs);
1155
ttyputmsg(M_(" Firing Priority = %d"), primhead->priority);
1158
ttyputmsg(M_("GATE %ld: %s (instance %s)"), primhead->num, primhead->name,
1159
(primhead->level == NULL) ? M_("null") : primhead->level);
1160
for (rowhead = (ROWPTR)primhead->ptr; rowhead; rowhead=rowhead->next)
1162
ttyputmsg(M_(" Timing: D=%g, L=%g, E=%g, R=%g, A=%g"), rowhead->delta,
1163
rowhead->linear, rowhead->exp, rowhead->random, rowhead->abs);
1164
ttyputmsg(M_(" Delay type: %s"), (rowhead->delay == NULL) ? M_("null") : rowhead->delay);
1165
simals_print_in_entry(rowhead);
1166
simals_print_out_entry(rowhead);
1168
ttyputmsg(M_(" Firing Priority = %d"), primhead->priority);
1171
ttyputerr(M_("Illegal primitive type '%c', database is bad"), primhead->type);
1178
if (namesamen(pt, "xref", l) == 0 && l >= 1)
1180
ttyputmsg(M_("** CROSS REFERENCE TABLE **"));
1181
simals_print_xref_entry(simals_levelptr, 0);
1185
if (namesamen(pt, "state", l) == 0 && l >= 2)
1189
ttyputusage("telltool simulation als print state NODENAME");
1192
simals_convert_to_upper(par[1]);
1193
nodehead = simals_find_node(par[1]);
1196
ttyputerr(M_("ERROR: Unable to find node %s"), par[1]);
1200
simals_trans_number_to_state(nodehead->new_state, s1);
1201
ttyputmsg(M_("Node %s: State = %s, Strength = %s"), par[1], s1,
1202
simals_strengthstring(nodehead->new_strength));
1203
stathead = nodehead->statptr;
1206
simals_trans_number_to_state(stathead->new_state, s1);
1207
ttyputmsg(M_("Primitive %ld: State = %s, Strength = %s"), stathead->primptr->num,
1208
s1, simals_strengthstring(stathead->new_strength));
1209
stathead = stathead->next;
1214
if (namesamen(pt, "instances", l) == 0 && l >= 1)
1216
ttyputmsg(M_("Instances at level: %s"), simals_compute_path_name(simals_levelptr));
1217
for (cellhead = simals_levelptr->child; cellhead; cellhead = cellhead->next)
1219
if (stopping(STOPREASONDISPLAY)) break;
1220
ttyputmsg(M_("Name: %s, Model: %s"), cellhead->inst_name, cellhead->model_name);
1224
ttyputbadusage("telltool simulation als print");
1227
char *simals_strengthstring(INTSML strength)
1229
if (strength == OFF_STRENGTH) return(_("off"));
1230
if (strength <= NODE_STRENGTH) return(_("node"));
1231
if (strength <= GATE_STRENGTH) return(_("gate"));
1236
* Name: simals_print_in_entry
1239
* This procedure examines an input entry and prints out the condition
1240
* that it represents. It is possible for an input entry operand to represent
1241
* a logic value, integer value, or another node address.
1243
* Calling Arguments:
1244
* rowhead = pointer to the row being printed
1246
void simals_print_in_entry(ROWPTR rowhead)
1250
unsigned char operatr;
1256
(void)addstringtoinfstr(M_(" Input: "));
1258
for (iohead = rowhead->inptr; iohead; iohead = iohead->next)
1260
if (flag) (void)addstringtoinfstr("& ");
1263
nodehead = (NODEPTR)iohead->nodeptr;
1264
(void)sprintf(s1, "N%ld", nodehead->num);
1265
(void)addstringtoinfstr(s1);
1267
if (iohead->operatr > 127)
1269
operatr = iohead->operatr - 128;
1270
nodehead = (NODEPTR) iohead->operand;
1271
(void)sprintf(s1, "%cN%ld", operatr, nodehead->num);
1272
(void)addstringtoinfstr(s1);
1276
(void)addtoinfstr(iohead->operatr);
1278
num = (INTBIG)iohead->operand;
1279
simals_trans_number_to_state(num, s1);
1280
(void)addstringtoinfstr(s1);
1281
(void)addstringtoinfstr(" ");
1283
ttyputmsg("%s", returninfstr());
1287
* Name: simals_print_out_entry
1290
* This procedure examines an output entry and prints out the condition
1291
* that it represents. It is possible for an output entry operand to represent
1292
* a logic value, integer value, or another node address.
1294
* Calling Arguments:
1295
* rowhead = pointer to the row being printed
1297
void simals_print_out_entry(ROWPTR rowhead)
1301
unsigned char operatr;
1308
(void)addstringtoinfstr(M_(" Output: "));
1310
for (iohead = rowhead->outptr; iohead; iohead = iohead->next)
1312
if (flag) (void)addstringtoinfstr("& ");
1315
stathead = (STATPTR)iohead->nodeptr;
1316
nodehead = stathead->nodeptr;
1317
(void)sprintf(s1, "N%ld", nodehead->num);
1318
(void)addstringtoinfstr(s1);
1320
if (iohead->operatr > 127)
1322
operatr = iohead->operatr - 128;
1323
nodehead = (NODEPTR) iohead->operand;
1324
(void)sprintf(s1, "%cN%ld@%d ", operatr, nodehead->num, (iohead->strength+1)/2);
1325
(void)addstringtoinfstr(s1);
1329
(void)addtoinfstr(iohead->operatr);
1331
num = (INTBIG)iohead->operand;
1332
simals_trans_number_to_state(num, s1);
1333
(void)addstringtoinfstr(s1);
1334
(void)sprintf(s1, "@%d ", (iohead->strength+1)/2);
1335
(void)addstringtoinfstr(s1);
1337
ttyputmsg("%s", returninfstr());
1341
* Name: simals_print_xref_entry
1344
* This procedure prints entries from the cross reference table that was
1345
* generated to transform the hierarchical network description into a totally flat
1346
* network description. The calling arguments define the root of the reference
1347
* table column and the level of indentation for the column.
1349
* Calling Arguments:
1350
* cellhead = pointer to cross reference table
1351
* tab = integer value indicating level of output indentation
1353
void simals_print_xref_entry(CONPTR cellhead, INTBIG tab)
1356
char tabsp[200], ts[256];
1360
if (stopping(STOPREASONDISPLAY)) return;
1361
for (i = 0; i < tab; ++i) tabsp[i] = ' ';
1363
ttyputmsg(M_("%sLevel: %s, Model: %s"), tabsp, simals_compute_path_name(cellhead),
1364
cellhead->model_name);
1366
for (exhead = cellhead->exptr; exhead; exhead = exhead->next)
1368
if (stopping(STOPREASONDISPLAY)) return;
1370
for (i=0; i<12; i++)
1372
delay = exhead->td[i];
1375
if (k == 0) (void)initinfstr();
1376
(void)sprintf(ts, "%s=%ld ", simals_tnames[i], delay);
1377
(void)addstringtoinfstr(ts);
1381
if (k == 0) ttyputmsg("%s%14s --> N%ld", tabsp, exhead->node_name, exhead->nodeptr->num); else
1382
ttyputmsg("%s%14s --> N%ld (%s)", tabsp, exhead->node_name, exhead->nodeptr->num, returninfstr());
1385
if (simals_instbuf[simals_instptr[1]] == 'X') return;
1387
for (subcell = cellhead->child; subcell; subcell = subcell->next)
1388
simals_print_xref_entry(subcell, tab + 10);
1391
/****************************** SEED ******************************/
1394
* Name: simals_seed_command
1397
* This procedure sets a flag which tells the simulator if it is necessary
1398
* to reseed the Random Number Generator each time a simulation is run.
1400
void simals_seed_command(INTBIG count, char *par[])
1404
ttyputusage("telltool simulation als seed (reset | no-reset)");
1407
if (namesamen(par[0], "reset", strlen(par[0])) == 0)
1408
simals_seed_flag = FALSE; else simals_seed_flag = TRUE;
1411
/****************************** SET ******************************/
1414
* Name: simals_set_command
1417
* This procedure sets the specified node to the state that is indicated
1418
* in the command line.
1420
void simals_set_command(INTBIG count, char *par[])
1429
if (sim_window_isactive(&np) == 0)
1431
ttyputerr(_("No simulator active"));
1436
ttyputusage("telltool simulation als set NODE LEVEL STRENGTH TIME");
1439
simals_convert_to_upper(par[0]);
1440
nodehead = simals_find_node(par[0]);
1443
ttyputerr(_("ERROR: Unable to find node %s"), par[0]);
1447
state = simals_trans_state_to_number(par[1]);
1448
strength = (INTSML)simals_atoi(par[2])*2;
1449
time = atof(par[3]);
1451
sethead = simals_alloc_link_mem();
1452
if (sethead == 0) return;
1453
sethead->type = 'N';
1454
sethead->ptr = (char *)nodehead;
1455
sethead->state = state;
1456
sethead->strength = strength;
1457
sethead->priority = 2;
1458
sethead->time = time;
1460
simals_insert_set_list(sethead);
1462
ttyputmsg(M_("Node '%s' scheduled, state = %s, strength = %s, time = %g"), par[0], par[1],
1463
simals_strengthstring(strength), time);
1464
(void)simals_initialize_simulator(FALSE);
1467
/****************************** TRACE ******************************/
1470
* Name: simals_trace_command
1473
* This procedure turns on/off the trace buffer. If it is turned off, no
1474
* timing diagram information will be stored in memory for plotting.
1476
void simals_trace_command(INTBIG count, char *par[])
1483
ttyputusage("telltool simulation als trace OPTION");
1486
l = strlen(pt = par[0]);
1487
if (namesamen(pt, "on", l) == 0 && l >= 2)
1489
(void)setvalkey((INTBIG)sim_tool, VTOOL, simals_no_update_key, 0, VINTEGER);
1492
if (namesamen(pt, "off", l) == 0 && l >= 2)
1494
(void)setvalkey((INTBIG)sim_tool, VTOOL, simals_no_update_key, 1, VINTEGER);
1497
ttyputbadusage("telltool simulation als trace");
1500
/****************************** VECTOR ******************************/
1502
void simals_vector_command(INTBIG count, char *par[])
1506
char s1[256], s2[80], *pt, **vectptr1, **backptr;
1507
char *filename, *truename;
1509
LINKPTR sethead, vecthead, vectptr2, nextvec;
1515
if (sim_window_isactive(&np) == 0)
1517
ttyputerr(_("No simulator active"));
1522
ttyputusage("telltool simulation als vector OPTION");
1525
l = strlen(pt = par[0]);
1527
if (namesamen(pt, "load", l) == 0)
1531
par[1] = fileselect(_("ALS vector file"), sim_filetypealsvec, "");
1532
if (par[1] == 0) return;
1534
vin = xopen(par[1], sim_filetypealsvec, "", &filename);
1537
ttyputerr(_("ERROR: Can't open %s"), par[1]);
1541
/* clear all vectors */
1542
while (simals_setroot)
1544
sethead = simals_setroot;
1545
simals_setroot = simals_setroot->right;
1546
if (sethead->type == 'C')
1548
clokhead = (ROWPTR) sethead->ptr;
1549
for (vectptr2 = (LINKPTR) clokhead->inptr; vectptr2; vectptr2 = nextvec)
1551
nextvec = vectptr2->right;
1552
simals_free_link_mem(vectptr2);
1554
efree((char *)clokhead);
1556
simals_free_link_mem(sethead);
1564
if (xfgets(s1, 255, vin))
1567
(void)simals_initialize_simulator(FALSE);
1570
simals_convert_to_upper(s1);
1571
if (simals_fragment_command(s1)) break;
1574
if (! strcmp(simals_instbuf, "CLOCK"))
1576
simals_convert_to_upper(&(simals_instbuf[simals_instptr[1]]));
1577
nodehead = simals_find_node(&(simals_instbuf[simals_instptr[1]]));
1580
ttyputerr(_("ERROR: Unable to find node %s"),
1581
&(simals_instbuf[simals_instptr[1]]));
1585
strength = atoi(&(simals_instbuf[simals_instptr[9]]))*2;
1587
sethead = simals_alloc_link_mem();
1588
if (sethead == 0) return;
1589
sethead->type = 'C';
1590
sethead->ptr = (char*)(clokhead = (ROWPTR) simals_alloc_mem((INTBIG)sizeof(ROW)));
1591
if (sethead->ptr == 0) return;
1592
sethead->state = atoi(&(simals_instbuf[simals_instptr[13]]));
1593
sethead->priority = 1;
1594
sethead->time = atof(&(simals_instbuf[simals_instptr[11]]));
1596
simals_insert_set_list(sethead);
1598
clokhead->delta = (float)atof(&(simals_instbuf[simals_instptr[3]]));
1599
clokhead->linear = (float)atof(&(simals_instbuf[simals_instptr[5]]));
1600
clokhead->exp = (float)atof(&(simals_instbuf[simals_instptr[7]]));
1601
clokhead->abs = 0.0;
1602
clokhead->random = 0.0;
1604
clokhead->delay = 0;
1606
vectptr1 = (char**) &(clokhead->inptr);
1609
if (xfgets(s1, 255, vin))
1612
(void)simals_initialize_simulator(FALSE);
1615
simals_convert_to_upper(s1);
1616
if (simals_fragment_command(s1)) return;
1617
if (!strcmp(simals_instbuf, "CLOCK") || !strcmp(simals_instbuf, "SET"))
1622
vectptr2 = simals_alloc_link_mem();
1623
if (vectptr2 == 0) return;
1624
vectptr2->type = 'N';
1625
vectptr2->ptr = (char *)nodehead;
1626
vectptr2->state = simals_trans_state_to_number(simals_instbuf);
1627
vectptr2->strength = strength;
1628
vectptr2->priority = 1;
1629
vectptr2->time = atof(&(simals_instbuf[simals_instptr[1]]));
1630
vectptr2->right = 0;
1631
*vectptr1 = (char*) vectptr2;
1632
vectptr1 = (char**) &(vectptr2->right);
1636
if (! strcmp(simals_instbuf, "SET"))
1638
simals_convert_to_upper(&(simals_instbuf[simals_instptr[1]]));
1639
nodehead = simals_find_node(&(simals_instbuf[simals_instptr[1]]));
1642
ttyputerr(_("ERROR: Unable to find node %s"),
1643
&(simals_instbuf[simals_instptr[1]]));
1648
sethead = simals_alloc_link_mem();
1649
if (sethead == 0) return;
1650
sethead->type = 'N';
1651
sethead->ptr = (char *) nodehead;
1652
sethead->state = simals_trans_state_to_number(&(simals_instbuf[simals_instptr[2]]));
1653
sethead->strength = atoi(&(simals_instbuf[simals_instptr[3]]))*2;
1654
sethead->priority = 2;
1655
sethead->time = atof(&(simals_instbuf[simals_instptr[5]]));
1657
simals_insert_set_list(sethead);
1664
if (namesamen(pt, "new", l) == 0)
1666
/* clear all vectors */
1667
simals_clearallvectors(FALSE);
1668
(void)simals_initialize_simulator(FALSE);
1672
if (namesamen(pt, "save", l) == 0)
1677
(void)formatinfstr("%s.vec", el_curlib->libname);
1678
par[1] = fileselect(_("ALS vector file"), sim_filetypealsvec|FILETYPEWRITE,
1680
if (par[1] == 0) return;
1682
vout = xcreate(par[1], sim_filetypealsvec, 0, &truename);
1685
if (truename != 0) ttyputerr(_("ERROR: Can't create %s"), truename);
1689
for (sethead = simals_setroot; sethead; sethead = sethead->right)
1691
switch (sethead->type)
1694
clokhead = (ROWPTR)sethead->ptr;
1695
vecthead = (LINKPTR)clokhead->inptr;
1696
simals_compute_node_name((NODEPTR)vecthead->ptr, s1);
1697
xprintf(vout, "CLOCK %s D=%g L=%g E=%g ", s1, clokhead->delta,
1698
clokhead->linear, clokhead->exp);
1699
xprintf(vout, "STRENGTH=%d TIME=%g CYCLES=%ld\n", vecthead->strength/2,
1700
sethead->time, sethead->state);
1701
for (; vecthead; vecthead = vecthead->right)
1703
simals_trans_number_to_state(vecthead->state, s2);
1704
xprintf(vout, " %s %g\n", s2, vecthead->time);
1708
simals_compute_node_name((NODEPTR)sethead->ptr, s1);
1709
simals_trans_number_to_state(sethead->state, s2);
1710
xprintf(vout, "SET %s=%s@%d TIME=%g\n", s1, s2, sethead->strength/2,
1718
if (namesamen(pt, "delete", l) == 0)
1722
ttyputusage("telltool simulation als vector delete NODE OPTIONS");
1725
simals_convert_to_upper(par[1]);
1726
nodehead = simals_find_node(par[1]);
1729
ttyputerr(_("ERROR: Unable to find node %s"), par[1]);
1733
backptr = (char**) &simals_setroot;
1734
sethead = simals_setroot;
1736
if (par[2][0] == 'a')
1740
if (sethead->type == 'C')
1742
clokhead = (ROWPTR)sethead->ptr;
1743
vecthead = (LINKPTR)clokhead->inptr;
1744
if ((NODEPTR)vecthead->ptr == nodehead)
1746
*backptr = (char *)sethead->right;
1747
simals_free_link_mem(sethead);
1748
sethead = (LINKPTR)*backptr;
1749
efree((char *)clokhead);
1750
for (; vecthead; vecthead = nextvec)
1752
nextvec = vecthead->right;
1753
simals_free_link_mem(vecthead);
1759
if ((NODEPTR)sethead->ptr == nodehead)
1761
*backptr = (char *)sethead->right;
1762
simals_free_link_mem(sethead);
1763
sethead = (LINKPTR)*backptr;
1768
backptr = (char**) &(sethead->right);
1769
sethead = sethead->right;
1771
(void)simals_initialize_simulator(FALSE);
1777
ttyputusage("telltool simulation als vector delete time TIME");
1780
time = atof(par[2]);
1783
if (sethead->time == time)
1785
if (sethead->type == 'C')
1787
clokhead = (ROWPTR)sethead->ptr;
1788
vecthead = (LINKPTR)clokhead->inptr;
1789
if ((NODEPTR)vecthead->ptr == nodehead)
1791
*backptr = (char*)sethead->right;
1792
simals_free_link_mem(sethead);
1793
sethead = (LINKPTR)*backptr;
1794
efree((char *)clokhead);
1795
for (; vecthead; vecthead = nextvec)
1797
nextvec = vecthead->right;
1798
simals_free_link_mem(vecthead);
1800
(void)simals_initialize_simulator(FALSE);
1805
if ((NODEPTR)sethead->ptr == nodehead)
1807
*backptr = (char *)sethead->right;
1808
simals_free_link_mem(sethead);
1809
sethead = (LINKPTR)*backptr;
1810
(void)simals_initialize_simulator(FALSE);
1816
backptr = (char**) &(sethead->right);
1817
sethead = sethead->right;
1822
ttyputbadusage("telltool simulation als vector");
1825
/****************************** ANNOTATE ******************************/
1828
* Name: simals_annotate_command
1831
* Annotate node information onto corresponding schematic.
1833
void simals_annotate_command(INTBIG count, char *par[])
1837
ttyputusage("telltool simulation als annotate [minimum | typical | maximum]");
1841
if (simals_levelptr == 0)
1843
ttyputerr(M_("Must start simulator before annotating delay information"));
1847
if (namesamen(par[0], "min", 3) == 0) simals_sdfdelaytype = DELAY_MIN;
1848
else if (namesamen(par[0], "typ", 3) == 0) simals_sdfdelaytype = DELAY_TYP;
1849
else if (namesamen(par[0], "max", 3) == 0) simals_sdfdelaytype = DELAY_MAX;
1852
ttyputbadusage("telltool simulation als annotate");
1856
simals_sdfannotate(simals_levelptr);
1857
simals_update_netlist();
1858
ttyputmsg(M_("Completed annotation of SDF %s delay values"), par[0]);
1862
* Routine to annotate SDF port delay info onto ALS netlist.
1864
void simals_sdfannotate(CONPTR cellhead)
1870
if (stopping(STOPREASONDISPLAY)) return;
1871
s1 = simals_compute_path_name(cellhead);
1873
ni = simals_getcellinstance(cellhead->model_name, s1);
1874
if (ni != NONODEINST)
1876
simals_sdfportdelay(cellhead, ni, s1);
1879
if (simals_instbuf[simals_instptr[1]] == 'X') return;
1881
for (subcell = cellhead->child; subcell; subcell = subcell->next)
1882
simals_sdfannotate(subcell);
1886
* Routine to get a NODEINST for specified cell instance.
1888
NODEINST *simals_getcellinstance(char *celltype, char *instance)
1893
char *pt, **instlist, *str, tmp[256];
1894
INTBIG i, j, count = 1;
1899
/* count number of hierarchy levels */
1900
(void)sprintf(tmp, "%s", instance);
1901
for (pt = tmp; *pt != 0; pt++) if (*pt == '.') count++;
1903
/* separate out each hiearchy level - skip first level which is the top */
1904
instlist = (char **)emalloc(count * (sizeof(char *)), el_tempcluster);
1906
for (i=0, j=0; i<count; i++)
1908
str = getkeyword(&pt, ".");
1909
if (i >= 2) if (allocstring(&instlist[j++], str, el_tempcluster))
1911
(void)tonextchar(&pt);
1915
if (count == 0) return(NONODEINST);
1917
/* find the NODEINST corresponding to bottom level of hierarchy */
1918
for(i=0; i<count; i++)
1920
for (ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1922
var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, el_node_name_key);
1923
if (var == NOVARIABLE) continue;
1924
if (namesame((char *)var->addr, instlist[i]) != 0) continue;
1928
if (ni == NONODEINST) break;
1929
if (np->primindex != 0) break;
1936
* Routine to extract SDF port delay information and annotate it to ALS netlist.
1938
void simals_sdfportdelay(CONPTR cellhead, NODEINST *ni, char *path)
1942
INTBIG len, i, j, delay;
1945
for (exhead = cellhead->exptr; exhead; exhead = exhead->next)
1947
for (pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1949
if (namesame(pi->proto->protoname, exhead->node_name) == 0)
1951
var = getval((INTBIG)pi, VPORTARCINST, VSTRING|VISARRAY, "SDF_absolute_port_delay");
1952
if (var != NOVARIABLE)
1954
len = getlength(var);
1955
for (i=0; i<len; i++)
1957
if (namesamen(path, ((char **)var->addr)[i], strlen(path)) == 0)
1959
for (j=0; j<12; j++)
1961
delay = simals_getportdelayvalue(((char **)var->addr)[i],
1962
simals_tnames[j], simals_sdfdelaytype);
1963
if (delay != -1) exhead->td[j] = delay; else
1975
* Routine to extract delay value from delay data string.
1977
INTBIG simals_getportdelayvalue(char *datastring, char *transition, DELAY_TYPES delaytype)
1979
char *pt, *ts, **instlist, *str, tmp[256];
1980
INTBIG i, count = 1;
1982
/* count number of parts in data string */
1983
(void)sprintf(tmp, "%s", datastring);
1984
for (pt = tmp; *pt != 0; pt++) if (*pt == ' ') count++;
1986
/* split data string into separate pieces */
1987
instlist = (char **)emalloc(count * (sizeof(char *)), el_tempcluster);
1989
for (i=0; i<count; i++)
1991
str = getkeyword(&pt, " ");
1992
if (allocstring(&instlist[i], str, el_tempcluster)) return(-1);
1995
/* get piece that corresponds to specified transition */
1996
for (i=0; i<count; i++)
1998
if (namesamen(instlist[i], transition, strlen(transition)) == 0)
2000
if (allocstring(&ts, instlist[i], el_tempcluster)) return(-1);
2001
return(simals_getdval(ts, delaytype));
2009
* Routine to get a delay value string from a transition string.
2010
* if tstring is '01(111:222:333)' and delaytype is DELAY_TYP return 222
2012
INTBIG simals_getdval(char *tstring, DELAY_TYPES delaytype)
2014
char *pt, *str, *bs, ts[256], *t1, *t2, *t3;
2015
INTBIG i, start = 0, stop = 0;
2017
bs = str = (char *)emalloc(strlen(tstring), el_tempcluster);
2018
for (pt = tstring; *pt != 0; pt++)
2020
if (*pt == ')') stop++;
2021
if (start && !stop) *str++ = *pt;
2022
if (*pt == '(') start++;
2026
(void)sprintf(ts, "%s", bs);
2028
/* delay string is not a triple, only one delay value implies typical */
2029
if (strstr(ts, ":") == NULL)
2031
if (delaytype == DELAY_TYP) return(atoi(ts));
2038
str = getkeyword(&pt, ":");
2039
if (i == 0) if (allocstring(&t1, str, el_tempcluster)) return(-1);
2040
if (i == 1) if (allocstring(&t2, str, el_tempcluster)) return(-1);
2041
if (i == 2) if (allocstring(&t3, str, el_tempcluster)) return(-1);
2042
(void)tonextchar(&pt);
2058
/****************************** ORDER ******************************/
2061
* Name: simals_order_command
2064
* Save/restore signal trace order for waveform display.
2066
void simals_order_command(INTBIG count, char *par[])
2070
ttyputusage("telltool simulation als order [save | restore]");
2074
if (namesamen(par[0], "sav", 3) == 0) simals_order_save();
2075
else if (namesamen(par[0], "res", 3) == 0)
2079
ttyputusage("telltool simulation als order restore OPTION");
2082
simals_order_restore(par[1]);
2085
ttyputbadusage("telltool simulation als order");
2090
void simals_order_save(void)
2093
BOOLEAN first = FALSE;
2095
NODEPROTO *curfacet;
2097
sim_window_inittraceloop();
2098
while ((tr = sim_window_nexttraceloop()) != 0)
2100
if (!first) (void)initinfstr();
2101
(void)sprintf(str, "%s:", sim_window_gettracename(tr));
2102
(void)addstringtoinfstr(str);
2108
ts = returninfstr();
2109
ts[(strlen(ts)-1)] = 0; /* chop off trailing ":" */
2111
/* save on current facet */
2112
curfacet = getcurfacet();
2113
if (curfacet != NULL) (void)setval((INTBIG)curfacet, VNODEPROTO,
2114
"SIM_als_trace_order", (INTBIG)ts, VSTRING);
2118
void simals_order_restore(char *list)
2120
INTBIG tc = 0, i, found, lines, thispos, pos, fromlib = 0;
2124
NODEPROTO *curfacet;
2125
char *pt, *str, **tl, tmp[256];
2127
if (namesame(list, "fromlib") == 0)
2129
curfacet = getcurfacet();
2130
if (curfacet != NONODEPROTO)
2132
var = getval((INTBIG)curfacet, VNODEPROTO, VSTRING, "SIM_als_trace_order");
2133
if (var != NOVARIABLE)
2135
(void)sprintf(tmp, "%s", (char *)var->addr);
2142
else (void)sprintf(tmp, "%s", list);
2144
/* count number of traces and fill trace list array */
2145
for (pt = tmp; *pt != 0; pt++) if (*pt == ':') tc++;
2146
if (tc == 0) return;
2148
tl = (char **)emalloc(tc * (sizeof(char *)), el_tempcluster);
2150
for (i=0; i<tc; i++)
2152
str = getkeyword(&pt, ":");
2153
(void)allocstring(&tl[i], str, el_tempcluster);
2154
(void)tonextchar(&pt);
2157
/* delete traces not in restored list */
2158
sim_window_cleartracehighlight();
2159
sim_window_inittraceloop();
2160
while ((tr = sim_window_nexttraceloop()) != 0)
2163
for (i=0; i<tc; i++)
2165
if (namesame(sim_window_gettracename(tr), tl[i]) == 0) found++;
2169
thispos = sim_window_gettraceline(tr);
2170
sim_window_inittraceloop2();
2173
trl = sim_window_nexttraceloop2();
2174
if (trl == 0) break;
2175
pos = sim_window_gettraceline(trl);
2176
if (pos > thispos) sim_window_settraceline(trl, pos-1);
2178
lines = sim_window_getlines();
2179
if (lines > 1) sim_window_setlines(lines-1);
2181
/* remove from the simulator's list */
2182
for(i=0; i<simals_levelptr->num_chn; i++)
2184
node = simals_levelptr->display_page[i+1].nodeptr;
2185
if (node == 0) continue;
2186
if (simals_levelptr->display_page[i+1].displayptr == tr)
2188
simals_levelptr->display_page[i+1].displayptr = 0;
2193
/* kill trace, redraw */
2194
sim_window_killtrace(tr);
2198
/* order the traces */
2199
sim_window_setlines(tc);
2200
sim_window_inittraceloop();
2201
while ((tr = sim_window_nexttraceloop()) != 0)
2203
for (i=0; i<tc; i++)
2204
if (namesame(tl[i], sim_window_gettracename(tr)) == 0) break;
2205
if (fromlib) sim_window_settraceline(tr, tc-i-1); else /* order from library save is bottom to top */
2206
sim_window_settraceline(tr, i);
2209
sim_window_redraw();
2213
* Update the flattened netlist with the annotated delay values.
2215
void simals_update_netlist(void)
2221
INTBIG delay, max_delay;
2223
for (primhead = simals_primroot; primhead; primhead = primhead->next)
2225
switch(primhead->type)
2231
/* cycle through all entries in table */
2232
for (rowhead = (ROWPTR)primhead->ptr; rowhead; rowhead=rowhead->next)
2234
/* check for valid delay transition name for current entry */
2235
if (strcmp(rowhead->delay, "XX"))
2237
/* TESTING - get the max delay value of all input ports matching transition */
2238
cellhead = simals_find_level(simals_parent_level(primhead->level));
2240
for (exhead = cellhead->exptr; exhead; exhead = exhead->next)
2242
delay = exhead->td[simals_get_tdindex(rowhead->delay)];
2243
if (max_delay < delay) max_delay = delay;
2247
rowhead->abs = (float)max_delay * 1.0e-12f;
2249
ttyputmsg(M_("*** DEBUG *** gate: %s, level: %s, delay: %g(%s)"),
2250
primhead->name, primhead->level, (float)max_delay * 1.0e-12, rowhead->delay);
2251
ttyputmsg(M_(" Timing: D=%g, L=%g, E=%g, R=%g, A=%g"),
2252
rowhead->delta, rowhead->linear, rowhead->exp, rowhead->random, rowhead->abs);
2253
simals_print_in_entry(rowhead);
2254
simals_print_out_entry(rowhead);
2260
ttyputerr(M_("Illegal primitive type '%c', database is bad"), primhead->type);
2267
* Return index for transition delays given text name.
2269
INTBIG simals_get_tdindex(char *name)
2273
for (i=0; i<12; i++)
2275
if (!strcmp(simals_tnames[i], name)) return(i);
2277
return(0); /* return '01' index */
2281
* Return the parent level of the given child.
2282
* if .TOP.NODE3.G1 is child, .TOP.NODE3 is parent
2284
char *simals_parent_level(char *child)
2286
char tmp[256], *pt, *str, **instlist;
2287
INTBIG i, count = 1;
2289
(void)sprintf(tmp, "%s", child);
2290
for (pt = tmp; *pt != 0; pt++) if (*pt == '.') count++;
2292
/* separate out each hiearchy level */
2293
instlist = (char **)emalloc(count * (sizeof(char *)), el_tempcluster);
2295
for (i=0; i<count; i++)
2297
str = getkeyword(&pt, ".");
2298
(void)allocstring(&instlist[i], str, el_tempcluster);
2299
(void)tonextchar(&pt);
2302
/* create the parent level name */
2304
for (i=0; i<count-1; i++)
2306
(void)addstringtoinfstr(instlist[i]);
2307
if (i != (count - 2)) (void)addstringtoinfstr(".");
2310
return(returninfstr());
2313
#endif /* SIMTOOL - at top */