From 3e86af39894176725e804b51672fa02a791e4499 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Fri, 29 Apr 2022 21:12:05 -0700 Subject: [PATCH] Add default zero delay models d0_gate, d0_eff, d0_gff, d0_tgate. Use tprintf. --- src/frontend/udevices.c | 456 +++++++++++++++++++++++----------------- 1 file changed, 260 insertions(+), 196 deletions(-) diff --git a/src/frontend/udevices.c b/src/frontend/udevices.c index dc10191d0..887e22164 100644 --- a/src/frontend/udevices.c +++ b/src/frontend/udevices.c @@ -1,6 +1,7 @@ /* udevices.c translate PSPICE U* instances and timing models */ #include #include +#include #include #include #include @@ -8,6 +9,7 @@ #include "ngspice/memory.h" #include "ngspice/bool.h" #include "ngspice/stringskip.h" +#include "ngspice/stringutil.h" #include "ngspice/udevices.h" /* TODO check for name collisions with new names @@ -16,8 +18,6 @@ TODO investigate the method for generating model names */ -#define BUFSIZE 2048 -#define SMBUFSIZE 256 /* #define TRACE */ /* device types */ @@ -254,7 +254,11 @@ static char *find_xspice_for_delay(char *itype) 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) { if (p) { @@ -426,16 +430,34 @@ static void interpret_xlator(Xlatorp xp, BOOL brief) /* static Xlatorp for collecting timing model delays */ static Xlatorp model_xlatorp = NULL; +static Xlatorp default_models = NULL; void create_model_xlator(void) { + Xlatep xdata; + 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) { delete_xlator(model_xlatorp); model_xlatorp = NULL; + delete_xlator(default_models); + default_models = NULL; } 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, ""); } -static Xlatep find_in_model_xlator(Xlatep x) +static Xlatep find_in_xlator(Xlatep x, Xlatorp xlp) { Xlatep x1; if (!x) { return NULL; } - if (!model_xlatorp) { return NULL; } - for (x1 = first_xlator(model_xlatorp); x1; - x1 = next_xlator(model_xlatorp)) { + if (!xlp) { return NULL; } + for (x1 = first_xlator(xlp); x1; x1 = next_xlator(xlp)) { if (strcmp(x1->tmodel, x->tmodel) == 0 && strcmp(x1->utype, x->utype) == 0) { if (strcmp(x1->xspice, x->xspice) == 0) { @@ -461,6 +482,15 @@ static Xlatep find_in_model_xlator(Xlatep x) } 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, 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); x1 = find_in_model_xlator(x); if (x1) { +/* printf("Already found timing model %s utype %s\n", x1->tmodel, x1->utype); +*/ delete_xlate(x); return; } @@ -919,23 +951,17 @@ char *new_inverter(char *iname, char *node, Xlatorp xlp) /* Return the name of the output of the new inverter */ /* tfree the returned string after it has been used ny the caller */ char *tmp = NULL; - size_t sz; Xlatep xdata = NULL; - sz = 2*strlen(iname) + 3*strlen(node) + strlen("d_zero_inv99"); - sz += 100; /* that should be enough */ - 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"); + tmp = tprintf("a%s_%s %s not_%s_%s d_zero_inv99", + iname, node, node, iname, node); /* instantiate the new inverter */ /* e.g. au5_s1bar s1bar not_u5_s1bar d_zero_inv99 */ xdata = create_xlate_translated(tmp); (void) add_xlator(xlp, xdata); - tmp[0] = '\0'; + tfree(tmp); /* the name of the inverter output */ - sprintf(tmp, "not_%s_%s", iname, node); + tmp = tprintf("not_%s_%s", iname, node); return tmp; } @@ -951,10 +977,9 @@ static BOOL gen_timing_model( xspice instance and model lines (not to be confused with model_xlatorp. */ Xlatep xin = NULL, xout = NULL, newdata; - char work[BUFSIZE]; + char *s1; BOOL retval; - printf("Need model %s %s for %s\n", tmodel, xspice, newname); if (strcmp(utype, "ugff") == 0) { xin = create_xlate_model("", utype, xspice, tmodel); } else { @@ -963,14 +988,14 @@ static BOOL gen_timing_model( xout = find_in_model_xlator(xin); if (xout) { /* 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); - work[0] = '\0'; - sprintf(work, ".model %s %s", newname, xspice); 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); retval = TRUE; } else { @@ -986,8 +1011,7 @@ static Xlatorp gen_dff_instance(struct dff_instance *ip) char *itype, *iname, **darr, **qarr, **qbarr; char *preb, *clrb, *clk, *tmodel, *qout, *qbout; int i, num_gates; - char work[BUFSIZE]; - char smallbuf[SMBUFSIZE]; + char *modelnm, *s1; Xlatorp xxp = NULL; Xlatep xdata = NULL; 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; tmodel = ip->tmodel; - smallbuf[0] = '\0'; /* 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++) { - 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]; if (strcmp(qout, "$d_nc") == 0) { qout = "NULL"; } - sprintf(work + strlen(work), " %s", qout); qbout = qbarr[i]; if (strcmp(qbout, "$d_nc") == 0) { qbout = "NULL"; } - sprintf(work + strlen(work), " %s", qbout); - sprintf(work + strlen(work), " %s", smallbuf); - xdata = create_xlate_instance(work, " d_dff", tmodel, smallbuf); + s1 = tprintf( "a%s_%d %s %s %s %s %s %s %s", + iname, i, darr[i], clk, preb, clrb, qout, qbout, modelnm + ); + xdata = create_xlate_instance(s1, " d_dff", tmodel, modelnm); 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", - tmodel, smallbuf); + tmodel, modelnm); } if (need_preb_inv || need_clrb_inv) { 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_clrb_inv) { tfree(clrb); } + tfree(modelnm); return xxp; return NULL; @@ -1061,8 +1082,7 @@ static Xlatorp gen_jkff_instance(struct jkff_instance *ip) char *itype, *iname, **jarr, **karr, **qarr, **qbarr; char *preb, *clrb, *clkb, *tmodel, *qout, *qbout; int i, num_gates; - char work[BUFSIZE]; - char smallbuf[SMBUFSIZE]; + char *modelnm, *s1; Xlatorp xxp = NULL; Xlatep xdata = NULL; 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); tmodel = ip->tmodel; - smallbuf[0] = '\0'; /* 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++) { - 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]; if (strcmp(qout, "$d_nc") == 0) { qout = "NULL"; } - sprintf(work + strlen(work), " %s", qout); qbout = qbarr[i]; if (strcmp(qbout, "$d_nc") == 0) { qbout = "NULL"; } - sprintf(work + strlen(work), " %s %s", qbout, smallbuf); - xdata = create_xlate_instance(work, " d_jkff", tmodel, smallbuf); + s1 = tprintf("a%s_%d %s %s %s %s %s %s %s %s", + 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); + 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", - tmodel, smallbuf); + tmodel, modelnm); } xdata = create_xlate_translated(".model d_zero_inv99 d_inverter"); xxp = add_xlator(xxp, xdata); tfree(clkb); if (need_preb_inv) { tfree(preb); } if (need_clrb_inv) { tfree(clrb); } + tfree(modelnm); return xxp; - return NULL; } 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 *preb, *clrb, *gate, *tmodel, *qout, *qbout; int i, num_gates; - char work[BUFSIZE]; - char smallbuf[SMBUFSIZE]; + char *modelnm, *s1, *s2, *s3; Xlatorp xxp = NULL; Xlatep xdata = NULL; 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; tmodel = ip->tmodel; - smallbuf[0] = '\0'; /* 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++) { - 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]; if (strcmp(qout, "$d_nc") == 0) { /* 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 { - 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]; if (strcmp(qbout, "$d_nc") == 0) { /* NULL not allowed??? */ - sprintf(work + strlen(work), " ncn%s_%d", iname, i); + s2 = tprintf(" ncn%s_%d %s", iname, i, modelnm); } else { - sprintf(work + strlen(work), " %s", qbout); + s2 = tprintf(" %s %s", qbout, modelnm); } - sprintf(work + strlen(work), " %s", smallbuf); - xdata = create_xlate_instance(work, " d_dlatch", tmodel, smallbuf); + s3 = tprintf("%s%s", s1, s2); + xdata = create_xlate_instance(s3, " d_dlatch", tmodel, modelnm); 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", - tmodel, smallbuf); + tmodel, modelnm); } if (need_preb_inv || need_clrb_inv) { 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_clrb_inv) { tfree(clrb); } + tfree(modelnm); return xxp; } @@ -1212,18 +1229,18 @@ static Xlatorp gen_dltch_instance(struct dltch_instance *ip) static Xlatorp gen_gate_instance(struct gate_instance *gip) { 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 tristate_array = FALSE, simple_array = 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; size_t sz; Xlatorp xxp = NULL; Xlatep xdata = NULL; if (!gip) { return NULL; } - smallbuf[0] = '\0'; itype = gip->hdrp->instance_type; iname = gip->hdrp->instance_name; inarr = gip->inputs; @@ -1238,6 +1255,7 @@ static Xlatorp gen_gate_instance(struct gate_instance *gip) vector = has_vector_inputs(itype); if (num_gates == 1) { + char *inst_begin = NULL; assert(num_outs == 1); simple_gate = is_gate(itype); tristate_gate = is_tristate(itype); @@ -1256,53 +1274,76 @@ static Xlatorp gen_gate_instance(struct gate_instance *gip) } assert(xspice); xxp = create_xlator(); - work = TMALLOC(char, BUFSIZE); - work[0] = '\0'; /* Now build the instance name and inputs section */ - /* instance name */ - sprintf(work, "a%s ", iname); - if (vector) { strcat(work, "["); } - /* inputs */ - for (i = 0; i < width; i++) { - sprintf(work + strlen(work), " %s", inarr[i]); + if (vector) { + startvec = "["; + endvec = " ]"; + } else { + startvec = ""; + 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 */ if (enable) { assert(tristate_gate); 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 */ - sprintf(smallbuf, "a%s_%s", iname, outarr[0]); - connector = TMALLOC(char, strlen(smallbuf) + 1); - connector[0] = '\0'; - (void) memcpy(connector, smallbuf, strlen(smallbuf) + 1); + connector = tprintf("a%s_%s", iname, outarr[0]); /* keep a copy of the model name of original gate */ - modelbuf[0] = '\0'; - sprintf(modelbuf, "d_a%s%s", iname, itype); + modelnm = tprintf("d_a%s%s", iname, itype); if (!add_tristate) { + char *instance_stmt = NULL; /* add output + model name => translated instance */ - sprintf(work + strlen(work), " %s %s", outarr[0], modelbuf); - xdata = create_xlate_instance(work, xspice, tmodel, modelbuf); + instance_stmt = tprintf("%s %s %s", + inst_begin, outarr[0], modelnm); + xdata = create_xlate_instance(instance_stmt, + xspice, tmodel, modelnm); xxp = add_xlator(xxp, xdata); + tfree(instance_stmt); if (simple_gate) { if (!gen_timing_model(tmodel, "ugate", xspice, - modelbuf, xxp)) { + modelnm, xxp)) { printf("WARNING unable to find tmodel %s for %s %s\n", - tmodel, modelbuf, xspice); + tmodel, modelnm, xspice); } } else { /* must be trstate gate buf3 */ if (!gen_timing_model(tmodel, "utgate", xspice, - modelbuf, xxp)) { + modelnm, xxp)) { printf("WARNING unable to find tmodel %s for %s %s\n", - tmodel, modelbuf, xspice); + tmodel, modelnm, xspice); } } } else { + char *new_model_nm = NULL; + char *new_stmt = NULL; /* Use connector as original gate output and tristate input; 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 the connector as output + model name. */ - sprintf(work + strlen(work), " %s %s", connector, modelbuf); - xdata = create_xlate_instance(work, xspice, "", modelbuf); + new_stmt = tprintf("%s %s %s", inst_begin, connector, modelnm); + xdata = create_xlate_instance(new_stmt, xspice, "", modelnm); xxp = add_xlator(xxp, xdata); + tfree(new_stmt); /* new model statement e.g. .model d_au2nand3 d_nand */ - work[0] = '\0'; - sprintf(work, ".model %s %s", modelbuf, xspice); - xdata = create_xlate_translated(work); + new_stmt = tprintf(".model %s %s", modelnm, xspice); + xdata = create_xlate_translated(new_stmt); xxp = add_xlator(xxp, xdata); + tfree(new_stmt); /* now the added tristate */ - work[0] = '\0'; - modelbuf[0] = '\0'; /* model name of added tristate */ - sprintf(modelbuf, "d_a%stribuf", iname); - sprintf(work, "a%s_tri %s %s %s %s", iname, connector, - enable, outarr[0], modelbuf); - xdata = create_xlate_instance(work, "d_tristate", tmodel, modelbuf); + new_model_nm = tprintf("d_a%stribuf", iname); + new_stmt = tprintf("a%s_tri %s %s %s %s", + iname, connector, enable, outarr[0], new_model_nm); + xdata = create_xlate_instance(new_stmt, "d_tristate", + tmodel, new_model_nm); xxp = add_xlator(xxp, xdata); + tfree(new_stmt); 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", - tmodel, modelbuf, xspice); + tmodel, new_model_nm, xspice); } + tfree(new_model_nm); } - tfree(work); tfree(connector); + tfree(modelnm); + tfree(inst_begin); return xxp; } else { + char *primary_model = NULL, *s1 = NULL, *s2 = NULL, *s3 = NULL; + int ksave; /* arrays of gates */ /* NOTE (n)and3a, (n)or3a, (n)xora types are not supported */ assert(num_outs == num_gates); @@ -1363,104 +1409,122 @@ static Xlatorp gen_gate_instance(struct gate_instance *gip) } assert(xspice); xxp = create_xlator(); - sz = BUFSIZE; - work = TMALLOC(char, sz); k = 0; connector = NULL; + if (vector) { + startvec = "["; + endvec = " ]"; + } else { + startvec = ""; + endvec = ""; + } /* model name, same for all primary gates */ - modelbuf[0] = '\0'; - sprintf(modelbuf, "d_a%s%s", iname, itype); + primary_model = tprintf("d_a%s%s", iname, itype); for (i = 0; i < num_gates; i++) { - work[0] = '\0'; - /* create new instance name for primary gate */ - sprintf(work, "a%s_%d ", iname, i); - if (vector) { strcat(work, "["); } + /* inputs */ + /* First calculate the space */ + ksave = k; + sz = 0; for (j = 0; j < width; j++) { /* inputs for primary gate */ - sprintf(work + strlen(work), " %s", inarr[k]); + sz += strlen(inarr[k]) + 4; // Extra 4 spaces separating 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 (!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 { + s1 = tprintf("a%s_%d %s%s%s", + iname, i, startvec, input_buf, endvec); /* connector if required for tristate */ - sprintf(smallbuf, "a%s_%d_%s", iname, i, outarr[i]); - connector = TMALLOC(char, strlen(smallbuf) + 1); - connector[0] = '\0'; - (void) memcpy(connector, smallbuf, strlen(smallbuf) + 1); + connector = tprintf("a%s_%d_%s", iname, i, outarr[i]); } + } else { + s1 = tprintf("a%s_%d %s%s%s", + iname, i, startvec, input_buf, endvec); } + tfree(input_buf); /* output of primary gate */ if (add_tristate) { - sprintf(work + strlen(work), " %s", connector); + s2 = tprintf(" %s %s", connector, primary_model); } else { - sprintf(work + strlen(work), " %s", outarr[i]); + s2 = tprintf(" %s %s", outarr[i], primary_model); } /* translated instance */ - sprintf(work + strlen(work), " %s", modelbuf); + s3 = tprintf("%s%s", s1, s2); + if (add_tristate) { - xdata = create_xlate_instance(work, xspice, "", modelbuf); + xdata = create_xlate_instance(s3, xspice, "", primary_model); xxp = add_xlator(xxp, xdata); } else { - xdata = create_xlate_instance(work, xspice, tmodel, modelbuf); + xdata = create_xlate_instance(s3, xspice, tmodel, + primary_model); xxp = add_xlator(xxp, xdata); + } + tfree(s1); + tfree(s2); + tfree(s3); + + if (!add_tristate) { if (tristate_array) { assert(strcmp(xspice, "d_tristate") == 0); assert(strcmp(itype, "buf3a") == 0); 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", - tmodel, modelbuf, xspice); + tmodel, primary_model, xspice); } } else { 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", - tmodel, modelbuf, xspice); + tmodel, primary_model, xspice); } } } if (add_tristate) { + char *s1 = NULL, *modelnm = NULL; if (i == 0) { /* Zero delay model for all original array instances */ - work[0] = '\0'; - sprintf(work, ".model %s %s", modelbuf, xspice); - xdata = create_xlate_translated(work); + s1 = tprintf(".model %s %s", primary_model, xspice); + xdata = create_xlate_translated(s1); xxp = add_xlator(xxp, xdata); + tfree(s1); } - - work[0] = '\0'; - smallbuf[0] = '\0'; /* model name of added tristate */ - sprintf(smallbuf, "d_a%stribuf", iname); + modelnm = tprintf("d_a%stribuf", iname); /* instance name of added tristate, connector, enable, original primary gate output, timing model. */ - sprintf(work, "a%s_%d_tri %s %s %s %s", iname, i, connector, - enable, outarr[i], smallbuf); - xdata = create_xlate_instance(work, "d_tristate", - tmodel, smallbuf); + s1 = tprintf("a%s_%d_tri %s %s %s %s", iname, i, connector, + enable, outarr[i], modelnm); + xdata = create_xlate_instance(s1, "d_tristate", + tmodel, modelnm); xxp = add_xlator(xxp, xdata); + tfree(s1); 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", - tmodel, smallbuf, "d_tristate"); + tmodel, modelnm, "d_tristate"); } + tfree(modelnm); 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 NULL; @@ -1555,7 +1619,6 @@ static void estimate_typ(struct timing_data *tdp) char *min, *typ, *max; float valmin, valmax, average; char *units1, *units2; - static char avebuf[SMBUFSIZE]; if (!tdp) { return; } min = tdp->min; @@ -1577,12 +1640,10 @@ static void estimate_typ(struct timing_data *tdp) valmin = strtof(tmpmin, &units1); valmax = strtof(tmpmax, &units2); average = (valmin + valmax) / 2.0; - sprintf(avebuf, "%.2f%s", average, units2); + tdp->ave = tprintf("%.2f%s", average, units2); if (strcmp(units1, units2) != 0) { 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; return; } @@ -1618,8 +1679,6 @@ static char *get_estimate(struct timing_data *tdp) static char *get_delays_ugate(char *rem, char *d_name) { char *rising, *falling, *delays = NULL; - int count; - char work_buf[BUFSIZE]; struct timing_data *tdp1, *tdp2; 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); if (rising && falling) { 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); - count++; - delays = TMALLOC(char, count); - (void) memcpy(delays, work_buf, count); } } 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) */ char *rising, *falling, *delays = NULL; - int count; - char work_buf[BUFSIZE]; struct timing_data *tdp1, *tdp2; 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); if (rising && falling) { if (strlen(rising) > 0 && strlen(falling) > 0) { - count = sprintf(work_buf, "(delay = %s)", rising); - count++; - delays = TMALLOC(char, count); - (void) memcpy(delays, work_buf, count); + delays = tprintf("(delay = %s)", rising); } } delete_timing_data(tdp1); @@ -1674,8 +1725,6 @@ static char *get_delays_ueff(char *rem, char *d_name) char *delays = NULL; char *clkqrise, *clkqfall, *pcqrise, *pcqfall; char *clkd, *setd, *resetd; - int count; - char work_buf[BUFSIZE]; struct timing_data *tdp1, *tdp2, *tdp3, *tdp4; tdp1 = create_min_typ_max("tpclkqlh", rem); @@ -1704,24 +1753,21 @@ static char *get_delays_ueff(char *rem, char *d_name) setd = resetd = pcqfall; } if (clkd && setd) { - count = sprintf(work_buf, "(clk_delay = %s " + delays = tprintf("(clk_delay = %s " "set_delay = %s reset_delay = %s " "rise_delay = 1.0ns fall_delay = 2.0ns)", clkd, setd, resetd); } else if (clkd) { - count = sprintf(work_buf, "(clk_delay = %s " + delays = tprintf("(clk_delay = %s " "rise_delay = 1.0ns fall_delay = 2.0ns)", clkd); } 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)", setd, resetd); } 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(tdp2); delete_timing_data(tdp3); @@ -1734,7 +1780,7 @@ static char *get_delays_ugff(char *rem, char *d_name) char *delays = NULL, *dname; char *tpdqlh, *tpdqhl, *tpgqlh, *tpgqhl, *tppcqlh, *tppcqhl; char *d_delay, *enab, *setd, *resetd; - char work_buf[BUFSIZE]; + char *s1, *s2; struct timing_data *tdp1, *tdp2, *tdp3, *tdp4, *tdp5, *tdp6; 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); estimate_typ(tdp6); tppcqhl = get_estimate(tdp6); - work_buf[0] = '\0'; - strcpy(work_buf, "("); d_delay = NULL; if (tpdqlh && strlen(tpdqlh) > 0) { d_delay = tpdqlh; } else if (tpdqhl && strlen(tpdqhl) > 0) { d_delay = tpdqhl; } - if (d_delay) { - sprintf(&work_buf[strlen(work_buf)], "%s = %s ", dname, d_delay); - } enab = NULL; if (tpgqlh && strlen(tpgqlh) > 0) { enab = tpgqlh; } else if (tpgqhl && strlen(tpgqhl) > 0) { enab = tpgqhl; } + s1 = NULL; 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; resetd = NULL; @@ -1790,13 +1841,19 @@ static char *get_delays_ugff(char *rem, char *d_name) setd = resetd = tppcqhl; } if (setd) { - sprintf(&work_buf[strlen(work_buf)], - "set_delay = %s reset_delay = %s ", setd, resetd); + s2 = tprintf("set_delay = %s reset_delay = %s " + "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)], - "rise_delay = 1.0ns fall_delay = 2.0ns)"); - delays = TMALLOC(char, strlen(work_buf) + 1); - (void) memcpy(delays, work_buf, strlen(work_buf) + 1); + if (s1) { + delays = tprintf("(%s%s", s1, s2); + tfree(s1); + } else { + delays = tprintf("(%s", s2); + } + tfree(s2); delete_timing_data(tdp1); delete_timing_data(tdp2); delete_timing_data(tdp3); @@ -1830,45 +1887,50 @@ static BOOL u_process_model(char *nline, char *original, if (remainder) { if (strcmp(utype, "ugate") == 0) { delays = get_delays_ugate(remainder, xspice); - printf("<%s>\n", delays); if (delays) { + printf("<%s>\n", delays); add_delays_to_model_xlator(delays, utype, "", tmodel); } else { + printf("<(null)>\n"); add_delays_to_model_xlator("", utype, "", tmodel); } if (delays) { tfree(delays); } } else if (strcmp(utype, "utgate") == 0) { delays = get_delays_utgate(remainder, xspice); - printf("<%s>\n", delays); if (delays) { + printf("<%s>\n", delays); add_delays_to_model_xlator(delays, utype, "", tmodel); } else { + printf("<(null)>\n"); add_delays_to_model_xlator("", utype, "", tmodel); } if (delays) { tfree(delays); } } else if (strcmp(utype, "ueff") == 0) { delays = get_delays_ueff(remainder, xspice); - printf("<%s>\n", delays); if (delays) { + printf("<%s>\n", delays); add_delays_to_model_xlator(delays, utype, "", tmodel); } else { + printf("<(null)>\n"); add_delays_to_model_xlator("", utype, "", tmodel); } if (delays) { tfree(delays); } } else if (strcmp(utype, "ugff") == 0) { delays = get_delays_ugff(remainder, "d_dlatch"); - printf("<%s>\n", delays); if (delays) { + printf("<%s>\n", delays); add_delays_to_model_xlator(delays, utype, "d_dlatch", tmodel); } else { + printf("<(null)>\n"); add_delays_to_model_xlator("", utype, "d_dlatch", tmodel); } if (delays) { tfree(delays); } delays = get_delays_ugff(remainder, "d_srlatch"); - printf("<%s>\n", delays); if (delays) { + printf("<%s>\n", delays); add_delays_to_model_xlator(delays, utype, "d_srlatch", tmodel); } else { + printf("<(null)>\n"); add_delays_to_model_xlator("", utype, "d_srlatch", tmodel); } if (delays) { tfree(delays); } @@ -2367,7 +2429,9 @@ BOOL u_process_instance(char *nline) retval = FALSE; } if (xp) { - //interpret_xlator(xp, TRUE); +#ifdef TRACE + interpret_xlator(xp, TRUE); +#endif delete_xlator(xp); } return retval;