Browse Source

Prevent crashes in udevices.c when malformed U* instances are present. This would happen with incorrectly written U* gates, ff, latches which do not conform to the PSpice specs. Instead, ERROR messages are output which, hopefully, will help a user to debug their subckt.

pre-master-46
Brian Taylor 3 years ago
committed by Holger Vogt
parent
commit
b79eca646b
  1. 242
      src/frontend/udevices.c

242
src/frontend/udevices.c

@ -438,9 +438,13 @@ static void add_all_port_names(char *subckt_line)
} }
/* skip past .subckt and its name */ /* skip past .subckt and its name */
tok = strtok(copy_line, " \t"); tok = strtok(copy_line, " \t");
tok = strtok(NULL, " \t");
while ((tok = strtok(NULL, " \t")) != NULL) {
add_port_name(tok);
if (tok) {
tok = strtok(NULL, " \t");
if (tok) {
while ((tok = strtok(NULL, " \t")) != NULL) {
add_port_name(tok);
}
}
} }
tfree(copy_line); tfree(copy_line);
} }
@ -1555,13 +1559,17 @@ static struct instance_hdr *create_instance_header(char *line)
hdr = TMALLOC(struct instance_hdr, 1); hdr = TMALLOC(struct instance_hdr, 1);
hdr->num1 = -1; hdr->num1 = -1;
hdr->num2 = -1; hdr->num2 = -1;
hdr->instance_name = NULL;
hdr->instance_type = NULL;
/* instance name */ /* instance name */
tok = strtok(newline, " \t"); tok = strtok(newline, " \t");
if (!tok) { delete_instance_hdr(hdr); tfree(newline); return NULL; }
tmp = TMALLOC(char, strlen(tok) + 1); tmp = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(tmp, tok, strlen(tok) + 1); (void) memcpy(tmp, tok, strlen(tok) + 1);
hdr->instance_name = tmp; hdr->instance_name = tmp;
/* instance type */ /* instance type */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { delete_instance_hdr(hdr); tfree(newline); return NULL; }
p1 = strchr(tok, '('); p1 = strchr(tok, '(');
if (p1) { if (p1) {
/* ...(n1,n2) or ...(n1) */ /* ...(n1,n2) or ...(n1) */
@ -1679,7 +1687,7 @@ static Xlatorp gen_dff_instance(struct dff_instance *ip, int withinv)
clrb = ip->clrbar; clrb = ip->clrbar;
xxp = create_xlator(); xxp = create_xlator();
if (eq(preb, "$d_hi")) {
if (eq(preb, "$d_hi") || eq(preb, "$d_nc")) {
preb = "NULL"; preb = "NULL";
} else { } else {
add_input_pin(preb); add_input_pin(preb);
@ -1689,7 +1697,7 @@ static Xlatorp gen_dff_instance(struct dff_instance *ip, int withinv)
} }
} }
if (eq(clrb, "$d_hi")) {
if (eq(clrb, "$d_hi") || eq(clrb, "$d_nc")) {
clrb = "NULL"; clrb = "NULL";
} else { } else {
add_input_pin(clrb); add_input_pin(clrb);
@ -1792,7 +1800,7 @@ static Xlatorp gen_jkff_instance(struct jkff_instance *ip, int withinv)
clrb = ip->clrbar; clrb = ip->clrbar;
xxp = create_xlator(); xxp = create_xlator();
if (eq(preb, "$d_hi")) {
if (eq(preb, "$d_hi") || eq(preb, "$d_nc")) {
preb = "NULL"; preb = "NULL";
} else { } else {
add_input_pin(preb); add_input_pin(preb);
@ -1802,7 +1810,7 @@ static Xlatorp gen_jkff_instance(struct jkff_instance *ip, int withinv)
} }
} }
if (eq(clrb, "$d_hi")) {
if (eq(clrb, "$d_hi") || eq(clrb, "$d_nc")) {
clrb = "NULL"; clrb = "NULL";
} else { } else {
add_input_pin(clrb); add_input_pin(clrb);
@ -1906,7 +1914,7 @@ static Xlatorp gen_dltch_instance(struct dltch_instance *ip, int withinv)
clrb = ip->clrbar; clrb = ip->clrbar;
xxp = create_xlator(); xxp = create_xlator();
if (eq(preb, "$d_hi")) {
if (eq(preb, "$d_hi") || eq(preb, "$d_nc")) {
preb = "NULL"; preb = "NULL";
} else { } else {
add_input_pin(preb); add_input_pin(preb);
@ -1916,7 +1924,7 @@ static Xlatorp gen_dltch_instance(struct dltch_instance *ip, int withinv)
} }
} }
if (eq(clrb, "$d_hi")) {
if (eq(clrb, "$d_hi") || eq(clrb, "$d_nc")) {
clrb = "NULL"; clrb = "NULL";
} else { } else {
add_input_pin(clrb); add_input_pin(clrb);
@ -2022,7 +2030,7 @@ static Xlatorp gen_srff_instance(struct srff_instance *srffp, int withinv)
clrb = srffp->clrbar; clrb = srffp->clrbar;
xxp = create_xlator(); xxp = create_xlator();
if (eq(preb, "$d_hi")) {
if (eq(preb, "$d_hi") || eq(preb, "$d_nc")) {
preb = "NULL"; preb = "NULL";
} else { } else {
add_input_pin(preb); add_input_pin(preb);
@ -2032,7 +2040,7 @@ static Xlatorp gen_srff_instance(struct srff_instance *srffp, int withinv)
} }
} }
if (eq(clrb, "$d_hi")) {
if (eq(clrb, "$d_hi") || eq(clrb, "$d_nc")) {
clrb = "NULL"; clrb = "NULL";
} else { } else {
add_input_pin(clrb); add_input_pin(clrb);
@ -3088,12 +3096,15 @@ static BOOL u_process_model(char *nline, char *original)
/* .model */ /* .model */
tok = strtok(nline, " \t"); tok = strtok(nline, " \t");
if (!tok) { return FALSE; }
/* model name */ /* model name */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { return FALSE; }
tmodel = TMALLOC(char, strlen(tok) + 1); tmodel = TMALLOC(char, strlen(tok) + 1);
memcpy(tmodel, tok, strlen(tok) + 1); memcpy(tmodel, tok, strlen(tok) + 1);
/* model utype */ /* model utype */
tok = strtok(NULL, " \t("); tok = strtok(NULL, " \t(");
if (!tok) { tfree(tmodel); return FALSE; }
utype = TMALLOC(char, strlen(tok) + 1); utype = TMALLOC(char, strlen(tok) + 1);
memcpy(utype, tok, strlen(tok) + 1); memcpy(utype, tok, strlen(tok) + 1);
@ -3166,19 +3177,24 @@ static struct dff_instance *add_dff_inout_timing_model(
char *name, **arrp; char *name, **arrp;
int i, num_gates = hdr->num1; int i, num_gates = hdr->num1;
struct dff_instance *dffip = NULL; struct dff_instance *dffip = NULL;
BOOL compat = TRUE;
if (num_gates < 1) { return NULL; }
dffip = create_dff_instance(hdr); dffip = create_dff_instance(hdr);
dffip->num_gates = num_gates; dffip->num_gates = num_gates;
copyline = TMALLOC(char, strlen(start) + 1); copyline = TMALLOC(char, strlen(start) + 1);
(void) memcpy(copyline, start, strlen(start) + 1); (void) memcpy(copyline, start, strlen(start) + 1);
/* prebar, clrbar, clk */ /* prebar, clrbar, clk */
tok = strtok(copyline, " \t"); tok = strtok(copyline, " \t");
if (!tok) { goto bail_out; }
dffip->prebar = TMALLOC(char, strlen(tok) + 1); dffip->prebar = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(dffip->prebar, tok, strlen(tok) + 1); (void) memcpy(dffip->prebar, tok, strlen(tok) + 1);
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
dffip->clrbar = TMALLOC(char, strlen(tok) + 1); dffip->clrbar = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(dffip->clrbar, tok, strlen(tok) + 1); (void) memcpy(dffip->clrbar, tok, strlen(tok) + 1);
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
dffip->clk = TMALLOC(char, strlen(tok) + 1); dffip->clk = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(dffip->clk, tok, strlen(tok) + 1); (void) memcpy(dffip->clk, tok, strlen(tok) + 1);
/* d inputs */ /* d inputs */
@ -3186,6 +3202,7 @@ static struct dff_instance *add_dff_inout_timing_model(
arrp = dffip->d_in; arrp = dffip->d_in;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
arrp[i] = get_name_hilo(tok); arrp[i] = get_name_hilo(tok);
} }
/* q_out outputs */ /* q_out outputs */
@ -3193,6 +3210,7 @@ static struct dff_instance *add_dff_inout_timing_model(
arrp = dffip->q_out; arrp = dffip->q_out;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
arrp[i] = name; arrp[i] = name;
@ -3202,12 +3220,14 @@ static struct dff_instance *add_dff_inout_timing_model(
arrp = dffip->qb_out; arrp = dffip->qb_out;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
arrp[i] = name; arrp[i] = name;
} }
/* timing model */ /* timing model */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
dffip->tmodel = TMALLOC(char, strlen(tok) + 1); dffip->tmodel = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(dffip->tmodel, tok, strlen(tok) + 1); (void) memcpy(dffip->tmodel, tok, strlen(tok) + 1);
tfree(copyline); tfree(copyline);
@ -3216,20 +3236,27 @@ static struct dff_instance *add_dff_inout_timing_model(
arrp = dffip->d_in; arrp = dffip->d_in;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
if (eq(arrp[i], "$d_nc")) { if (eq(arrp[i], "$d_nc")) {
delete_dff_instance(dffip);
return NULL;
fprintf(stderr, "ERROR incompatible dff d input $d_nc\n");
compat = FALSE;
break;
} }
} }
if (eq(dffip->prebar, "$d_lo") || eq(dffip->prebar, "$d_nc")) {
delete_dff_instance(dffip);
return NULL;
if (eq(dffip->clk, "$d_nc")) {
fprintf(stderr, "ERROR incompatible dff clk $d_nc\n");
compat = FALSE;
} }
if (eq(dffip->clrbar, "$d_lo") || eq(dffip->clrbar, "$d_nc")) {
if (compat) {
return dffip;
} else {
delete_dff_instance(dffip); delete_dff_instance(dffip);
return NULL; return NULL;
} }
return dffip;
bail_out:
fprintf(stderr, "ERROR parsing dff\n");
delete_dff_instance(dffip);
tfree(copyline);
return NULL;
} }
static struct dltch_instance *add_dltch_inout_timing_model( static struct dltch_instance *add_dltch_inout_timing_model(
@ -3239,19 +3266,24 @@ static struct dltch_instance *add_dltch_inout_timing_model(
char *name, **arrp; char *name, **arrp;
int i, num_gates = hdr->num1; int i, num_gates = hdr->num1;
struct dltch_instance *dlp = NULL; struct dltch_instance *dlp = NULL;
BOOL compat = TRUE;
if (num_gates < 1) { return NULL; }
dlp = create_dltch_instance(hdr); dlp = create_dltch_instance(hdr);
dlp->num_gates = num_gates; dlp->num_gates = num_gates;
copyline = TMALLOC(char, strlen(start) + 1); copyline = TMALLOC(char, strlen(start) + 1);
(void) memcpy(copyline, start, strlen(start) + 1); (void) memcpy(copyline, start, strlen(start) + 1);
/* prebar, clrbar, clk(gate) */ /* prebar, clrbar, clk(gate) */
tok = strtok(copyline, " \t"); tok = strtok(copyline, " \t");
if (!tok) { goto bail_out; }
dlp->prebar = TMALLOC(char, strlen(tok) + 1); dlp->prebar = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(dlp->prebar, tok, strlen(tok) + 1); (void) memcpy(dlp->prebar, tok, strlen(tok) + 1);
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
dlp->clrbar = TMALLOC(char, strlen(tok) + 1); dlp->clrbar = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(dlp->clrbar, tok, strlen(tok) + 1); (void) memcpy(dlp->clrbar, tok, strlen(tok) + 1);
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
dlp->gate = get_name_hilo(tok); dlp->gate = get_name_hilo(tok);
/* d inputs */ /* d inputs */
@ -3259,6 +3291,7 @@ static struct dltch_instance *add_dltch_inout_timing_model(
arrp = dlp->d_in; arrp = dlp->d_in;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
arrp[i] = get_name_hilo(tok); arrp[i] = get_name_hilo(tok);
} }
/* q_out outputs */ /* q_out outputs */
@ -3266,6 +3299,7 @@ static struct dltch_instance *add_dltch_inout_timing_model(
arrp = dlp->q_out; arrp = dlp->q_out;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
arrp[i] = name; arrp[i] = name;
@ -3275,12 +3309,14 @@ static struct dltch_instance *add_dltch_inout_timing_model(
arrp = dlp->qb_out; arrp = dlp->qb_out;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
arrp[i] = name; arrp[i] = name;
} }
/* timing model */ /* timing model */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
dlp->tmodel = TMALLOC(char, strlen(tok) + 1); dlp->tmodel = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(dlp->tmodel, tok, strlen(tok) + 1); (void) memcpy(dlp->tmodel, tok, strlen(tok) + 1);
tfree(copyline); tfree(copyline);
@ -3289,23 +3325,27 @@ static struct dltch_instance *add_dltch_inout_timing_model(
arrp = dlp->d_in; arrp = dlp->d_in;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
if (eq(arrp[i], "$d_nc")) { if (eq(arrp[i], "$d_nc")) {
delete_dltch_instance(dlp);
return NULL;
fprintf(stderr, "ERROR incompatible dltch d input $d_nc\n");
compat = FALSE;
break;
} }
} }
if (eq(dlp->gate, "$d_nc")) { if (eq(dlp->gate, "$d_nc")) {
delete_dltch_instance(dlp);
return NULL;
}
if (eq(dlp->prebar, "$d_lo") || eq(dlp->prebar, "$d_nc")) {
delete_dltch_instance(dlp);
return NULL;
fprintf(stderr, "ERROR incompatible dltch gate $d_nc\n");
compat = FALSE;
} }
if (eq(dlp->clrbar, "$d_lo") || eq(dlp->clrbar, "$d_nc")) {
if (compat) {
return dlp;
} else {
delete_dltch_instance(dlp); delete_dltch_instance(dlp);
return NULL; return NULL;
} }
return dlp;
bail_out:
fprintf(stderr, "ERROR parsing dltch\n");
delete_dltch_instance(dlp);
tfree(copyline);
return NULL;
} }
static struct jkff_instance *add_jkff_inout_timing_model( static struct jkff_instance *add_jkff_inout_timing_model(
@ -3315,19 +3355,24 @@ static struct jkff_instance *add_jkff_inout_timing_model(
char *name, **arrp, **arrpk; char *name, **arrp, **arrpk;
int i, num_gates = hdr->num1; int i, num_gates = hdr->num1;
struct jkff_instance *jkffip = NULL; struct jkff_instance *jkffip = NULL;
BOOL compat = TRUE;
if (num_gates < 1) { return NULL; }
jkffip = create_jkff_instance(hdr); jkffip = create_jkff_instance(hdr);
jkffip->num_gates = num_gates; jkffip->num_gates = num_gates;
copyline = TMALLOC(char, strlen(start) + 1); copyline = TMALLOC(char, strlen(start) + 1);
(void) memcpy(copyline, start, strlen(start) + 1); (void) memcpy(copyline, start, strlen(start) + 1);
/* prebar, clrbar, clkbar */ /* prebar, clrbar, clkbar */
tok = strtok(copyline, " \t"); tok = strtok(copyline, " \t");
if (!tok) { goto bail_out; }
jkffip->prebar = TMALLOC(char, strlen(tok) + 1); jkffip->prebar = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(jkffip->prebar, tok, strlen(tok) + 1); (void) memcpy(jkffip->prebar, tok, strlen(tok) + 1);
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
jkffip->clrbar = TMALLOC(char, strlen(tok) + 1); jkffip->clrbar = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(jkffip->clrbar, tok, strlen(tok) + 1); (void) memcpy(jkffip->clrbar, tok, strlen(tok) + 1);
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
jkffip->clkbar = TMALLOC(char, strlen(tok) + 1); jkffip->clkbar = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(jkffip->clkbar, tok, strlen(tok) + 1); (void) memcpy(jkffip->clkbar, tok, strlen(tok) + 1);
/* j inputs */ /* j inputs */
@ -3335,6 +3380,7 @@ static struct jkff_instance *add_jkff_inout_timing_model(
arrp = jkffip->j_in; arrp = jkffip->j_in;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
arrp[i] = get_name_hilo(tok); arrp[i] = get_name_hilo(tok);
} }
/* k inputs */ /* k inputs */
@ -3342,6 +3388,7 @@ static struct jkff_instance *add_jkff_inout_timing_model(
arrp = jkffip->k_in; arrp = jkffip->k_in;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
arrp[i] = get_name_hilo(tok); arrp[i] = get_name_hilo(tok);
} }
/* q_out outputs */ /* q_out outputs */
@ -3349,6 +3396,7 @@ static struct jkff_instance *add_jkff_inout_timing_model(
arrp = jkffip->q_out; arrp = jkffip->q_out;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
arrp[i] = name; arrp[i] = name;
@ -3358,12 +3406,14 @@ static struct jkff_instance *add_jkff_inout_timing_model(
arrp = jkffip->qb_out; arrp = jkffip->qb_out;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
arrp[i] = name; arrp[i] = name;
} }
/* timing model */ /* timing model */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
jkffip->tmodel = TMALLOC(char, strlen(tok) + 1); jkffip->tmodel = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(jkffip->tmodel, tok, strlen(tok) + 1); (void) memcpy(jkffip->tmodel, tok, strlen(tok) + 1);
tfree(copyline); tfree(copyline);
@ -3373,19 +3423,27 @@ static struct jkff_instance *add_jkff_inout_timing_model(
arrpk = jkffip->k_in; arrpk = jkffip->k_in;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
if (eq(arrp[i], "$d_nc") || eq(arrpk[i], "$d_nc")) { if (eq(arrp[i], "$d_nc") || eq(arrpk[i], "$d_nc")) {
delete_jkff_instance(jkffip);
return NULL;
fprintf(stderr, "ERROR incompatible jkff j/k input $d_nc\n");
compat = FALSE;
break;
} }
} }
if (eq(jkffip->prebar, "$d_lo") || eq(jkffip->prebar, "$d_nc")) {
delete_jkff_instance(jkffip);
return NULL;
if (eq(jkffip->clkbar, "$d_nc")) {
fprintf(stderr, "ERROR incompatible jkff clkbar $d_nc\n");
compat = FALSE;
} }
if (eq(jkffip->clrbar, "$d_lo") || eq(jkffip->clrbar, "$d_nc")) {
if (compat) {
return jkffip;
} else {
delete_jkff_instance(jkffip); delete_jkff_instance(jkffip);
return NULL; return NULL;
} }
return jkffip;
bail_out:
fprintf(stderr, "ERROR parsing jkff\n");
delete_jkff_instance(jkffip);
tfree(copyline);
return NULL;
} }
static struct srff_instance *add_srff_inout_timing_model( static struct srff_instance *add_srff_inout_timing_model(
@ -3395,7 +3453,9 @@ static struct srff_instance *add_srff_inout_timing_model(
char *name, **arrp, **arrpr; char *name, **arrp, **arrpr;
int i, num_gates = hdr->num1; int i, num_gates = hdr->num1;
struct srff_instance *srffp = NULL; struct srff_instance *srffp = NULL;
BOOL compat = TRUE;
if (num_gates < 1) { return NULL; }
srffp = create_srff_instance(hdr); srffp = create_srff_instance(hdr);
srffp->num_gates = num_gates; srffp->num_gates = num_gates;
copyline = TMALLOC(char, strlen(start) + 1); copyline = TMALLOC(char, strlen(start) + 1);
@ -3403,14 +3463,17 @@ static struct srff_instance *add_srff_inout_timing_model(
/* prebar, clrbar, gate */ /* prebar, clrbar, gate */
tok = strtok(copyline, " \t"); tok = strtok(copyline, " \t");
if (!tok) { goto bail_out; }
srffp->prebar = TMALLOC(char, strlen(tok) + 1); srffp->prebar = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(srffp->prebar, tok, strlen(tok) + 1); (void) memcpy(srffp->prebar, tok, strlen(tok) + 1);
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
srffp->clrbar = TMALLOC(char, strlen(tok) + 1); srffp->clrbar = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(srffp->clrbar, tok, strlen(tok) + 1); (void) memcpy(srffp->clrbar, tok, strlen(tok) + 1);
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
srffp->gate = get_name_hilo(tok); srffp->gate = get_name_hilo(tok);
/* s inputs */ /* s inputs */
@ -3418,6 +3481,7 @@ static struct srff_instance *add_srff_inout_timing_model(
arrp = srffp->s_in; arrp = srffp->s_in;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
arrp[i] = get_name_hilo(tok); arrp[i] = get_name_hilo(tok);
} }
/* r inputs */ /* r inputs */
@ -3425,6 +3489,7 @@ static struct srff_instance *add_srff_inout_timing_model(
arrp = srffp->r_in; arrp = srffp->r_in;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
arrp[i] = get_name_hilo(tok); arrp[i] = get_name_hilo(tok);
} }
/* q_out outputs */ /* q_out outputs */
@ -3432,6 +3497,7 @@ static struct srff_instance *add_srff_inout_timing_model(
arrp = srffp->q_out; arrp = srffp->q_out;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
arrp[i] = name; arrp[i] = name;
@ -3441,12 +3507,14 @@ static struct srff_instance *add_srff_inout_timing_model(
arrp = srffp->qb_out; arrp = srffp->qb_out;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
arrp[i] = name; arrp[i] = name;
} }
/* timing model */ /* timing model */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
srffp->tmodel = TMALLOC(char, strlen(tok) + 1); srffp->tmodel = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(srffp->tmodel, tok, strlen(tok) + 1); (void) memcpy(srffp->tmodel, tok, strlen(tok) + 1);
tfree(copyline); tfree(copyline);
@ -3456,23 +3524,27 @@ static struct srff_instance *add_srff_inout_timing_model(
arrpr = srffp->r_in; arrpr = srffp->r_in;
for (i = 0; i < num_gates; i++) { for (i = 0; i < num_gates; i++) {
if (eq(arrp[i], "$d_nc") || eq(arrpr[i], "$d_nc")) { if (eq(arrp[i], "$d_nc") || eq(arrpr[i], "$d_nc")) {
delete_srff_instance(srffp);
return NULL;
fprintf(stderr, "ERROR incompatible srff s/r input $d_nc\n");
compat = FALSE;
break;
} }
} }
if (eq(srffp->gate, "$d_nc")) {
delete_srff_instance(srffp);
return NULL;
}
if (eq(srffp->prebar, "$d_lo") || eq(srffp->prebar, "$d_nc")) {
delete_srff_instance(srffp);
return NULL;
if (eq(srffp->gate, "$d_nc")) { /* d_srff clk cannot be null */
fprintf(stderr, "ERROR incompatible srff gate $d_nc\n");
compat = FALSE;
} }
if (eq(srffp->clrbar, "$d_lo") || eq(srffp->clrbar, "$d_nc")) {
if (compat) {
return srffp;
} else {
delete_srff_instance(srffp); delete_srff_instance(srffp);
return NULL; return NULL;
} }
return srffp;
bail_out:
fprintf(stderr, "ERROR parsing srff\n");
delete_srff_instance(srffp);
tfree(copyline);
return NULL;
} }
static struct compound_instance *add_compound_inout_timing_model( static struct compound_instance *add_compound_inout_timing_model(
@ -3485,8 +3557,9 @@ static struct compound_instance *add_compound_inout_timing_model(
BOOL first = TRUE; BOOL first = TRUE;
if (is_compound_gate(itype)) { if (is_compound_gate(itype)) {
inwidth = n1;
numgates = n2;
inwidth = n1;
numgates = n2;
if (inwidth < 2 || numgates < 1) { return NULL; }
} else { } else {
return NULL; return NULL;
} }
@ -3504,9 +3577,11 @@ static struct compound_instance *add_compound_inout_timing_model(
for (j = 0; j < inwidth; j++) { for (j = 0; j < inwidth; j++) {
if (first) { if (first) {
tok = strtok(copyline, " \t"); tok = strtok(copyline, " \t");
if (!tok) { goto bail_out; }
first = FALSE; first = FALSE;
} else { } else {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
} }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
@ -3516,16 +3591,24 @@ static struct compound_instance *add_compound_inout_timing_model(
} }
/* one output */ /* one output */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
compi->output = name; compi->output = name;
/* timing model */ /* timing model */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
compi->tmodel = name; compi->tmodel = name;
tfree(copyline); tfree(copyline);
return compi; return compi;
bail_out:
fprintf(stderr, "ERROR parsing compound instance\n");
delete_compound_instance(compi);
tfree(copyline);
return NULL;
} }
static struct gate_instance *add_array_inout_timing_model( static struct gate_instance *add_array_inout_timing_model(
@ -3540,23 +3623,29 @@ static struct gate_instance *add_array_inout_timing_model(
if (is_tristate_buf_array(itype)) { if (is_tristate_buf_array(itype)) {
inwidth = 1; inwidth = 1;
numgates = n1; numgates = n1;
if (numgates < 1) { return NULL; }
tristate = TRUE; tristate = TRUE;
} else if (is_buf_gate_array(itype)) { } else if (is_buf_gate_array(itype)) {
inwidth = 1; inwidth = 1;
numgates = n1; numgates = n1;
if (numgates < 1) { return NULL; }
} else if (is_vector_gate_array(itype)) { } else if (is_vector_gate_array(itype)) {
inwidth = n1; inwidth = n1;
numgates = n2; numgates = n2;
if (inwidth < 2 || numgates < 1) { return NULL; }
} else if (is_tristate_vector_array(itype)) { } else if (is_tristate_vector_array(itype)) {
inwidth = n1; inwidth = n1;
numgates = n2; numgates = n2;
if (inwidth < 2 || numgates < 1) { return NULL; }
tristate = TRUE; tristate = TRUE;
} else if (is_xor_gate_array(itype)) { } else if (is_xor_gate_array(itype)) {
inwidth = 2; inwidth = 2;
numgates = n1; numgates = n1;
if (numgates < 1) { return NULL; }
} else if (is_tristate_xor_array(itype)) { } else if (is_tristate_xor_array(itype)) {
inwidth = 2; inwidth = 2;
numgates = n1; numgates = n1;
if (numgates < 1) { return NULL; }
tristate = TRUE; tristate = TRUE;
} else { } else {
return NULL; return NULL;
@ -3579,9 +3668,11 @@ static struct gate_instance *add_array_inout_timing_model(
for (j = 0; j < inwidth; j++) { for (j = 0; j < inwidth; j++) {
if (first) { if (first) {
tok = strtok(copyline, " \t"); tok = strtok(copyline, " \t");
if (!tok) { goto bail_out; }
first = FALSE; first = FALSE;
} else { } else {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
} }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
@ -3592,6 +3683,7 @@ static struct gate_instance *add_array_inout_timing_model(
/* enable for tristate */ /* enable for tristate */
if (tristate) { if (tristate) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
gip->enable = name; gip->enable = name;
@ -3601,17 +3693,25 @@ static struct gate_instance *add_array_inout_timing_model(
gip->outputs = outarr; gip->outputs = outarr;
for (i = 0; i < numgates; i++) { for (i = 0; i < numgates; i++) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
outarr[i] = name; outarr[i] = name;
} }
/* timing model last */ /* timing model last */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
gip->tmodel = name; gip->tmodel = name;
tfree(copyline); tfree(copyline);
return gip; return gip;
bail_out:
fprintf(stderr, "ERROR parsing array of gates\n");
delete_gate_instance(gip);
tfree(copyline);
return NULL;
} }
static struct gate_instance *add_gate_inout_timing_model( static struct gate_instance *add_gate_inout_timing_model(
@ -3625,8 +3725,10 @@ static struct gate_instance *add_gate_inout_timing_model(
if (is_vector_gate(itype)) { if (is_vector_gate(itype)) {
inwidth = n1; inwidth = n1;
if (inwidth < 2) { return NULL; }
} else if (is_vector_tristate(itype)) { } else if (is_vector_tristate(itype)) {
inwidth = n1; inwidth = n1;
if (inwidth < 2) { return NULL; }
tristate = TRUE; tristate = TRUE;
} else if (is_buf_gate(itype)) { } else if (is_buf_gate(itype)) {
inwidth = 1; inwidth = 1;
@ -3654,9 +3756,11 @@ static struct gate_instance *add_gate_inout_timing_model(
for (i = 0; i < inwidth; i++) { for (i = 0; i < inwidth; i++) {
if (first) { if (first) {
tok = strtok(copyline, " \t"); tok = strtok(copyline, " \t");
if (!tok) { goto bail_out; }
first = FALSE; first = FALSE;
} else { } else {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
} }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
@ -3665,6 +3769,7 @@ static struct gate_instance *add_gate_inout_timing_model(
/* enable for tristate */ /* enable for tristate */
if (tristate) { if (tristate) {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
gip->enable = name; gip->enable = name;
@ -3673,16 +3778,24 @@ static struct gate_instance *add_gate_inout_timing_model(
outarr = TMALLOC(char *, gip->num_outs); outarr = TMALLOC(char *, gip->num_outs);
gip->outputs = outarr; gip->outputs = outarr;
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
outarr[0] = name; outarr[0] = name;
/* timing model last */ /* timing model last */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (!tok) { goto bail_out; }
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
gip->tmodel = name; gip->tmodel = name;
tfree(copyline); tfree(copyline);
return gip; return gip;
bail_out:
fprintf(stderr, "ERROR parsing gate\n");
delete_gate_instance(gip);
tfree(copyline);
return NULL;
} }
static char *skip_past_words(char *start, int count) static char *skip_past_words(char *start, int count)
@ -3703,7 +3816,7 @@ static char *skip_past_words(char *start, int count)
static Xlatorp translate_pull(struct instance_hdr *hdr, char *start) static Xlatorp translate_pull(struct instance_hdr *hdr, char *start)
{ {
char *itype, *xspice, *iname, *newline = NULL, *tok; char *itype, *xspice, *iname, *newline = NULL, *tok;
char *model_name, *inst_stmt, *model_stmt;
char *model_name = NULL, *inst_stmt = NULL, *model_stmt = NULL;
int i, numpulls; int i, numpulls;
Xlatorp xp = NULL; Xlatorp xp = NULL;
Xlatep xdata = NULL; Xlatep xdata = NULL;
@ -3723,6 +3836,11 @@ static Xlatorp translate_pull(struct instance_hdr *hdr, char *start)
} else { } else {
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
} }
if (!tok) {
delete_xlator(xp);
xp = NULL;
goto end_of_function;
}
inst_stmt = tprintf("a%s_%d %s %s", iname, i, tok, model_name); inst_stmt = tprintf("a%s_%d %s %s", iname, i, tok, model_name);
xdata = create_xlate_translated(inst_stmt); xdata = create_xlate_translated(inst_stmt);
xp = add_xlator(xp, xdata); xp = add_xlator(xp, xdata);
@ -3731,9 +3849,10 @@ static Xlatorp translate_pull(struct instance_hdr *hdr, char *start)
model_stmt = tprintf(".model %s %s(load = 1pf)", model_name, xspice); model_stmt = tprintf(".model %s %s(load = 1pf)", model_name, xspice);
xdata = create_xlate_translated(model_stmt); xdata = create_xlate_translated(model_stmt);
xp = add_xlator(xp, xdata); xp = add_xlator(xp, xdata);
tfree(model_stmt);
tfree(model_name);
tfree(newline);
end_of_function:
if (model_stmt) { tfree(model_stmt); }
if (model_name) { tfree(model_name); }
if (newline) { tfree(newline); }
delete_instance_hdr(hdr); delete_instance_hdr(hdr);
return xp; return xp;
} }
@ -3829,6 +3948,9 @@ BOOL u_check_instance(char *line)
char *xspice, *itype; char *xspice, *itype;
struct instance_hdr *hdr = create_instance_header(line); struct instance_hdr *hdr = create_instance_header(line);
if (!hdr) {
return FALSE;
}
itype = hdr->instance_type; itype = hdr->instance_type;
xspice = find_xspice_for_delay(itype); xspice = find_xspice_for_delay(itype);
if (!xspice) { if (!xspice) {
@ -3870,6 +3992,9 @@ BOOL u_process_instance(char *nline)
Xlatorp xp = NULL; Xlatorp xp = NULL;
BOOL behav_ret = TRUE; BOOL behav_ret = TRUE;
if (!hdr) {
return FALSE;
}
itype = hdr->instance_type; itype = hdr->instance_type;
xspice = find_xspice_for_delay(itype); xspice = find_xspice_for_delay(itype);
if (!xspice) { if (!xspice) {
@ -3916,6 +4041,10 @@ BOOL u_process_instance(char *nline)
} }
/* Skip past instance name, type, pwr, gnd */ /* Skip past instance name, type, pwr, gnd */
p1 = skip_past_words(nline, 4); p1 = skip_past_words(nline, 4);
if (!p1 || strlen(p1) == 0) {
delete_instance_hdr(hdr);
return FALSE;
}
if (is_gate(itype) || is_gate_array(itype)) { if (is_gate(itype) || is_gate_array(itype)) {
xp = translate_gate(hdr, p1); xp = translate_gate(hdr, p1);
} else if (is_tristate(itype) || is_tristate_array(itype)) { } else if (is_tristate(itype) || is_tristate_array(itype)) {
@ -3944,11 +4073,12 @@ BOOL u_process_instance(char *nline)
delete_xlator(xp); delete_xlator(xp);
return TRUE; return TRUE;
} else { } else {
if (current_subckt) {
fprintf(stderr, "ERROR in %s\n", current_subckt);
}
fprintf(stderr, "ERROR U* device syntax error\n");
fprintf(stderr, "ERROR at line \"%s\"\n", nline);
if (ps_udevice_exit) { if (ps_udevice_exit) {
if (current_subckt) {
fprintf(stderr, "ERROR in %s\n", current_subckt);
}
fprintf(stderr, "ERROR U* device syntax error\n");
fflush(stdout); fflush(stdout);
controlled_exit(EXIT_FAILURE); controlled_exit(EXIT_FAILURE);
} }

Loading…
Cancel
Save