ses_step_va_bridge.c
authoryu.dongliang <18588496441@163.com>
Sat, 16 Mar 2024 15:38:05 +0000 (23:38 +0800)
committeryu.dongliang <18588496441@163.com>
Sat, 16 Mar 2024 15:38:05 +0000 (23:38 +0800)
Makefile
ses_core.h
ses_step_da.c [new file with mode: 0644]
ses_step_jr.c
ses_step_va.c
ses_step_va_balance.c
ses_step_va_bridge.c
ses_steps.c
ses_utils.c

index e61f46b39cedc2f58944b9a41b53ac0646308beb..68e2d7fdb3ec5aac7b76ed7e95f7b07494fb84b1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -20,6 +20,7 @@ CFILES += ses_step_va_transistor.c
 CFILES += ses_step_va.c 
 CFILES += ses_step_va_bridge.c
 CFILES += ses_step_va_balance.c
+CFILES += ses_step_da.c
 CFILES += ses_step_output.c
 
 CFLAGS += -g -D_GNU_SOURCE
index e29da74f8493413623fc8b52e22b36c706b3239f..8dfeffc0dc3ea48b64c5df64a7fcb0819769b988 100644 (file)
@@ -15,6 +15,7 @@ struct ses_flow_s
        scf_vector_t*  paths;
 
        ScfEpin*       vip;
+       ScfEpin*       vip_n;
 
        int            pos_pins;
        int            neg_pins;
@@ -78,6 +79,9 @@ struct ses_path_s
        double         a;
        double         ja;
 
+       double         da;
+       double         dja;
+
        int            type;
        int            index;
 
@@ -112,7 +116,7 @@ void        ses_flow_print(ses_flow_t* flow);
 
 void        ses_flow_v_pos(ses_flow_t* flow, double a, double ja);
 void        ses_flow_v_neg(ses_flow_t* flow, double a, double ja);
-void        ses_flow_jr   (ses_flow_t* flow);
+void        ses_flow_jr   (ses_flow_t* flow, ScfEfunction* f);
 
 ses_ctx_t*  ses_ctx_alloc();
 void        ses_ctx_free (ses_ctx_t* ctx);
@@ -124,15 +128,21 @@ int ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count);
 int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, ses_path_t* bridge);
 
 void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double la, double jla, double* a, double* ja);
-void __ses_path_pr     (ScfEfunction* f, ses_path_t* path, int i, int j, ScfEpin* cp1, double* r, double* jr);
-void __ses_path_sr     (ScfEfunction* f, ses_path_t* path, int i, int j, ScfEpin* cp1, double* r, double* jr);
-int  __ses_path_va     (ScfEfunction* f, ses_path_t* path, int *changed);
-int  __ses_path_pos    (ScfEfunction* f, ScfEline*   el);
-int  __ses_path_neg    (ScfEfunction* f, ScfEline*   el);
-
 int  __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe);
 int  __ses_topo_paths  (ScfEfunction* f, scf_vector_t*  paths);
 
+int  __ses_path_jr (ScfEfunction* f, ses_path_t* path);
+void __ses_path_pr (ScfEfunction* f, ses_path_t* path, int i, int j, ScfEpin* cp1, double* r, double* jr);
+void __ses_path_sr (ScfEfunction* f, ses_path_t* path, int i, int j, ScfEpin* cp1, double* r, double* jr);
+int  __ses_path_va (ScfEfunction* f, ses_path_t* path, int *changed);
+int  __ses_path_da (ScfEfunction* f, ses_path_t* path, int *changed, double da, double dja);
+int  __ses_path_pos(ScfEfunction* f, ScfEline*   el);
+int  __ses_path_neg(ScfEfunction* f, ScfEline*   el);
+void __ses_npn_epr (ScfEfunction* f, ScfEpin*    pe, double* r, double* jr);
+void __ses_npn_dr (ScfEcomponent* c, ScfEpin*    pb, ScfEpin* pe);
+void __ses_pn_dr  (ScfEcomponent* c, ScfEpin*    pb, ScfEpin* pe);
+
+
 static inline void vertical(int* px, int* py, int dx, int dy, int d)
 {
        /*
diff --git a/ses_step_da.c b/ses_step_da.c
new file mode 100644 (file)
index 0000000..790f06a
--- /dev/null
@@ -0,0 +1,270 @@
+#include"ses_core.h"
+
+static int __ses_path_split_da(ScfEfunction* f, ses_path_t* path, int i, double* da, double *dja, int* changed)
+{
+       ses_path_t*    child;
+
+       ScfEcomponent* c;
+       ScfEline*      el;
+       ScfEpin*       p;
+       ScfEpin*       p2;
+       ScfEpin*       cp0;
+       ScfEpin*       cp1;
+
+       int j;
+       int k;
+       int n = 0;
+
+       p = path->pins->data[i];
+
+       for (j    = 0; j < path->childs->size; j++) {
+               child =        path->childs->data[j];
+
+               cp0 = child->pins->data[0];
+               cp1 = child->pins->data[child->pins->size - 1];
+
+               if (p->lid != cp0->lid)
+                       continue;
+
+               for (k = i + 1; k < path->pins->size; k++) {
+                       p2 =            path->pins->data[k];
+
+                       if (p2->lid == cp1->lid)
+                               break;
+               }
+
+               if (k >= path->pins->size) {
+                       scf_loge("\n");
+                       return -EINVAL;
+               }
+
+               double _r  = p2->pr  - p->pr;
+               double _jr = p2->jpr - p->jpr;
+
+               double _dv  = 0;
+               double _djv = 0;
+               double _da  = 0;
+               double _dja = 0;
+
+               __ses_path_pr(f, path, i, k, cp1, &_r, &_jr);
+
+               ses_ir_u(&_dv, &_djv, *da, *dja, _r, _jr);
+
+               scf_logw("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld), _dv: %lg, da: %lg, _r: %lg, p->pr: %lg, p->dr: %lg, p2->pr: %lg\n",
+                               child->index, p->cid, p->id, p2->cid, p2->id, cp0->cid, cp0->id, cp1->cid, cp1->id, _dv, *da, _r, p->pr, p->dr, p2->pr);
+
+               ses_ur_i(&_da, &_dja, _dv, _djv, child->r, child->jr);
+
+               *da    -= _da;
+               *dja   -= _dja;
+
+               el      = f->elines[p2->lid];
+               el->v  -= _dv;
+               el->jv -= _djv;
+
+               scf_loge("child: %d, c%ldp%ld, c%ldp%ld, p->v: %lg, el->v: %lg, _dv: %lg\n",
+                               child->index, p->cid, p->id, p2->cid, p2->id, p->v, el->v, _dv);
+
+               int ret = __ses_path_da(f, child, changed, _da, _dja);
+               if (ret < 0)
+                       return ret;
+
+               n++;
+       }
+
+       scf_logw("*****************\n");
+       return n;
+}
+
+static void __ses_path_split_dv(ScfEfunction* f, ses_path_t* path, int i0, int i, double da, double dja)
+{
+       ScfEcomponent* B  = f->components[0];
+       ScfEpin*       Bp = B->pins[SCF_EDA_Battery_POS];
+       ScfEpin*       Bn = B->pins[SCF_EDA_Battery_NEG];
+       ScfEpin*       p0 = path->pins->data[i0];
+       ScfEpin*       p  = path->pins->data[i];
+
+       double   dv;
+       double   djv;
+       double   r;
+       double   jr;
+
+       __ses_path_sr(f, path, i0, i, NULL, &r, &jr);
+
+       ses_ir_u(&dv, &djv, da, dja, r, jr);
+
+       if (p->lid != Bp->lid && p->lid != Bn->lid) {
+               p->v  -= dv;
+               p->jv -= djv;
+       }
+
+       scf_logd("c%ldp%ld, c%ldp%ld, da: %lg, r: %lg, dv: %lg\n", p0->cid, p0->id, p->cid, p->id, da, r, dv);
+}
+
+void __ses_pn_dr(ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe)
+{
+       double v  = pb->v  - pe->v;
+       double jv = pb->jv - pe->jv;
+       double r;
+       double jr;
+
+       if (v >= SCF_EDA_V_Diode_ON) {
+
+               ses_ui_r(&r, &jr, v, jv, pb->a, pb->ja);
+               pe->dr = r - pe->r;
+
+       } else if (v > SCF_EDA_V_Diode_OFF)
+               pe->dr = pb->r * (SCF_EDA_V_Diode_ON - SCF_EDA_V_Diode_OFF) / (v - SCF_EDA_V_Diode_OFF + 0.001);
+       else
+               pe->dr = 1e12;
+}
+
+void __ses_npn_dr(ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe)
+{
+       double v  = pb->v  - pe->v;
+       double jv = pb->jv - pe->jv;
+       double r;
+       double jr;
+
+       if (v >= SCF_EDA_V_NPN_ON) {
+
+               ses_ui_r(&r, &jr, v, jv, pb->a, pb->ja);
+               pb->dr = r - pb->r;
+
+       } else if (v > SCF_EDA_V_NPN_OFF)
+               pb->dr = pb->r * (SCF_EDA_V_NPN_ON - SCF_EDA_V_NPN_OFF) / (v - SCF_EDA_V_NPN_OFF + 0.001);
+       else
+               pb->dr = 1e12;
+
+       scf_loge("v: %lg, pb->dr: %lg\n", v, pb->dr);
+}
+
+int __ses_path_da(ScfEfunction* f, ses_path_t* path, int* changed, double da, double dja)
+{
+       if (!path)
+               return -EINVAL;
+
+       if (path->pins->size < 2) {
+               scf_loge("\n");
+               return -EINVAL;
+       }
+
+       ses_path_t*    child;
+       ScfEcomponent* c;
+       ScfEline*      el;
+       ScfEpin*       p;
+       ScfEpin*       p0;
+       ScfEpin*       p1;
+       ScfEpin*       p2;
+       ScfEpin*       cp0;
+       ScfEpin*       cp1;
+
+       int i;
+       int j;
+
+       double r   = 0;
+       double jr  = 0;
+       double dv  = 0;
+       double jdv = 0;
+
+       path->da  = da;
+       path->dja = dja;
+
+       int i0 = 0;
+
+       for (i = 0; i < path->pins->size; i++) {
+               p  =        path->pins->data[i];
+
+               if (!(i & 0x1) && path->childs) {
+
+                       __ses_path_split_dv(f, path, i0, i, da, dja);
+
+                       int ret = __ses_path_split_da(f, path, i, &da, &dja, changed);
+                       if (ret < 0)
+                               return ret;
+
+                       if (ret > 0) {
+                               p0 = p;
+                               i0 = i;
+                               scf_logd("i: %d, p0: c%ldp%ld\n", i, p0->cid, p0->id);
+                       }
+               } else
+                       __ses_path_split_dv(f, path, i0, i, da, dja);
+
+               el     = f->elines[p->lid];
+               el->v  = p->v;
+               el->jv = p->jv;
+
+               r     += p->r  + p->dr;
+               jr    += p->jr + p->jdr;
+
+               if (i & 0x1) {
+                       c    = f->components[p->cid];
+                       r   += c->r;
+                       jr  += c->jr;
+
+                       dv  -= p->v;
+                       jdv -= p->jv;
+
+                       p->a  += da;
+                       p->ja += dja;
+
+                       p2      = path->pins->data[i - 1];
+                       p2->a  += da;
+                       p2->ja += dja;
+
+                       if (path->childs) {
+                               for (j    = 0; j < path->childs->size; j++) {
+                                       child =        path->childs->data[j];
+
+                                       cp0 = child->pins->data[0];
+                                       cp1 = child->pins->data[child->pins->size - 1];
+
+                                       if (p->lid == cp1->lid) {
+                                               da  += child->da;
+                                               dja += child->dja;
+
+                                               scf_logd("path: %d, i: %d, c%ldp%ld, child->da: %lg\n", child->index, i, cp1->cid, cp1->id, child->da);
+                                       }
+                               }
+                       }
+
+                       scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, r: %lg, p->a: %lg, da: %lg, p->pr: %lg\n\n", path->index, i, p->cid, p->id,
+                                       p->v, dv, r, p->a, da, p->pr);
+
+                       if (SCF_EDA_Diode == c->type) {
+
+                               if (SCF_EDA_Diode_NEG == p->id) {
+                                       p2 = path->pins->data[i - 1];
+
+                                       *changed += __ses_status_check(f, c, p2, p);
+
+                                       __ses_pn_dr(c, p2, p);
+                               }
+
+                       } else if (SCF_EDA_NPN == c->type) {
+
+                               if (SCF_EDA_NPN_E == p->id) {
+                                       p2 = path->pins->data[i - 1];
+
+                                       if (SCF_EDA_NPN_B == p2->id) {
+                                               *changed += __ses_status_check(f, c, p2, p);
+
+                                               __ses_npn_dr(c, p2, p);
+                                       }
+                               }
+                       }
+
+                       r   = 0;
+                       jr  = 0;
+               } else {
+                       dv  = p->v;
+                       jdv = p->jv;
+
+                       scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, p->a: %lg, da: %lg, p->pr: %lg\n", path->index, i, p->cid, p->id, p->v, dv, p->a, da, p->pr);
+               }
+       }
+       printf("\n");
+
+       return 0;
+}
index 0290e7a1f8c4f0c57958be553cdc4b9c2b424b5c..6a7c497e44a0ddc736e9734b8b2b22e4c814fe13 100644 (file)
@@ -132,7 +132,7 @@ void __ses_path_pr(ScfEfunction* f, ses_path_t* path, int i, int j, ScfEpin* cp1
        scf_logd("c%ldp%ld-c%ldp%ld, r: %lg, p0->pr: %lg, p1->pr: %lg\n", p0->cid, p0->id, p1->cid, p1->id, *r, p0->pr, p1->pr);
 }
 
-static int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
+int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
 {
        if (!path)
                return -EINVAL;
index 4f396c9972ff026db84850c450d47b166e249915..a2e963ec1ad69d072c6244d1030c6a2e480389a7 100644 (file)
@@ -213,7 +213,10 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed)
 
                                if (SCF_EDA_Diode_NEG == p->id) {
                                        p2 = path->pins->data[i - 1];
+
                                        *changed += __ses_status_check(f, c, p2, p);
+
+                                       __ses_pn_dr(c, p2, p);
                                }
 
                        } else if (SCF_EDA_NPN == c->type) {
@@ -221,8 +224,11 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed)
                                if (SCF_EDA_NPN_E == p->id) {
                                        p2 = path->pins->data[i - 1];
 
-                                       if (SCF_EDA_NPN_B == p2->id)
+                                       if (SCF_EDA_NPN_B == p2->id) {
                                                *changed += __ses_status_check(f, c, p2, p);
+
+                                               __ses_npn_dr(c, p2, p);
+                                       }
                                }
                        }
 
index 7db3b0f76b0ae74f4c1ee542d2b63c928564003c..16fc24c98bd71060147029c7f24961219df0ca44 100644 (file)
@@ -210,14 +210,14 @@ static int _va_balance_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_c
                ses_flow_print(flow0);
                printf("\n");
 
-               ses_flow_jr(flow0);
+               ses_flow_jr(flow0, f);
 
                printf("-------------\n");
 
                ses_flow_print(flow1);
                printf("\n");
 
-               ses_flow_jr(flow1);
+               ses_flow_jr(flow1, f);
                printf("-------------\n");
 
                ret = __ses_path_va_balance(f, bridge, flow0, flow1);
index e1498972886c8939a8ad4d95bb820705054350ac..cdee3a9dade809ce040e01027dc8baf890736f16 100644 (file)
@@ -1,6 +1,6 @@
 #include"ses_core.h"
 
-int __ses_flow_a_pos(ScfEfunction* f, ses_flow_t* flow, double da_vip, double dja_vip)
+int __ses_flow_a_pos(ScfEfunction* f, ses_flow_t* flow, double da_vip, double dja_vip, int* changed)
 {
        if (!flow || !flow->paths || flow->paths->size <= 0 || !flow->vip)
                return -EINVAL;
@@ -51,7 +51,7 @@ int __ses_flow_a_pos(ScfEfunction* f, ses_flow_t* flow, double da_vip, double dj
                                ses_ir_u(&v, &jv, da_vip, dja_vip, r, jr);
                        }
 
-                       if (p->lid != Bp->lid) {
+                       if (p->v - v < Bp->lid) {
                                p->v   -= v;
                                p->jv  -= jv;
 
@@ -59,7 +59,10 @@ int __ses_flow_a_pos(ScfEfunction* f, ses_flow_t* flow, double da_vip, double dj
                                el->v   = p->v;
                                el->jv  = p->jv;
                        }
-                       scf_logw("c%ldp%ld->v: %lg, r: %lg, l%ld->v: %lg\n", p->cid, p->id, p->v, r, el->id, el->v);
+
+                       p->a  += da_vip;
+                       p->ja += dja_vip;
+                       scf_logw("c%ldp%ld->v: %lg, p->a: %lg, r: %lg, l%ld->v: %lg\n", p->cid, p->id, p->v, p->a, r, el->id, el->v);
 
                        if (!(j & 0x1)) {
                                r  = 0;
@@ -73,7 +76,7 @@ int __ses_flow_a_pos(ScfEfunction* f, ses_flow_t* flow, double da_vip, double dj
        return 0;
 }
 
-int __ses_flow_v_neg(ScfEfunction* f, ses_flow_t* flow, double dv_vip, double djv_vip)
+int __ses_flow_v_neg(ScfEfunction* f, ses_flow_t* flow, double dv_vip, double djv_vip, int* changed)
 {
        if (!flow || !flow->paths || flow->paths->size <= 0 || !flow->vip)
                return -EINVAL;
@@ -86,6 +89,7 @@ int __ses_flow_v_neg(ScfEfunction* f, ses_flow_t* flow, double dv_vip, double dj
        ses_path_t*    path = flow->paths->data[flow->paths->size - 1];
        ScfEpin*       vip  = flow->vip;
        ScfEpin*       p;
+       ScfEpin*       p2;
        ScfEline*      el;
 
        double v  = dv_vip;
@@ -127,7 +131,7 @@ int __ses_flow_v_neg(ScfEfunction* f, ses_flow_t* flow, double dv_vip, double dj
                                ses_ir_u(&v, &jv, da, dja, r, jr);
                        }
 
-                       if (p->lid != Bn->lid) {
+                       if (p->v + v > Bn->lid) {
                                p->v   += v;
                                p->jv  += jv;
 
@@ -136,9 +140,35 @@ int __ses_flow_v_neg(ScfEfunction* f, ses_flow_t* flow, double dv_vip, double dj
                                el->jv  = p->jv;
                        }
 
-                       scf_logw("c%ldp%ld->v: %lg, r: %lg, v: %lg, l%ld->v: %lg\n", p->cid, p->id, p->v, r, v, el->id, el->v);
+                       p->a  += da;
+                       p->ja += dja;
+
+                       scf_logw("c%ldp%ld->v: %lg, p->a: %lg, r: %lg, v: %lg, l%ld->v: %lg\n", p->cid, p->id, p->v, p->a, r, v, el->id, el->v);
 
                        if (j & 0x1) {
+                               if (SCF_EDA_Diode == c->type) {
+
+                                       if (SCF_EDA_Diode_NEG == p->id) {
+                                               p2 = path->pins->data[j - 1];
+
+                                               *changed += __ses_status_check(f, c, p2, p);
+
+                                               __ses_pn_dr(c, p2, p);
+                                       }
+
+                               } else if (SCF_EDA_NPN == c->type) {
+
+                                       if (SCF_EDA_NPN_E == p->id) {
+                                               p2 = path->pins->data[j - 1];
+
+                                               if (SCF_EDA_NPN_B == p2->id) {
+                                                       *changed += __ses_status_check(f, c, p2, p);
+
+                                                       __ses_npn_dr(c, p2, p);
+                                               }
+                                       }
+                               }
+
                                r  = 0;
                                jr = 0;
                        }
@@ -162,8 +192,6 @@ static int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* change
 
        ses_flow_t*    flow;
        ses_path_t*    fpath;
-       ScfEpin*       fp0;
-       ScfEpin*       fp1;
 
        ScfEcomponent* B;
        ScfEline*      el;
@@ -182,14 +210,6 @@ static int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* change
        if (p0->lid == Bp->lid && p1->lid == Bn->lid)
                return 0;
 
-       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;
-
        flow = ses_flow_alloc();
        if (!flow)
                return -ENOMEM;
@@ -201,14 +221,12 @@ static int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* change
        }
 
        ses_flow_print(flow);
-       ses_flow_jr(flow);
+       ses_flow_jr(flow, f);
 
        fpath = flow->paths->data[flow->paths->size - 1];
-       fp0   = fpath->pins->data[0];
-       fp1   = fpath->pins->data[fpath->pins->size - 1];
 
-       scf_logw("flow vip: c%ldp%ld->a: %lg, fp0: c%ldp%ld->a: %lg, fp1: c%ldp%ld->a: %lg\n\n",
-                       flow->vip->cid, flow->vip->id, flow->vip->a, fp0->cid, fp0->id, fp0->a, fp1->cid, fp1->id, fp1->a);
+       scf_logw("flow vip: c%ldp%ld->a: %lg, vip_n: c%ldp%ld->a: %lg\n\n",
+                       flow->vip->cid, flow->vip->id, flow->vip->a, flow->vip_n->cid, flow->vip_n->id, flow->vip_n->a);
 
        double da;
        double dja;
@@ -218,28 +236,39 @@ static int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* change
 
        double a   = 0;
        double ja  = 0;
-       double Eta = 0.01;
+       double Eta = 0.001;
 
        int k = 0;
        do {
                scf_logw("k: %d, ****************\n", k);
 
+               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;
+
                ret = __ses_path_va(f, bridge, changed);
                if (ret < 0)
                        return ret;
 
+               __ses_path_jr(f, bridge);
+
                da  = bridge->a  - a;
                dja = bridge->ja - ja;
 
                a  += Eta * da;
                ja += Eta * dja;
 
-               scf_loge("da: %lg, a: %lg\n", da, a);
+               scf_loge("da: %lg, a: %lg, bridge->a: %lg, bridge->r: %lg, p0->v: %lg, p1->v: %lg\n",
+                               da, a, bridge->a, bridge->r, p0->v, p1->v);
 
                v  = flow->vip->v;
                jv = flow->vip->jv;
 
-               ret = __ses_flow_a_pos(f, flow, Eta * da, Eta * dja);
+               ret = __ses_flow_a_pos(f, flow, Eta * da, Eta * dja, changed);
                if (ret < 0)
                        return ret;
 
@@ -248,13 +277,21 @@ static int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* change
 
                scf_logi("dv: %lg, v: %lg - %lg ----------------\n", dv, flow->vip->v, v);
 
-               ret = __ses_flow_v_neg(f, flow, dv, djv);
+               ret = __ses_flow_v_neg(f, flow, dv, djv, changed);
                if (ret < 0)
                        return ret;
-               printf("\n");
+
+               __ses_path_jr(f, fpath);
+               ses_flow_jr(flow, f);
+
+               scf_logw("flow vip: c%ldp%ld->a: %lg, vip_n: c%ldp%ld->a: %lg, bridge->a: %lg, diff: %lg\n\n",
+                               flow->vip->cid, flow->vip->id, flow->vip->a,
+                               flow->vip_n->cid, flow->vip_n->id, flow->vip_n->a,
+                               bridge->a,
+                               flow->vip->a - flow->vip_n->a - bridge->a);
 
                k++;
-       } while (da > 1e-4);
+       } while (fabs(flow->vip->a - flow->vip_n->a - bridge->a) > 1e-4);
 
        v  = p0->v  - p1->v;
        jv = p0->jv - p1->jv;
index 204bbab7b4fa979f9735dc2d6e97ebde6dd05495..044cbc92bcf8c946bf7e101167eb50e19858cc48 100644 (file)
@@ -144,7 +144,7 @@ int ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count)
                        return ret;
 
                int j;
-               for (j = 0; j < 1; j++) {
+               for (j = 0; j < 3; j++) {
                        printf("\n\033[33m%s(), %d(), j: %d\033[0m\n", __func__, __LINE__, j);
 
                        ret = __ses_steps_analyse(f, ns, i, ctx);
index 554aee429d2bb607610e6fb5fe6130f0ca37c5c6..6444795834f838f219a6cef58d05a39961667fb6 100644 (file)
@@ -43,7 +43,14 @@ int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, ses
                        p  =        path->pins->data[j];
 
                        if (vip ->lid == p->lid) {
-                               flow->vip  = p;
+
+                               if (j + 1 >= path->pins->size) {
+                                       scf_loge("ses_paths_find_flow error\n");
+                                       return -1;
+                               }
+
+                               flow->vip   = p;
+                               flow->vip_n = path->pins->data[j + 1];;
 
                                if (scf_vector_add(flow->paths, path) < 0)
                                        return -1;
@@ -68,7 +75,7 @@ int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, ses
        return 0;
 }
 
-void ses_flow_jr(ses_flow_t* flow)
+void ses_flow_jr(ses_flow_t* flow, ScfEfunction* f)
 {
        if (!flow)
                return;
@@ -85,10 +92,11 @@ void ses_flow_jr(ses_flow_t* flow)
        if (!flow->paths || !flow->vip)
                return;
 
-       ses_path_t* path;
-       ScfEpin*    p;
-       ScfEpin*    p0;
-       ScfEpin*    vip = flow->vip;
+       ses_path_t*    path;
+       ScfEcomponent* c;
+       ScfEpin*       p;
+       ScfEpin*       p0;
+       ScfEpin*       vip = flow->vip;
 
        int i;
        int j;
@@ -104,12 +112,19 @@ void ses_flow_jr(ses_flow_t* flow)
                        if (p->lid == vip->lid) {
 
                                vip = path->pins->data[0];
+                               c   = f->components[p->cid];
+
+                               double pr  = p->pr;
+                               double jpr = p->jpr;
 
-                               flow->pos_r  += p->pr;
-                               flow->pos_jr += p->jpr;
+                               if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id)
+                                       __ses_npn_epr(f, p, &pr, &jpr);
 
-                               scf_logd("flow->pos_r: %lg, c%ldp%ld->pr: %lg, vip c%ldp%ld->pr: %lg\n",
-                                               flow->pos_r, p->cid, p->id, p->pr, vip->cid, vip->id, vip->pr);
+                               flow->pos_r  += pr;
+                               flow->pos_jr += jpr;
+
+                               scf_logd("flow->pos_r: %lg, c%ldp%ld->pr: %lg, pr: %lg, vip c%ldp%ld->pr: %lg\n",
+                                               flow->pos_r, p->cid, p->id, p->pr, pr, vip->cid, vip->id, vip->pr);
                                break;
                        }
                }
@@ -132,14 +147,34 @@ void ses_flow_jr(ses_flow_t* flow)
 
                        ++flow->neg_pins;
 
-                       if (p->sr != p->pr) {
+                       c = f->components[p->cid];
+
+                       if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id) {
+                               p = path->pins->data[j - 1];
+
+                               if (p == p0) {
+                                       flow->neg_r  += p->r  + p->dr;
+                                       flow->neg_jr += p->jr + p->jdr;
+                               } else {
+                                       flow->neg_r  += p->pr  - p0->pr;
+                                       flow->neg_jr += p->jpr - p0->jpr;
+                               }
+
+                               scf_loge("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+                                               flow->neg_r, p->cid, p->id, p->sr, p0->cid, p0->id, p0->pr);
+
+                               if (j + 1 < path->pins->size)
+                                       p0    = path->pins->data[j + 1];
+                               else
+                                       p0    = path->pins->data[j];
+
+                       } else if (p->sr != p->pr) {
 
                                flow->neg_r  += p->sr  - p0->pr;
                                flow->neg_jr += p->jsr - p0->jpr;
 
-                               scf_logd("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+                               scf_logw("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
                                                flow->neg_r, p->cid, p->id, p->sr, p0->cid, p0->id, p0->pr);
-
                                p0 = p;
                        }
                }
@@ -151,9 +186,11 @@ void ses_flow_jr(ses_flow_t* flow)
                if (vip != p0) {
                        flow->neg_r  += vip->sr  - p0->pr;
                        flow->neg_jr += vip->jsr - p0->jpr;
+                       scf_loge("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+                                       flow->neg_r, vip->cid, vip->id, vip->sr, p0->cid, p0->id, p0->pr);
                }
 
-               scf_logd("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+               scf_logi("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
                                flow->neg_r, vip->cid, vip->id, vip->sr, p0->cid, p0->id, p0->pr);
        }