From 036e1f0947dc72de8b011ef937b3c7f40bcc4905 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 1 Aug 2018 15:40:23 -0400 Subject: [PATCH] Modified the verilog reading code so that it will automatically determine if a parameter is a floating-point number, integer, or string, and set the parameter accordingly. Found an error in the parameter comparison if the subcircuit definitions don't agree on the type of parameter. Now all values are promoted to a single type based on preference order (double, integer, string). Tested on a verilog file with a primitive device type defined as a module with its properties encoded as parameters. This successfully matched against the SPICE primitive device. --- base/netcmp.c | 33 ++++++++++++++++++++++++++------- base/verilog.c | 27 ++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/base/netcmp.c b/base/netcmp.c index eb3d000..3d69fe6 100644 --- a/base/netcmp.c +++ b/base/netcmp.c @@ -4625,7 +4625,7 @@ PropertyCheckMismatch(struct objlist *tp1, struct nlist *tc1, { int mismatches = 0; int len2, *check2; - struct property *kl1, *kl2; + struct property *kl1, *kl2, *klt; struct valuelist *vl1, *vl2; int i, j; int islop; @@ -4797,8 +4797,27 @@ PropertyCheckMismatch(struct objlist *tp1, struct nlist *tc1, /* Promote properties as necessary to make sure they all match */ if (kl1->type != vl1->type) PromoteProperty(kl1, vl1); if (kl2->type != vl2->type) PromoteProperty(kl2, vl2); - if (kl1->type != vl2->type) PromoteProperty(kl1, vl2); - if (vl1->type != kl2->type) PromoteProperty(kl2, vl1); + + /* If kl1 and kl2 types differ, choose one type to target. Prefer */ + /* double if either type is double, otherwise string. */ + + if (kl1->type == PROP_DOUBLE) + klt = kl1; + else if (kl2->type == PROP_DOUBLE) + klt = kl2; + else if (kl1->type == PROP_INTEGER) + klt = kl1; + else if (kl2->type == PROP_INTEGER) + klt = kl2; + else if (kl1->type == PROP_STRING) + klt = kl1; + else if (kl2->type == PROP_STRING) + klt = kl2; + else + klt = kl1; + + if (vl2->type != klt->type) PromoteProperty(klt, vl2); + if (vl1->type != klt->type) PromoteProperty(klt, vl1); if (vl1->type != vl2->type) { if (do_print && (vl1->type != vl2->type)) { @@ -4849,13 +4868,13 @@ PropertyCheckMismatch(struct objlist *tp1, struct nlist *tc1, if (rval != NULL) mismatches++; } - else switch (kl1->type) { + else switch (klt->type) { case PROP_DOUBLE: case PROP_VALUE: dval1 = vl1->value.dval; dval2 = vl2->value.dval; - dslop = MAX(kl1->slop.dval, kl2->slop.dval); + dslop = klt->slop.dval; pd = 2 * fabs(dval1 - dval2) / (dval1 + dval2); if (pd > dslop) { if (do_print) { @@ -4883,7 +4902,7 @@ PropertyCheckMismatch(struct objlist *tp1, struct nlist *tc1, ival1 = vl1->value.ival; ival2 = vl2->value.ival; - islop = MAX(kl1->slop.ival, kl2->slop.ival); + islop = klt->slop.ival; if (abs(ival1 - ival2) > islop) { if (do_print) { if (mismatches == 0) @@ -4913,7 +4932,7 @@ PropertyCheckMismatch(struct objlist *tp1, struct nlist *tc1, } break; case PROP_STRING: - islop = (int)(MAX(kl1->slop.dval, kl2->slop.dval) + 0.5); + islop = (int)(klt->slop.dval + 0.5); if (islop == 0) { if (!(*matchfunc)(vl1->value.string, vl2->value.string)) { if (do_print) { diff --git a/base/verilog.c b/base/verilog.c index c78fc37..f72c380 100644 --- a/base/verilog.c +++ b/base/verilog.c @@ -375,7 +375,7 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr, char devtype, in_module, in_comment, in_param; char *eqptr, *parptr, *matchptr; struct keyvalue *kvlist = NULL; - char inst[256], model[256], instname[256], portname[256]; + char inst[256], model[256], instname[256], portname[256], pkey[256]; struct nlist *tp; struct objlist *parent, *sobj, *nobj, *lobj, *pobj; @@ -540,9 +540,30 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr, } } else if ((eqptr = strchr(nexttok, '=')) != NULL) { + double dval; + *eqptr = '\0'; - // Only String properties allowed - PropertyString(tp->name, filenum, nexttok, 0, eqptr + 1); + /* In case the variable name is not followed by whitespace */ + if (eqptr > nexttok) strcpy(pkey, nexttok); + eqptr++; + + // Equal sign may be followed by whitespace, in which case + // the parameter value is the next token. + if (strlen(eqptr) == 0) { + SkipTok(VLOG_DELIMITERS); /* get the next token */ + eqptr = nexttok; + } + + // Try first as a double, otherwise it's a string + // Double value's slop defaults to 1%. + if (ConvertStringToFloat(eqptr, &dval) == 1) + PropertyDouble(tp->name, filenum, pkey, 0.01, dval); + else + PropertyString(tp->name, filenum, pkey, 0, eqptr); + } + else { + /* Assume this is a keyword and save it */ + strcpy(pkey, nexttok); } } else {