fix: v not right for 2 c-e-connected NPN
authoryu.dongliang <18588496441@163.com>
Thu, 2 Nov 2023 04:05:28 +0000 (12:05 +0800)
committeryu.dongliang <18588496441@163.com>
Thu, 2 Nov 2023 04:05:28 +0000 (12:05 +0800)
ses_step_va_transistor.c

index a54240f84e28770e7cb716dc5a099947fefdebc6..a562111a5eb7ef4f6622d721c808588a5d0bb9be 100644 (file)
@@ -18,8 +18,8 @@ void __ses_path_dr_transistor(ScfEfunction* f, ses_path_t* path, int i, int j)
        p->dr  -= r;
        p->jdr -= jr;
 
-       scf_logd("c%ldp%ld, v: %lg, r: %lg, p->sr: %lg, p->a: %lg, p->dr: %lg\n",
-                       p->cid, p->id, v, r, p->sr, p->a, p->dr);
+       scf_logd("c%ldp%ld--c%ldp%ld, v: %lg, r: %lg, p->sr: %lg, p->a: %lg, p->dr: %lg\n",
+                       p->cid, p->id, p1->cid, p1->id, v, r, p->sr, p->a, p->dr);
 }
 
 int __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe)
@@ -151,7 +151,7 @@ static int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
        ScfEcomponent* B;
        ScfEline*      el;
        ScfEpin*       p0;
-       ScfEpin*       p1;
+       ScfEpin*       pj;
        ScfEpin*       Bp;
        ScfEpin*       Bn;
 
@@ -167,32 +167,23 @@ static int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
                Bn = parent->pins->data[parent->pins->size - 1];
        }
 
+       int i;
+       int j = path->pins->size - 1;
+
        p0 = path->pins->data[0];
-       p1 = path->pins->data[path->pins->size - 1];
+       pj = path->pins->data[j];
 
        el     = f->elines[p0->lid];
        p0->v  = el->v;
        p0->jv = el->jv;
 
-       el     = f->elines[p1->lid];
-       p1->v  = el->v;
-       p1->jv = el->jv;
-
-       int i;
-
-       for (i = 0; i < path->pins->size - 1; i++) {
-               pc =        path->pins->data[i];
-
-               c  = f->components[pc->cid];
-
-               if (SCF_EDA_NPN != c->type)
-                       continue;
-
-               if (SCF_EDA_NPN_C != pc->id)
-                       continue;
+       el     = f->elines[pj->lid];
+       pj->v  = el->v;
+       pj->jv = el->jv;
 
-               if (!pc->aconst)
-                       continue;
+       for (i = path->pins->size - 1; i >= 0; i--) {
+               pc = path->pins->data[i];
+               pj = path->pins->data[j];
 
                double v;
                double jv;
@@ -203,6 +194,42 @@ static int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
                double _pr;
                double _jpr;
 
+               c = f->components[pc->cid];
+
+               scf_logd("i: %d, c%ldp%ld--c%ldp%ld, pc->v: %lg, pc->a: %lg\n", i, p0->cid, p0->id, pc->cid, pc->id, pc->v, pc->a);
+
+               if (SCF_EDA_NPN != c->type || SCF_EDA_NPN_C != pc->id) {
+
+                       if (j < path->pins->size - 1) {
+
+                               pc->a  = pj->a;
+                               pc->ja = pj->ja;
+
+                               if (pc->lid != pj->lid) {
+
+                                       __ses_path_pr(f, path, i, j, NULL, &pr, &jpr);
+
+                                       ses_ir_u(&v, &jv, pj->a, pj->ja, pr, jpr);
+
+                                       pc->v  = p0->v  - v;
+                                       pc->jv = p0->jv - jv;
+
+                                       if (path->childs)
+                                               __ses_path_split_i(f, path, i, j, pj->a, pj->ja, &pc->a,  &pc->ja);
+
+                               } else {
+                                       pc->v  = pj->v;
+                                       pc->jv = pj->jv;
+                               }
+
+                               j = i;
+                       }
+                       continue;
+               }
+
+               if (!pc->aconst)
+                       continue;
+
                __ses_path_pr(f, path, 0, i, NULL, &pr, &jpr);
 
                ses_ir_u(&v, &jv, pc->a, pc->ja, pr, jpr);
@@ -210,25 +237,25 @@ static int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
                pc->v  = p0->v  - v;
                pc->jv = p0->jv - jv;
 
-               if (pc->v < p1->v) {
+               if (pc->v < pj->v) {
                        pr   += path->parent_r0;
                        jpr  += path->parent_jr0;
 
-                       v     = Bp->v  - p1->v;
-                       jv    = Bp->jv - p1->jv;
+                       v     = Bp->v  - pj->v;
+                       jv    = Bp->jv - pj->jv;
 
                        _pr   = pc->pr  + path->parent_r0;
                        _jpr  = pc->jpr + path->parent_jr0;
 
                        ses_ur_i(&pc->a, &pc->ja, v, jv, _pr, _jpr);
 
-                       scf_logd("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, _pr: %lg pc->pr: %lg\n",
-                                       i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, _pr, pc->pr);
-
                        ses_ir_u(&v, &jv, pc->a, pc->ja, pr, jpr);
 
                        pc->v  = Bp->v  - v;
                        pc->jv = Bp->jv - jv;
+
+                       scf_logd("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, _pr: %lg pc->pr: %lg\n",
+                                       i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, _pr, pc->pr);
                }
 
                el     = f->elines[pc->lid];
@@ -242,7 +269,7 @@ static int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
                                i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, pc->dr);
 
                if (path->childs) {
-                       __ses_path_split_i(f, path, i, path->pins->size - 1, el->a, el->ja, &pc->a,  &pc->ja);
+                       __ses_path_split_i(f, path, i, j, el->a, el->ja, &pc->a,  &pc->ja);
 
                        if (i > 0) {
                                p     = path->pins->data[i - 1];
@@ -258,10 +285,12 @@ static int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
                        p0->ja = el->ja;
                }
 
-               __ses_path_dr_transistor(f, path, i, path->pins->size - 1);
+               __ses_path_dr_transistor(f, path, i, j);
 
                scf_loge("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, pc->dr: %lg\n\n",
                                i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, pc->dr);
+
+               j = i;
        }
 
        return 0;