Compare commits

...
4 Commits
Author SHA1 Message Date
Tim Edwards aaf8fefc1a Merge branch 'master' into netgen-1.5 2024-10-16 02:00:02 -04:00
Tim Edwards e1aa231db1 Corrected another error discovered by Andrei Bondar in which
the critical property (e.g., L for transistors) is required to
match exactly between devices in order to allow the additive
property (e.g., W for transistors) to be summed.  The critical
property should match if all values are within the slop value,
for floating-point values.  Note:  The implementation is still
not rigorous, as the saved critical value may shift from
device to device;  so comparing, e.g., 1.00 to 1.01 to 1.02 to
1.03, etc., can find that all individual comparisons are within
the slop value even though the slop is exceeded across all values.
2024-10-15 20:52:23 -04:00
Tim Edwards abaf896f7f Merge branch 'master' into netgen-1.5 2024-10-15 02:00:02 -04:00
Tim Edwards df8fa29b2f Fixed an issue with property matching that was preventing the last-
ditch effort of matching based on combining devices with the same
critical property (e.g., adding gate widths together for transistors
of the same gate length, if the property records remain stubbornly
mismatched to the end).  Thanks to Bondar Andrey Renatovich for
surfacing this issue and providing a reproducible example.
2024-10-14 13:24:35 -04:00
2 changed files with 35 additions and 17 deletions
+1 -1
View File
@@ -1 +1 @@
1.5.282
1.5.284
+34 -16
View File
@@ -5169,26 +5169,34 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
// (if any)
if (comb == TRUE) {
double pd;
int mult, cidx = -1;
struct valuelist *avl, *cvl = NULL;
critval.type = PROP_ENDLIST;
critval.value.dval = 0.0;
for (i = 0; i < run; i++) {
avl = NULL;
if (vlist[0][i] == NULL) continue;
mult = vlist[0][i]->value.ival;
// if (vlist[0][i] == NULL) continue;
// mult = vlist[0][i]->value.ival;
if (vlist[0][i] == NULL)
mult = 1;
else
mult = vlist[0][i]->value.ival;
changed = 0;
/* For all properties that are not M, S, or crit, */
/* combine as specified by the merge type of the property. */
for (p = 1; p < pcount; p++) {
kl = plist[p];
vl = vlist[p][i];
ctype = clist[p][i];
/* critical properties never combine, but track them */
if ((series == TRUE) && (ctype & MERGE_S_CRIT)) {
if ((vl->type != critval.type) || (vl->value.dval != critval.value.dval))
pd = 2 * fabs(vl->value.dval - critval.value.dval) /
(vl->value.dval + critval.value.dval);
if ((vl->type != critval.type) || (pd > kl->slop.dval))
{
critval.type = vl->type;
critval.value = vl->value;
@@ -5197,7 +5205,9 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
continue;
}
if ((series == FALSE) && (ctype & MERGE_P_CRIT)) {
if ((vl->type != critval.type) || (vl->value.dval != critval.value.dval))
pd = 2 * fabs(vl->value.dval - critval.value.dval) /
(vl->value.dval + critval.value.dval);
if ((vl->type != critval.type) || (pd > kl->slop.dval))
{
critval.type = vl->type;
critval.value = vl->value;
@@ -5243,6 +5253,11 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
ctype = clist[p][i];
if (ctype & (MERGE_S_ADD | MERGE_P_ADD)) {
if (!vlist[0][i]) {
/* Create an entry with M = 0 to force removal */
vlist[0][i] = (struct valuelist *)CALLOC(1,
sizeof(struct valuelist));
}
vlist[0][i]->value.ival = 0; /* set M to 0 */
if (cvl && (cvl->type == PROP_INTEGER))
{
@@ -5262,6 +5277,11 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
}
}
else if (ctype & (MERGE_S_PAR | MERGE_P_PAR)) {
if (!vlist[0][i]) {
/* Create an entry with M = 0 to force removal */
vlist[0][i] = (struct valuelist *)CALLOC(1,
sizeof(struct valuelist));
}
vlist[0][i]->value.ival = 0; /* set M to 0 */
/* To do parallel combination, both types need to
* be double, so recast them if they are integer.
@@ -6250,22 +6270,20 @@ PropertyMatch(struct Element *E1, struct Element *E2,
int multmatch, count;
PropertyCheckMismatch(tp1, tc1, inst1, tp2, tc2,
inst2, E1, E2, FALSE, FALSE, &multmatch, NULL);
if (multmatch == 1) {
/* Final attempt: Reduce M to 1 on both devices */
run1 = run2 = 0;
for (tpc = tp1; tpc && (tpc->type == PROPERTY); tpc = tpc->next) run1++;
for (tpc = tp2; tpc && (tpc->type == PROPERTY); tpc = tpc->next) run2++;
PropertyOptimize(tp1, tc1, run1, FALSE, TRUE);
PropertyOptimize(tp2, tc2, run2, FALSE, TRUE);
}
else if (multmatch == 2) {
run1 = run2 = 0;
for (tpc = tp1; tpc && (tpc->type == PROPERTY); tpc = tpc->next) run1++;
for (tpc = tp2; tpc && (tpc->type == PROPERTY); tpc = tpc->next) run2++;
if (multmatch == 2) {
/* Final attempt: Reduce S to 1 on both devices */
run1 = run2 = 0;
for (tpc = tp1; tpc && (tpc->type == PROPERTY); tpc = tpc->next) run1++;
for (tpc = tp2; tpc && (tpc->type == PROPERTY); tpc = tpc->next) run2++;
PropertyOptimize(tp1, tc1, run1, TRUE, TRUE);
PropertyOptimize(tp2, tc2, run2, TRUE, TRUE);
}
else if ((multmatch == 1) || (run1 != run2)) {
/* Final attempt: Reduce M to 1 on both devices */
PropertyOptimize(tp1, tc1, run1, FALSE, TRUE);
PropertyOptimize(tp2, tc2, run2, FALSE, TRUE);
}
#ifdef TCL_NETGEN
mlist =
#endif