Add default zero delay models d0_gate, d0_eff, d0_gff, d0_tgate. Use tprintf.

This commit is contained in:
Brian Taylor 2022-04-29 21:12:05 -07:00 committed by Holger Vogt
parent 5b332a1aba
commit 3e86af3989
1 changed files with 260 additions and 196 deletions

View File

@ -1,6 +1,7 @@
/* udevices.c translate PSPICE U* instances and timing models */ /* udevices.c translate PSPICE U* instances and timing models */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <assert.h> #include <assert.h>
@ -8,6 +9,7 @@
#include "ngspice/memory.h" #include "ngspice/memory.h"
#include "ngspice/bool.h" #include "ngspice/bool.h"
#include "ngspice/stringskip.h" #include "ngspice/stringskip.h"
#include "ngspice/stringutil.h"
#include "ngspice/udevices.h" #include "ngspice/udevices.h"
/* /*
TODO check for name collisions with new names TODO check for name collisions with new names
@ -16,8 +18,6 @@
TODO investigate the method for generating model names TODO investigate the method for generating model names
*/ */
#define BUFSIZE 2048
#define SMBUFSIZE 256
/* #define TRACE */ /* #define TRACE */
/* device types */ /* device types */
@ -254,7 +254,11 @@ static char *find_xspice_for_delay(char *itype)
return NULL; return NULL;
} }
/* Xlator and Xlate */ /*
Xlator and Xlate
Xlate struct data is stored in an Xlatorp list struct
Used to save translated instance and model statements
*/
static void delete_xlate(Xlatep p) static void delete_xlate(Xlatep p)
{ {
if (p) { if (p) {
@ -426,16 +430,34 @@ static void interpret_xlator(Xlatorp xp, BOOL brief)
/* static Xlatorp for collecting timing model delays */ /* static Xlatorp for collecting timing model delays */
static Xlatorp model_xlatorp = NULL; static Xlatorp model_xlatorp = NULL;
static Xlatorp default_models = NULL;
void create_model_xlator(void) void create_model_xlator(void)
{ {
Xlatep xdata;
model_xlatorp = create_xlator(); model_xlatorp = create_xlator();
default_models = create_xlator();
/* .model d0_gate ugate () */
xdata = create_xlate("", "", "ugate", "", "d0_gate", "");
(void) add_xlator(default_models, xdata);
/* .model d0_gff ugff () */
xdata = create_xlate("", "", "ugff", "", "d0_gff", "");
(void) add_xlator(default_models, xdata);
/* .model d0_eff ueff () */
xdata = create_xlate("", "", "ueff", "", "d0_eff", "");
(void) add_xlator(default_models, xdata);
/* .model d0_tgate utgate () */
xdata = create_xlate("", "", "utgate", "", "d0_tgate", "");
(void) add_xlator(default_models, xdata);
} }
void cleanup_model_xlator(void) void cleanup_model_xlator(void)
{ {
delete_xlator(model_xlatorp); delete_xlator(model_xlatorp);
model_xlatorp = NULL; model_xlatorp = NULL;
delete_xlator(default_models);
default_models = NULL;
} }
static Xlatep create_xlate_model(char *delays, static Xlatep create_xlate_model(char *delays,
@ -444,14 +466,13 @@ static Xlatep create_xlate_model(char *delays,
return create_xlate("", delays, utype, xspice, tmodel, ""); return create_xlate("", delays, utype, xspice, tmodel, "");
} }
static Xlatep find_in_model_xlator(Xlatep x) static Xlatep find_in_xlator(Xlatep x, Xlatorp xlp)
{ {
Xlatep x1; Xlatep x1;
if (!x) { return NULL; } if (!x) { return NULL; }
if (!model_xlatorp) { return NULL; } if (!xlp) { return NULL; }
for (x1 = first_xlator(model_xlatorp); x1; for (x1 = first_xlator(xlp); x1; x1 = next_xlator(xlp)) {
x1 = next_xlator(model_xlatorp)) {
if (strcmp(x1->tmodel, x->tmodel) == 0 && if (strcmp(x1->tmodel, x->tmodel) == 0 &&
strcmp(x1->utype, x->utype) == 0) { strcmp(x1->utype, x->utype) == 0) {
if (strcmp(x1->xspice, x->xspice) == 0) { if (strcmp(x1->xspice, x->xspice) == 0) {
@ -461,6 +482,15 @@ static Xlatep find_in_model_xlator(Xlatep x)
} }
return NULL; return NULL;
} }
static Xlatep find_in_model_xlator(Xlatep x)
{
Xlatep x1;
x1 = find_in_xlator(x, model_xlatorp);
if (x1) { return x1; }
x1 = find_in_xlator(x, default_models);
return x1;
}
static void add_delays_to_model_xlator(char *delays, static void add_delays_to_model_xlator(char *delays,
char *utype, char *xspice, char *tmodel) char *utype, char *xspice, char *tmodel)
@ -475,8 +505,10 @@ static void add_delays_to_model_xlator(char *delays,
x = create_xlate_model(delays, utype, xspice, tmodel); x = create_xlate_model(delays, utype, xspice, tmodel);
x1 = find_in_model_xlator(x); x1 = find_in_model_xlator(x);
if (x1) { if (x1) {
/*
printf("Already found timing model %s utype %s\n", printf("Already found timing model %s utype %s\n",
x1->tmodel, x1->utype); x1->tmodel, x1->utype);
*/
delete_xlate(x); delete_xlate(x);
return; return;
} }
@ -919,23 +951,17 @@ char *new_inverter(char *iname, char *node, Xlatorp xlp)
/* Return the name of the output of the new inverter */ /* Return the name of the output of the new inverter */
/* tfree the returned string after it has been used ny the caller */ /* tfree the returned string after it has been used ny the caller */
char *tmp = NULL; char *tmp = NULL;
size_t sz;
Xlatep xdata = NULL; Xlatep xdata = NULL;
sz = 2*strlen(iname) + 3*strlen(node) + strlen("d_zero_inv99"); tmp = tprintf("a%s_%s %s not_%s_%s d_zero_inv99",
sz += 100; /* that should be enough */ iname, node, node, iname, node);
tmp = TMALLOC(char, sz);
tmp[0] = '\0';
sprintf(tmp, "a%s_%s %s", iname, node, node);
sprintf(tmp + strlen(tmp), " not_%s_%s", iname, node);
sprintf(tmp + strlen(tmp), " d_zero_inv99");
/* instantiate the new inverter */ /* instantiate the new inverter */
/* e.g. au5_s1bar s1bar not_u5_s1bar d_zero_inv99 */ /* e.g. au5_s1bar s1bar not_u5_s1bar d_zero_inv99 */
xdata = create_xlate_translated(tmp); xdata = create_xlate_translated(tmp);
(void) add_xlator(xlp, xdata); (void) add_xlator(xlp, xdata);
tmp[0] = '\0'; tfree(tmp);
/* the name of the inverter output */ /* the name of the inverter output */
sprintf(tmp, "not_%s_%s", iname, node); tmp = tprintf("not_%s_%s", iname, node);
return tmp; return tmp;
} }
@ -951,10 +977,9 @@ static BOOL gen_timing_model(
xspice instance and model lines (not to be confused with model_xlatorp. xspice instance and model lines (not to be confused with model_xlatorp.
*/ */
Xlatep xin = NULL, xout = NULL, newdata; Xlatep xin = NULL, xout = NULL, newdata;
char work[BUFSIZE]; char *s1;
BOOL retval; BOOL retval;
printf("Need model %s %s for %s\n", tmodel, xspice, newname);
if (strcmp(utype, "ugff") == 0) { if (strcmp(utype, "ugff") == 0) {
xin = create_xlate_model("", utype, xspice, tmodel); xin = create_xlate_model("", utype, xspice, tmodel);
} else { } else {
@ -963,14 +988,14 @@ static BOOL gen_timing_model(
xout = find_in_model_xlator(xin); xout = find_in_model_xlator(xin);
if (xout) { if (xout) {
/* Don't delete xout or the model_xlatorp will be corrupted */ /* Don't delete xout or the model_xlatorp will be corrupted */
//printf("Found tming model %s %s\n", xout->tmodel, xout->utype);
print_xlate(xout); print_xlate(xout);
work[0] = '\0';
sprintf(work, ".model %s %s", newname, xspice);
if (xout->delays && strlen(xout->delays) > 0) { if (xout->delays && strlen(xout->delays) > 0) {
sprintf(work + strlen(work), "%s", xout->delays); s1 = tprintf(".model %s %s%s", newname, xspice, xout->delays);
} else {
s1 = tprintf(".model %s %s", newname, xspice);
} }
newdata = create_xlate_translated(work); newdata = create_xlate_translated(s1);
tfree(s1);
(void) add_xlator(xlp, newdata); (void) add_xlator(xlp, newdata);
retval = TRUE; retval = TRUE;
} else { } else {
@ -986,8 +1011,7 @@ static Xlatorp gen_dff_instance(struct dff_instance *ip)
char *itype, *iname, **darr, **qarr, **qbarr; char *itype, *iname, **darr, **qarr, **qbarr;
char *preb, *clrb, *clk, *tmodel, *qout, *qbout; char *preb, *clrb, *clk, *tmodel, *qout, *qbout;
int i, num_gates; int i, num_gates;
char work[BUFSIZE]; char *modelnm, *s1;
char smallbuf[SMBUFSIZE];
Xlatorp xxp = NULL; Xlatorp xxp = NULL;
Xlatep xdata = NULL; Xlatep xdata = NULL;
BOOL need_preb_inv = FALSE, need_clrb_inv = FALSE; BOOL need_preb_inv = FALSE, need_clrb_inv = FALSE;
@ -1019,31 +1043,27 @@ static Xlatorp gen_dff_instance(struct dff_instance *ip)
clk = ip->clk; clk = ip->clk;
tmodel = ip->tmodel; tmodel = ip->tmodel;
smallbuf[0] = '\0';
/* model name, same for each dff */ /* model name, same for each dff */
sprintf(smallbuf, "d_a%s%s", iname, itype); modelnm = tprintf("d_a%s%s", iname, itype);
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
work[0] = '\0';
sprintf(work, "a%s_%d", iname, i);
sprintf(work + strlen(work), " %s %s %s %s",
darr[i], clk, preb, clrb);
qout = qarr[i]; qout = qarr[i];
if (strcmp(qout, "$d_nc") == 0) { if (strcmp(qout, "$d_nc") == 0) {
qout = "NULL"; qout = "NULL";
} }
sprintf(work + strlen(work), " %s", qout);
qbout = qbarr[i]; qbout = qbarr[i];
if (strcmp(qbout, "$d_nc") == 0) { if (strcmp(qbout, "$d_nc") == 0) {
qbout = "NULL"; qbout = "NULL";
} }
sprintf(work + strlen(work), " %s", qbout); s1 = tprintf( "a%s_%d %s %s %s %s %s %s %s",
sprintf(work + strlen(work), " %s", smallbuf); iname, i, darr[i], clk, preb, clrb, qout, qbout, modelnm
xdata = create_xlate_instance(work, " d_dff", tmodel, smallbuf); );
xdata = create_xlate_instance(s1, " d_dff", tmodel, modelnm);
xxp = add_xlator(xxp, xdata); xxp = add_xlator(xxp, xdata);
tfree(s1);
} }
if (!gen_timing_model(tmodel, "ueff", "d_dff", smallbuf, xxp)) { if (!gen_timing_model(tmodel, "ueff", "d_dff", modelnm, xxp)) {
printf("WARNING unable to find tmodel %s for %s d_dff\n", printf("WARNING unable to find tmodel %s for %s d_dff\n",
tmodel, smallbuf); tmodel, modelnm);
} }
if (need_preb_inv || need_clrb_inv) { if (need_preb_inv || need_clrb_inv) {
xdata = create_xlate_translated(".model d_zero_inv99 d_inverter"); xdata = create_xlate_translated(".model d_zero_inv99 d_inverter");
@ -1051,6 +1071,7 @@ static Xlatorp gen_dff_instance(struct dff_instance *ip)
} }
if (need_preb_inv) { tfree(preb); } if (need_preb_inv) { tfree(preb); }
if (need_clrb_inv) { tfree(clrb); } if (need_clrb_inv) { tfree(clrb); }
tfree(modelnm);
return xxp; return xxp;
return NULL; return NULL;
@ -1061,8 +1082,7 @@ static Xlatorp gen_jkff_instance(struct jkff_instance *ip)
char *itype, *iname, **jarr, **karr, **qarr, **qbarr; char *itype, *iname, **jarr, **karr, **qarr, **qbarr;
char *preb, *clrb, *clkb, *tmodel, *qout, *qbout; char *preb, *clrb, *clkb, *tmodel, *qout, *qbout;
int i, num_gates; int i, num_gates;
char work[BUFSIZE]; char *modelnm, *s1;
char smallbuf[SMBUFSIZE];
Xlatorp xxp = NULL; Xlatorp xxp = NULL;
Xlatep xdata = NULL; Xlatep xdata = NULL;
BOOL need_preb_inv = FALSE, need_clrb_inv = FALSE; BOOL need_preb_inv = FALSE, need_clrb_inv = FALSE;
@ -1098,39 +1118,36 @@ static Xlatorp gen_jkff_instance(struct jkff_instance *ip)
clkb = new_inverter(iname, clkb, xxp); clkb = new_inverter(iname, clkb, xxp);
tmodel = ip->tmodel; tmodel = ip->tmodel;
smallbuf[0] = '\0';
/* model name, same for each latch */ /* model name, same for each latch */
sprintf(smallbuf, "d_a%s%s", iname, itype); modelnm = tprintf("d_a%s%s", iname, itype);
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
work[0] = '\0';
sprintf(work, "a%s_%d", iname, i);
sprintf(work + strlen(work), " %s %s %s %s %s",
jarr[i], karr[i], clkb, preb, clrb);
qout = qarr[i]; qout = qarr[i];
if (strcmp(qout, "$d_nc") == 0) { if (strcmp(qout, "$d_nc") == 0) {
qout = "NULL"; qout = "NULL";
} }
sprintf(work + strlen(work), " %s", qout);
qbout = qbarr[i]; qbout = qbarr[i];
if (strcmp(qbout, "$d_nc") == 0) { if (strcmp(qbout, "$d_nc") == 0) {
qbout = "NULL"; qbout = "NULL";
} }
sprintf(work + strlen(work), " %s %s", qbout, smallbuf); s1 = tprintf("a%s_%d %s %s %s %s %s %s %s %s",
xdata = create_xlate_instance(work, " d_jkff", tmodel, smallbuf); iname, i, jarr[i], karr[i], clkb, preb, clrb, qout, qbout, modelnm
);
xdata = create_xlate_instance(s1, " d_jkff", tmodel, modelnm);
xxp = add_xlator(xxp, xdata); xxp = add_xlator(xxp, xdata);
tfree(s1);
} }
if (!gen_timing_model(tmodel, "ueff", "d_jkff", smallbuf, xxp)) { if (!gen_timing_model(tmodel, "ueff", "d_jkff", modelnm, xxp)) {
printf("WARNING unable to find tmodel %s for %s d_jkff\n", printf("WARNING unable to find tmodel %s for %s d_jkff\n",
tmodel, smallbuf); tmodel, modelnm);
} }
xdata = create_xlate_translated(".model d_zero_inv99 d_inverter"); xdata = create_xlate_translated(".model d_zero_inv99 d_inverter");
xxp = add_xlator(xxp, xdata); xxp = add_xlator(xxp, xdata);
tfree(clkb); tfree(clkb);
if (need_preb_inv) { tfree(preb); } if (need_preb_inv) { tfree(preb); }
if (need_clrb_inv) { tfree(clrb); } if (need_clrb_inv) { tfree(clrb); }
tfree(modelnm);
return xxp; return xxp;
return NULL;
} }
static Xlatorp gen_dltch_instance(struct dltch_instance *ip) static Xlatorp gen_dltch_instance(struct dltch_instance *ip)
@ -1138,8 +1155,7 @@ static Xlatorp gen_dltch_instance(struct dltch_instance *ip)
char *itype, *iname, **darr, **qarr, **qbarr; char *itype, *iname, **darr, **qarr, **qbarr;
char *preb, *clrb, *gate, *tmodel, *qout, *qbout; char *preb, *clrb, *gate, *tmodel, *qout, *qbout;
int i, num_gates; int i, num_gates;
char work[BUFSIZE]; char *modelnm, *s1, *s2, *s3;
char smallbuf[SMBUFSIZE];
Xlatorp xxp = NULL; Xlatorp xxp = NULL;
Xlatep xdata = NULL; Xlatep xdata = NULL;
BOOL need_preb_inv = FALSE, need_clrb_inv = FALSE; BOOL need_preb_inv = FALSE, need_clrb_inv = FALSE;
@ -1169,35 +1185,35 @@ static Xlatorp gen_dltch_instance(struct dltch_instance *ip)
} }
gate = ip->gate; gate = ip->gate;
tmodel = ip->tmodel; tmodel = ip->tmodel;
smallbuf[0] = '\0';
/* model name, same for each latch */ /* model name, same for each latch */
sprintf(smallbuf, "d_a%s%s", iname, itype); modelnm = tprintf("d_a%s%s", iname, itype);
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
work[0] = '\0';
sprintf(work, "a%s_%d", iname, i);
sprintf(work + strlen(work), " %s %s %s %s",
darr[i], gate, preb, clrb);
qout = qarr[i]; qout = qarr[i];
if (strcmp(qout, "$d_nc") == 0) { if (strcmp(qout, "$d_nc") == 0) {
/* NULL not allowed??? */ /* NULL not allowed??? */
sprintf(work + strlen(work), " nco%s_%d", iname, i); s1 = tprintf("a%s_%d %s %s %s %s nco%s_%d",
iname, i, darr[i], gate, preb, clrb, iname, i);
} else { } else {
sprintf(work + strlen(work), " %s", qout); s1 = tprintf("a%s_%d %s %s %s %s %s",
iname, i, darr[i], gate, preb, clrb, qout);
} }
qbout = qbarr[i]; qbout = qbarr[i];
if (strcmp(qbout, "$d_nc") == 0) { if (strcmp(qbout, "$d_nc") == 0) {
/* NULL not allowed??? */ /* NULL not allowed??? */
sprintf(work + strlen(work), " ncn%s_%d", iname, i); s2 = tprintf(" ncn%s_%d %s", iname, i, modelnm);
} else { } else {
sprintf(work + strlen(work), " %s", qbout); s2 = tprintf(" %s %s", qbout, modelnm);
} }
sprintf(work + strlen(work), " %s", smallbuf); s3 = tprintf("%s%s", s1, s2);
xdata = create_xlate_instance(work, " d_dlatch", tmodel, smallbuf); xdata = create_xlate_instance(s3, " d_dlatch", tmodel, modelnm);
xxp = add_xlator(xxp, xdata); xxp = add_xlator(xxp, xdata);
tfree(s1);
tfree(s2);
tfree(s3);
} }
if (!gen_timing_model(tmodel, "ugff", "d_dlatch", smallbuf, xxp)) { if (!gen_timing_model(tmodel, "ugff", "d_dlatch", modelnm, xxp)) {
printf("WARNING unable to find tmodel %s for %s d_dlatch\n", printf("WARNING unable to find tmodel %s for %s d_dlatch\n",
tmodel, smallbuf); tmodel, modelnm);
} }
if (need_preb_inv || need_clrb_inv) { if (need_preb_inv || need_clrb_inv) {
xdata = create_xlate_translated(".model d_zero_inv99 d_inverter"); xdata = create_xlate_translated(".model d_zero_inv99 d_inverter");
@ -1205,6 +1221,7 @@ static Xlatorp gen_dltch_instance(struct dltch_instance *ip)
} }
if (need_preb_inv) { tfree(preb); } if (need_preb_inv) { tfree(preb); }
if (need_clrb_inv) { tfree(clrb); } if (need_clrb_inv) { tfree(clrb); }
tfree(modelnm);
return xxp; return xxp;
} }
@ -1212,18 +1229,18 @@ static Xlatorp gen_dltch_instance(struct dltch_instance *ip)
static Xlatorp gen_gate_instance(struct gate_instance *gip) static Xlatorp gen_gate_instance(struct gate_instance *gip)
{ {
char **inarr, **outarr, *itype, *iname, *enable, *tmodel; char **inarr, **outarr, *itype, *iname, *enable, *tmodel;
char *work, *xspice = NULL, *connector = NULL; char *xspice = NULL, *connector = NULL;
BOOL vector = FALSE, tristate_gate = FALSE, simple_gate = FALSE; BOOL vector = FALSE, tristate_gate = FALSE, simple_gate = FALSE;
BOOL tristate_array = FALSE, simple_array = FALSE; BOOL tristate_array = FALSE, simple_array = FALSE;
BOOL add_tristate = FALSE; BOOL add_tristate = FALSE;
char smallbuf[SMBUFSIZE], modelbuf[SMBUFSIZE]; char *modelnm = NULL, *startvec = NULL, *endvec = NULL;
char *input_buf = NULL;
int i, j, k, width, num_gates, num_ins, num_outs; int i, j, k, width, num_gates, num_ins, num_outs;
size_t sz; size_t sz;
Xlatorp xxp = NULL; Xlatorp xxp = NULL;
Xlatep xdata = NULL; Xlatep xdata = NULL;
if (!gip) { return NULL; } if (!gip) { return NULL; }
smallbuf[0] = '\0';
itype = gip->hdrp->instance_type; itype = gip->hdrp->instance_type;
iname = gip->hdrp->instance_name; iname = gip->hdrp->instance_name;
inarr = gip->inputs; inarr = gip->inputs;
@ -1238,6 +1255,7 @@ static Xlatorp gen_gate_instance(struct gate_instance *gip)
vector = has_vector_inputs(itype); vector = has_vector_inputs(itype);
if (num_gates == 1) { if (num_gates == 1) {
char *inst_begin = NULL;
assert(num_outs == 1); assert(num_outs == 1);
simple_gate = is_gate(itype); simple_gate = is_gate(itype);
tristate_gate = is_tristate(itype); tristate_gate = is_tristate(itype);
@ -1256,53 +1274,76 @@ static Xlatorp gen_gate_instance(struct gate_instance *gip)
} }
assert(xspice); assert(xspice);
xxp = create_xlator(); xxp = create_xlator();
work = TMALLOC(char, BUFSIZE);
work[0] = '\0';
/* Now build the instance name and inputs section */ /* Now build the instance name and inputs section */
/* instance name */ if (vector) {
sprintf(work, "a%s ", iname); startvec = "[";
if (vector) { strcat(work, "["); } endvec = " ]";
/* inputs */ } else {
for (i = 0; i < width; i++) { startvec = "";
sprintf(work + strlen(work), " %s", inarr[i]); endvec = "";
} }
if (vector) { strcat(work, " ]"); } /* inputs */
/* First calculate the space */
sz = 0;
for (i = 0; i < width; i++) {
sz += strlen(inarr[i]) + 4; // Extra 4 spaces separating
}
input_buf = TMALLOC(char, sz);
input_buf[0] = '\0';
for (i = 0; i < width; i++) {
sprintf(input_buf + strlen(input_buf), " %s", inarr[i]);
}
/* instance name and inputs */
/* add the tristate enable if required on original */ /* add the tristate enable if required on original */
if (enable) { if (enable) {
assert(tristate_gate); assert(tristate_gate);
if (!add_tristate) { if (!add_tristate) {
sprintf(work + strlen(work)," %s", enable); /* Warning: changing the format string affects input_buf sz */
inst_begin = tprintf("a%s %s%s%s %s",
iname, startvec, input_buf, endvec, enable);
} else {
/* Warning: changing the format string affects input_buf sz */
inst_begin = tprintf("a%s %s%s%s",
iname, startvec, input_buf, endvec);
} }
} else {
/* Warning: changing the format string affects input_buf sz */
inst_begin = tprintf("a%s %s%s%s",
iname, startvec, input_buf, endvec);
} }
tfree(input_buf);
/* connector if required for tristate */ /* connector if required for tristate */
sprintf(smallbuf, "a%s_%s", iname, outarr[0]); connector = tprintf("a%s_%s", iname, outarr[0]);
connector = TMALLOC(char, strlen(smallbuf) + 1);
connector[0] = '\0';
(void) memcpy(connector, smallbuf, strlen(smallbuf) + 1);
/* keep a copy of the model name of original gate */ /* keep a copy of the model name of original gate */
modelbuf[0] = '\0'; modelnm = tprintf("d_a%s%s", iname, itype);
sprintf(modelbuf, "d_a%s%s", iname, itype);
if (!add_tristate) { if (!add_tristate) {
char *instance_stmt = NULL;
/* add output + model name => translated instance */ /* add output + model name => translated instance */
sprintf(work + strlen(work), " %s %s", outarr[0], modelbuf); instance_stmt = tprintf("%s %s %s",
xdata = create_xlate_instance(work, xspice, tmodel, modelbuf); inst_begin, outarr[0], modelnm);
xdata = create_xlate_instance(instance_stmt,
xspice, tmodel, modelnm);
xxp = add_xlator(xxp, xdata); xxp = add_xlator(xxp, xdata);
tfree(instance_stmt);
if (simple_gate) { if (simple_gate) {
if (!gen_timing_model(tmodel, "ugate", xspice, if (!gen_timing_model(tmodel, "ugate", xspice,
modelbuf, xxp)) { modelnm, xxp)) {
printf("WARNING unable to find tmodel %s for %s %s\n", printf("WARNING unable to find tmodel %s for %s %s\n",
tmodel, modelbuf, xspice); tmodel, modelnm, xspice);
} }
} else { /* must be trstate gate buf3 */ } else { /* must be trstate gate buf3 */
if (!gen_timing_model(tmodel, "utgate", xspice, if (!gen_timing_model(tmodel, "utgate", xspice,
modelbuf, xxp)) { modelnm, xxp)) {
printf("WARNING unable to find tmodel %s for %s %s\n", printf("WARNING unable to find tmodel %s for %s %s\n",
tmodel, modelbuf, xspice); tmodel, modelnm, xspice);
} }
} }
} else { } else {
char *new_model_nm = NULL;
char *new_stmt = NULL;
/* /*
Use connector as original gate output and tristate input; Use connector as original gate output and tristate input;
tristate has original gate output and utgate delay; tristate has original gate output and utgate delay;
@ -1310,34 +1351,39 @@ static Xlatorp gen_gate_instance(struct gate_instance *gip)
Complete the translation of the original gate adding Complete the translation of the original gate adding
the connector as output + model name. the connector as output + model name.
*/ */
sprintf(work + strlen(work), " %s %s", connector, modelbuf); new_stmt = tprintf("%s %s %s", inst_begin, connector, modelnm);
xdata = create_xlate_instance(work, xspice, "", modelbuf); xdata = create_xlate_instance(new_stmt, xspice, "", modelnm);
xxp = add_xlator(xxp, xdata); xxp = add_xlator(xxp, xdata);
tfree(new_stmt);
/* new model statement e.g. .model d_au2nand3 d_nand */ /* new model statement e.g. .model d_au2nand3 d_nand */
work[0] = '\0'; new_stmt = tprintf(".model %s %s", modelnm, xspice);
sprintf(work, ".model %s %s", modelbuf, xspice); xdata = create_xlate_translated(new_stmt);
xdata = create_xlate_translated(work);
xxp = add_xlator(xxp, xdata); xxp = add_xlator(xxp, xdata);
tfree(new_stmt);
/* now the added tristate */ /* now the added tristate */
work[0] = '\0';
modelbuf[0] = '\0';
/* model name of added tristate */ /* model name of added tristate */
sprintf(modelbuf, "d_a%stribuf", iname); new_model_nm = tprintf("d_a%stribuf", iname);
sprintf(work, "a%s_tri %s %s %s %s", iname, connector, new_stmt = tprintf("a%s_tri %s %s %s %s",
enable, outarr[0], modelbuf); iname, connector, enable, outarr[0], new_model_nm);
xdata = create_xlate_instance(work, "d_tristate", tmodel, modelbuf); xdata = create_xlate_instance(new_stmt, "d_tristate",
tmodel, new_model_nm);
xxp = add_xlator(xxp, xdata); xxp = add_xlator(xxp, xdata);
tfree(new_stmt);
if (!gen_timing_model(tmodel, "utgate", "d_tristate", if (!gen_timing_model(tmodel, "utgate", "d_tristate",
modelbuf, xxp)) { new_model_nm, xxp)) {
printf("WARNING unable to find tmodel %s for %s %s\n", printf("WARNING unable to find tmodel %s for %s %s\n",
tmodel, modelbuf, xspice); tmodel, new_model_nm, xspice);
} }
tfree(new_model_nm);
} }
tfree(work);
tfree(connector); tfree(connector);
tfree(modelnm);
tfree(inst_begin);
return xxp; return xxp;
} else { } else {
char *primary_model = NULL, *s1 = NULL, *s2 = NULL, *s3 = NULL;
int ksave;
/* arrays of gates */ /* arrays of gates */
/* NOTE (n)and3a, (n)or3a, (n)xora types are not supported */ /* NOTE (n)and3a, (n)or3a, (n)xora types are not supported */
assert(num_outs == num_gates); assert(num_outs == num_gates);
@ -1363,104 +1409,122 @@ static Xlatorp gen_gate_instance(struct gate_instance *gip)
} }
assert(xspice); assert(xspice);
xxp = create_xlator(); xxp = create_xlator();
sz = BUFSIZE;
work = TMALLOC(char, sz);
k = 0; k = 0;
connector = NULL; connector = NULL;
if (vector) {
startvec = "[";
endvec = " ]";
} else {
startvec = "";
endvec = "";
}
/* model name, same for all primary gates */ /* model name, same for all primary gates */
modelbuf[0] = '\0'; primary_model = tprintf("d_a%s%s", iname, itype);
sprintf(modelbuf, "d_a%s%s", iname, itype);
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
work[0] = '\0'; /* inputs */
/* create new instance name for primary gate */ /* First calculate the space */
sprintf(work, "a%s_%d ", iname, i); ksave = k;
if (vector) { strcat(work, "["); } sz = 0;
for (j = 0; j < width; j++) { for (j = 0; j < width; j++) {
/* inputs for primary gate */ /* inputs for primary gate */
sprintf(work + strlen(work), " %s", inarr[k]); sz += strlen(inarr[k]) + 4; // Extra 4 spaces separating
k++; k++;
} }
if (vector) { strcat(work, " ]"); } k = ksave;
input_buf = TMALLOC(char, sz);
input_buf[0] = '\0';
for (j = 0; j < width; j++) {
/* inputs for primary gate */
/* Warning: changing the format string affects input_buf sz */
sprintf(input_buf + strlen(input_buf), " %s", inarr[k]);
k++;
}
/* create new instance name for primary gate */
if (enable) { if (enable) {
if (!add_tristate) { if (!add_tristate) {
sprintf(work + strlen(work)," %s", enable); s1 = tprintf("a%s_%d %s%s%s %s",
iname, i, startvec, input_buf, endvec, enable);
} else { } else {
s1 = tprintf("a%s_%d %s%s%s",
iname, i, startvec, input_buf, endvec);
/* connector if required for tristate */ /* connector if required for tristate */
sprintf(smallbuf, "a%s_%d_%s", iname, i, outarr[i]); connector = tprintf("a%s_%d_%s", iname, i, outarr[i]);
connector = TMALLOC(char, strlen(smallbuf) + 1);
connector[0] = '\0';
(void) memcpy(connector, smallbuf, strlen(smallbuf) + 1);
} }
} else {
s1 = tprintf("a%s_%d %s%s%s",
iname, i, startvec, input_buf, endvec);
} }
tfree(input_buf);
/* output of primary gate */ /* output of primary gate */
if (add_tristate) { if (add_tristate) {
sprintf(work + strlen(work), " %s", connector); s2 = tprintf(" %s %s", connector, primary_model);
} else { } else {
sprintf(work + strlen(work), " %s", outarr[i]); s2 = tprintf(" %s %s", outarr[i], primary_model);
} }
/* translated instance */ /* translated instance */
sprintf(work + strlen(work), " %s", modelbuf); s3 = tprintf("%s%s", s1, s2);
if (add_tristate) { if (add_tristate) {
xdata = create_xlate_instance(work, xspice, "", modelbuf); xdata = create_xlate_instance(s3, xspice, "", primary_model);
xxp = add_xlator(xxp, xdata); xxp = add_xlator(xxp, xdata);
} else { } else {
xdata = create_xlate_instance(work, xspice, tmodel, modelbuf); xdata = create_xlate_instance(s3, xspice, tmodel,
primary_model);
xxp = add_xlator(xxp, xdata); xxp = add_xlator(xxp, xdata);
}
tfree(s1);
tfree(s2);
tfree(s3);
if (!add_tristate) {
if (tristate_array) { if (tristate_array) {
assert(strcmp(xspice, "d_tristate") == 0); assert(strcmp(xspice, "d_tristate") == 0);
assert(strcmp(itype, "buf3a") == 0); assert(strcmp(itype, "buf3a") == 0);
if (i == 0 && !gen_timing_model(tmodel, "utgate", if (i == 0 && !gen_timing_model(tmodel, "utgate",
xspice, modelbuf, xxp)) { xspice, primary_model, xxp)) {
printf("WARNING unable to find tmodel %s for %s %s\n", printf("WARNING unable to find tmodel %s for %s %s\n",
tmodel, modelbuf, xspice); tmodel, primary_model, xspice);
} }
} else { } else {
if (i == 0 && !gen_timing_model(tmodel, "ugate", if (i == 0 && !gen_timing_model(tmodel, "ugate",
xspice, modelbuf, xxp)) { xspice, primary_model, xxp)) {
printf("WARNING unable to find tmodel %s for %s %s\n", printf("WARNING unable to find tmodel %s for %s %s\n",
tmodel, modelbuf, xspice); tmodel, primary_model, xspice);
} }
} }
} }
if (add_tristate) { if (add_tristate) {
char *s1 = NULL, *modelnm = NULL;
if (i == 0) { if (i == 0) {
/* Zero delay model for all original array instances */ /* Zero delay model for all original array instances */
work[0] = '\0'; s1 = tprintf(".model %s %s", primary_model, xspice);
sprintf(work, ".model %s %s", modelbuf, xspice); xdata = create_xlate_translated(s1);
xdata = create_xlate_translated(work);
xxp = add_xlator(xxp, xdata); xxp = add_xlator(xxp, xdata);
tfree(s1);
} }
work[0] = '\0';
smallbuf[0] = '\0';
/* model name of added tristate */ /* model name of added tristate */
sprintf(smallbuf, "d_a%stribuf", iname); modelnm = tprintf("d_a%stribuf", iname);
/* /*
instance name of added tristate, connector, instance name of added tristate, connector,
enable, original primary gate output, timing model. enable, original primary gate output, timing model.
*/ */
sprintf(work, "a%s_%d_tri %s %s %s %s", iname, i, connector, s1 = tprintf("a%s_%d_tri %s %s %s %s", iname, i, connector,
enable, outarr[i], smallbuf); enable, outarr[i], modelnm);
xdata = create_xlate_instance(work, "d_tristate", xdata = create_xlate_instance(s1, "d_tristate",
tmodel, smallbuf); tmodel, modelnm);
xxp = add_xlator(xxp, xdata); xxp = add_xlator(xxp, xdata);
tfree(s1);
if (i == 0 && !gen_timing_model(tmodel, "utgate", if (i == 0 && !gen_timing_model(tmodel, "utgate",
"d_tristate", smallbuf, xxp)) { "d_tristate", modelnm, xxp)) {
printf("WARNING unable to find tmodel %s for %s %s\n", printf("WARNING unable to find tmodel %s for %s %s\n",
tmodel, smallbuf, "d_tristate"); tmodel, modelnm, "d_tristate");
} }
tfree(modelnm);
tfree(connector); tfree(connector);
} }
if (strlen(work) > BUFSIZE/2) {
tfree(work);
sz += BUFSIZE;
printf("TMALLOC work size %lu\n", sz);
work = TMALLOC(char, sz);
}
} }
tfree(work); tfree(primary_model);
return xxp; return xxp;
} }
return NULL; return NULL;
@ -1555,7 +1619,6 @@ static void estimate_typ(struct timing_data *tdp)
char *min, *typ, *max; char *min, *typ, *max;
float valmin, valmax, average; float valmin, valmax, average;
char *units1, *units2; char *units1, *units2;
static char avebuf[SMBUFSIZE];
if (!tdp) { return; } if (!tdp) { return; }
min = tdp->min; min = tdp->min;
@ -1577,12 +1640,10 @@ static void estimate_typ(struct timing_data *tdp)
valmin = strtof(tmpmin, &units1); valmin = strtof(tmpmin, &units1);
valmax = strtof(tmpmax, &units2); valmax = strtof(tmpmax, &units2);
average = (valmin + valmax) / 2.0; average = (valmin + valmax) / 2.0;
sprintf(avebuf, "%.2f%s", average, units2); tdp->ave = tprintf("%.2f%s", average, units2);
if (strcmp(units1, units2) != 0) { if (strcmp(units1, units2) != 0) {
printf("WARNING units do not match\n"); printf("WARNING units do not match\n");
} }
tdp->ave = TMALLOC(char, strlen(avebuf) + 1);
(void) memcpy(tdp->ave, avebuf, strlen(avebuf) + 1);
tdp->estimate = EST_AVE; tdp->estimate = EST_AVE;
return; return;
} }
@ -1618,8 +1679,6 @@ static char *get_estimate(struct timing_data *tdp)
static char *get_delays_ugate(char *rem, char *d_name) static char *get_delays_ugate(char *rem, char *d_name)
{ {
char *rising, *falling, *delays = NULL; char *rising, *falling, *delays = NULL;
int count;
char work_buf[BUFSIZE];
struct timing_data *tdp1, *tdp2; struct timing_data *tdp1, *tdp2;
tdp1 = create_min_typ_max("tplh", rem); tdp1 = create_min_typ_max("tplh", rem);
@ -1630,11 +1689,8 @@ static char *get_delays_ugate(char *rem, char *d_name)
falling = get_estimate(tdp2); falling = get_estimate(tdp2);
if (rising && falling) { if (rising && falling) {
if (strlen(rising) > 0 && strlen(falling) > 0) { if (strlen(rising) > 0 && strlen(falling) > 0) {
count = sprintf(work_buf, "(rise_delay = %s fall_delay = %s)", delays = tprintf("(rise_delay = %s fall_delay = %s)",
rising, falling); rising, falling);
count++;
delays = TMALLOC(char, count);
(void) memcpy(delays, work_buf, count);
} }
} }
delete_timing_data(tdp1); delete_timing_data(tdp1);
@ -1646,8 +1702,6 @@ static char *get_delays_utgate(char *rem, char *d_name)
{ {
/* Return estimate of tristate delay (delay = val3) */ /* Return estimate of tristate delay (delay = val3) */
char *rising, *falling, *delays = NULL; char *rising, *falling, *delays = NULL;
int count;
char work_buf[BUFSIZE];
struct timing_data *tdp1, *tdp2; struct timing_data *tdp1, *tdp2;
tdp1 = create_min_typ_max("tplh", rem); tdp1 = create_min_typ_max("tplh", rem);
@ -1658,10 +1712,7 @@ static char *get_delays_utgate(char *rem, char *d_name)
falling = get_estimate(tdp2); falling = get_estimate(tdp2);
if (rising && falling) { if (rising && falling) {
if (strlen(rising) > 0 && strlen(falling) > 0) { if (strlen(rising) > 0 && strlen(falling) > 0) {
count = sprintf(work_buf, "(delay = %s)", rising); delays = tprintf("(delay = %s)", rising);
count++;
delays = TMALLOC(char, count);
(void) memcpy(delays, work_buf, count);
} }
} }
delete_timing_data(tdp1); delete_timing_data(tdp1);
@ -1674,8 +1725,6 @@ static char *get_delays_ueff(char *rem, char *d_name)
char *delays = NULL; char *delays = NULL;
char *clkqrise, *clkqfall, *pcqrise, *pcqfall; char *clkqrise, *clkqfall, *pcqrise, *pcqfall;
char *clkd, *setd, *resetd; char *clkd, *setd, *resetd;
int count;
char work_buf[BUFSIZE];
struct timing_data *tdp1, *tdp2, *tdp3, *tdp4; struct timing_data *tdp1, *tdp2, *tdp3, *tdp4;
tdp1 = create_min_typ_max("tpclkqlh", rem); tdp1 = create_min_typ_max("tpclkqlh", rem);
@ -1704,24 +1753,21 @@ static char *get_delays_ueff(char *rem, char *d_name)
setd = resetd = pcqfall; setd = resetd = pcqfall;
} }
if (clkd && setd) { if (clkd && setd) {
count = sprintf(work_buf, "(clk_delay = %s " delays = tprintf("(clk_delay = %s "
"set_delay = %s reset_delay = %s " "set_delay = %s reset_delay = %s "
"rise_delay = 1.0ns fall_delay = 2.0ns)", "rise_delay = 1.0ns fall_delay = 2.0ns)",
clkd, setd, resetd); clkd, setd, resetd);
} else if (clkd) { } else if (clkd) {
count = sprintf(work_buf, "(clk_delay = %s " delays = tprintf("(clk_delay = %s "
"rise_delay = 1.0ns fall_delay = 2.0ns)", "rise_delay = 1.0ns fall_delay = 2.0ns)",
clkd); clkd);
} else if (setd) { } else if (setd) {
count = sprintf(work_buf, "(set_delay = %s reset_delay = %s " delays = tprintf("(set_delay = %s reset_delay = %s "
"rise_delay = 1.0ns fall_delay = 2.0ns)", "rise_delay = 1.0ns fall_delay = 2.0ns)",
setd, resetd); setd, resetd);
} else { } else {
count = sprintf(work_buf, "(rise_delay = 1.0ns fall_delay = 2.0ns)"); delays = tprintf("(rise_delay = 1.0ns fall_delay = 2.0ns)");
} }
count++;
delays = TMALLOC(char, count);
(void) memcpy(delays, work_buf, count);
delete_timing_data(tdp1); delete_timing_data(tdp1);
delete_timing_data(tdp2); delete_timing_data(tdp2);
delete_timing_data(tdp3); delete_timing_data(tdp3);
@ -1734,7 +1780,7 @@ static char *get_delays_ugff(char *rem, char *d_name)
char *delays = NULL, *dname; char *delays = NULL, *dname;
char *tpdqlh, *tpdqhl, *tpgqlh, *tpgqhl, *tppcqlh, *tppcqhl; char *tpdqlh, *tpdqhl, *tpgqlh, *tpgqhl, *tppcqlh, *tppcqhl;
char *d_delay, *enab, *setd, *resetd; char *d_delay, *enab, *setd, *resetd;
char work_buf[BUFSIZE]; char *s1, *s2;
struct timing_data *tdp1, *tdp2, *tdp3, *tdp4, *tdp5, *tdp6; struct timing_data *tdp1, *tdp2, *tdp3, *tdp4, *tdp5, *tdp6;
if (strcmp(d_name, "d_dlatch") == 0) { if (strcmp(d_name, "d_dlatch") == 0) {
@ -1762,25 +1808,30 @@ static char *get_delays_ugff(char *rem, char *d_name)
tdp6 = create_min_typ_max("tppcqhl", rem); tdp6 = create_min_typ_max("tppcqhl", rem);
estimate_typ(tdp6); estimate_typ(tdp6);
tppcqhl = get_estimate(tdp6); tppcqhl = get_estimate(tdp6);
work_buf[0] = '\0';
strcpy(work_buf, "(");
d_delay = NULL; d_delay = NULL;
if (tpdqlh && strlen(tpdqlh) > 0) { if (tpdqlh && strlen(tpdqlh) > 0) {
d_delay = tpdqlh; d_delay = tpdqlh;
} else if (tpdqhl && strlen(tpdqhl) > 0) { } else if (tpdqhl && strlen(tpdqhl) > 0) {
d_delay = tpdqhl; d_delay = tpdqhl;
} }
if (d_delay) {
sprintf(&work_buf[strlen(work_buf)], "%s = %s ", dname, d_delay);
}
enab = NULL; enab = NULL;
if (tpgqlh && strlen(tpgqlh) > 0) { if (tpgqlh && strlen(tpgqlh) > 0) {
enab = tpgqlh; enab = tpgqlh;
} else if (tpgqhl && strlen(tpgqhl) > 0) { } else if (tpgqhl && strlen(tpgqhl) > 0) {
enab = tpgqhl; enab = tpgqhl;
} }
s1 = NULL;
if (enab) { if (enab) {
sprintf(&work_buf[strlen(work_buf)], "enable_delay = %s ", enab); if (d_delay) {
s1 = tprintf("%s = %s enable_delay = %s ",
dname, d_delay, enab);
} else {
s1 = tprintf("enable_delay = %s ", enab);
}
} else {
if (d_delay) {
s1 = tprintf("%s = %s ", dname, d_delay);
}
} }
setd = NULL; setd = NULL;
resetd = NULL; resetd = NULL;
@ -1790,13 +1841,19 @@ static char *get_delays_ugff(char *rem, char *d_name)
setd = resetd = tppcqhl; setd = resetd = tppcqhl;
} }
if (setd) { if (setd) {
sprintf(&work_buf[strlen(work_buf)], s2 = tprintf("set_delay = %s reset_delay = %s "
"set_delay = %s reset_delay = %s ", setd, resetd); "rise_delay = 1.0ns fall_delay = 2.0ns)",
setd, resetd);
} else {
s2 = tprintf("rise_delay = 1.0ns fall_delay = 2.0ns)");
} }
sprintf(&work_buf[strlen(work_buf)], if (s1) {
"rise_delay = 1.0ns fall_delay = 2.0ns)"); delays = tprintf("(%s%s", s1, s2);
delays = TMALLOC(char, strlen(work_buf) + 1); tfree(s1);
(void) memcpy(delays, work_buf, strlen(work_buf) + 1); } else {
delays = tprintf("(%s", s2);
}
tfree(s2);
delete_timing_data(tdp1); delete_timing_data(tdp1);
delete_timing_data(tdp2); delete_timing_data(tdp2);
delete_timing_data(tdp3); delete_timing_data(tdp3);
@ -1830,45 +1887,50 @@ static BOOL u_process_model(char *nline, char *original,
if (remainder) { if (remainder) {
if (strcmp(utype, "ugate") == 0) { if (strcmp(utype, "ugate") == 0) {
delays = get_delays_ugate(remainder, xspice); delays = get_delays_ugate(remainder, xspice);
printf("<%s>\n", delays);
if (delays) { if (delays) {
printf("<%s>\n", delays);
add_delays_to_model_xlator(delays, utype, "", tmodel); add_delays_to_model_xlator(delays, utype, "", tmodel);
} else { } else {
printf("<(null)>\n");
add_delays_to_model_xlator("", utype, "", tmodel); add_delays_to_model_xlator("", utype, "", tmodel);
} }
if (delays) { tfree(delays); } if (delays) { tfree(delays); }
} else if (strcmp(utype, "utgate") == 0) { } else if (strcmp(utype, "utgate") == 0) {
delays = get_delays_utgate(remainder, xspice); delays = get_delays_utgate(remainder, xspice);
printf("<%s>\n", delays);
if (delays) { if (delays) {
printf("<%s>\n", delays);
add_delays_to_model_xlator(delays, utype, "", tmodel); add_delays_to_model_xlator(delays, utype, "", tmodel);
} else { } else {
printf("<(null)>\n");
add_delays_to_model_xlator("", utype, "", tmodel); add_delays_to_model_xlator("", utype, "", tmodel);
} }
if (delays) { tfree(delays); } if (delays) { tfree(delays); }
} else if (strcmp(utype, "ueff") == 0) { } else if (strcmp(utype, "ueff") == 0) {
delays = get_delays_ueff(remainder, xspice); delays = get_delays_ueff(remainder, xspice);
printf("<%s>\n", delays);
if (delays) { if (delays) {
printf("<%s>\n", delays);
add_delays_to_model_xlator(delays, utype, "", tmodel); add_delays_to_model_xlator(delays, utype, "", tmodel);
} else { } else {
printf("<(null)>\n");
add_delays_to_model_xlator("", utype, "", tmodel); add_delays_to_model_xlator("", utype, "", tmodel);
} }
if (delays) { tfree(delays); } if (delays) { tfree(delays); }
} else if (strcmp(utype, "ugff") == 0) { } else if (strcmp(utype, "ugff") == 0) {
delays = get_delays_ugff(remainder, "d_dlatch"); delays = get_delays_ugff(remainder, "d_dlatch");
printf("<%s>\n", delays);
if (delays) { if (delays) {
printf("<%s>\n", delays);
add_delays_to_model_xlator(delays, utype, "d_dlatch", tmodel); add_delays_to_model_xlator(delays, utype, "d_dlatch", tmodel);
} else { } else {
printf("<(null)>\n");
add_delays_to_model_xlator("", utype, "d_dlatch", tmodel); add_delays_to_model_xlator("", utype, "d_dlatch", tmodel);
} }
if (delays) { tfree(delays); } if (delays) { tfree(delays); }
delays = get_delays_ugff(remainder, "d_srlatch"); delays = get_delays_ugff(remainder, "d_srlatch");
printf("<%s>\n", delays);
if (delays) { if (delays) {
printf("<%s>\n", delays);
add_delays_to_model_xlator(delays, utype, "d_srlatch", tmodel); add_delays_to_model_xlator(delays, utype, "d_srlatch", tmodel);
} else { } else {
printf("<(null)>\n");
add_delays_to_model_xlator("", utype, "d_srlatch", tmodel); add_delays_to_model_xlator("", utype, "d_srlatch", tmodel);
} }
if (delays) { tfree(delays); } if (delays) { tfree(delays); }
@ -2367,7 +2429,9 @@ BOOL u_process_instance(char *nline)
retval = FALSE; retval = FALSE;
} }
if (xp) { if (xp) {
//interpret_xlator(xp, TRUE); #ifdef TRACE
interpret_xlator(xp, TRUE);
#endif
delete_xlator(xp); delete_xlator(xp);
} }
return retval; return retval;