support 'capacitor' for oscillator.pack ok
authoryu.dongliang <18588496441@163.com>
Sat, 20 Apr 2024 13:40:02 +0000 (21:40 +0800)
committeryu.dongliang <18588496441@163.com>
Sat, 20 Apr 2024 13:40:50 +0000 (21:40 +0800)
main.c
scf_eda_pack.h
ses_core.h
ses_step_jr.c
ses_step_va.c
ses_step_va_capacitor.c
test/main.c

diff --git a/main.c b/main.c
index ac011ef4c21abdb422ddf648a1f7ea65374ea8ab..6a3f23191d9bec41b50660039c27fc930ab2a3ec 100644 (file)
--- a/main.c
+++ b/main.c
@@ -107,7 +107,7 @@ int main(int argc, char* argv[])
 
                printf("f: %s\n", f->name);
 
-               ses_steps_analyse(f, 1000, 16);
+               ses_steps_analyse(f, 1000, 8);
        }
 #endif
 
index 3acab9155edaf5c3e8dacc1e2cad1ed7c1647e42..c5ae79c5d71c4d9728ff95c6245efd37319fa9ab 100644 (file)
@@ -125,6 +125,9 @@ struct scf_epin_s
        SCF_PACK_DEF_VAR(double, sr);
        SCF_PACK_DEF_VAR(double, pr);
 
+       SCF_PACK_DEF_VAR(double, jsr);
+       SCF_PACK_DEF_VAR(double, jpr);
+
        SCF_PACK_DEF_VAR(uint64_t, path);
 
        SCF_PACK_DEF_VAR(int, x);
@@ -160,6 +163,8 @@ SCF_PACK_INFO_VAR(ScfEpin, dr),
 
 SCF_PACK_INFO_VAR(ScfEpin, sr),
 SCF_PACK_INFO_VAR(ScfEpin, pr),
+SCF_PACK_INFO_VAR(ScfEpin, jsr),
+SCF_PACK_INFO_VAR(ScfEpin, jpr),
 
 SCF_PACK_INFO_VAR(ScfEpin, path),
 SCF_PACK_INFO_VAR(ScfEpin, x),
index d8beb94473e6682a1423a39ba586be9d304ddb83..d5b35aac6d14cbcc8d6455cad4ebb15cd7e60aeb 100644 (file)
@@ -54,10 +54,14 @@ struct ses_path_s
        int            parent_p1;
 
        double         parent_pr;
+       double         parent_jpr;
 
        double         sr;
        double         pr;
 
+       double         jsr;
+       double         jpr;
+
        double         v;
        double         a;
 
@@ -120,7 +124,9 @@ double __ses_path_v_capacitor(ScfEfunction* f, ses_path_t* path);
 
 int  __ses_path_jr (ScfEfunction* f, ses_path_t* path);
 void __ses_path_pr (ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* child, double* r);
+void __ses_path_jpr(ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* child, double* jr);
 void __ses_path_sr (ScfEfunction* f, ses_path_t* path, int i, int j, double* r);
+void __ses_path_jsr(ScfEfunction* f, ses_path_t* path, int i, int j, double* jr);
 int  __ses_path_va (ScfEfunction* f, ses_path_t* path, int *changed, int64_t ns);
 int  __ses_path_da (ScfEfunction* f, ses_path_t* path, int* changed, double da);
 int  __ses_path_pos(ScfEfunction* f, ScfEline*   el);
index 30428c8512ae508dcc03979c1520755dc3845865..0dc3c637d7652545b3a31dd8ce93530ce95deb89 100644 (file)
@@ -38,6 +38,35 @@ void __ses_path_pr(ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t*
        }
 }
 
+void __ses_path_jsr(ScfEfunction* f, ses_path_t* path, int i, int j, double* jr)
+{
+       ScfEpin* p0 = path->pins->data[i];
+       ScfEpin* p1 = path->pins->data[j];
+
+       *jr = p1->jsr - p0->jpr;
+
+       scf_logd("c%ldp%ld-c%ldp%ld, jr: %lg, p0->jsr: %lg, p0->jpr: %lg, p1->jsr: %lg, p1->jpr: %lg\n",
+                       p0->cid, p0->id, p1->cid, p1->id, *jr, p0->jsr, p0->jpr, p1->jsr, p1->jpr);
+}
+
+void __ses_path_jpr(ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* child, double* jr)
+{
+       ScfEpin* p0 = path->pins->data[i];
+       ScfEpin* p1 = path->pins->data[j];
+
+       if (!child) {
+               *jr = p1->jpr - p0->jpr;
+
+               scf_logd("c%ldp%ld-c%ldp%ld, jr: %lg, p0->jpr: %lg, p1->jpr: %lg\n",
+                               p0->cid, p0->id, p1->cid, p1->id, *jr, p0->jpr, p1->jpr);
+       } else {
+               *jr = child->parent_jpr - p0->jpr;
+
+               scf_logd("c%ldp%ld-c%ldp%ld, jr: %lg, p0->jpr: %lg, p1->jpr: %lg, child->parent_jpr: %lg\n",
+                               p0->cid, p0->id, p1->cid, p1->id, *jr, p0->jpr, p1->jpr, child->parent_jpr);
+       }
+}
+
 int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
 {
        if (!path)
@@ -59,6 +88,9 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
        double r;
        double r2;
 
+       double jr;
+       double jr2;
+
        int    i;
        int    j;
 
@@ -72,7 +104,8 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
                }
        }
 
-       r = 0;
+       r  = 0;
+       jr = 0;
 
        for (i = 0; i < path->pins->size; i++) {
                p  =        path->pins->data[i];
@@ -81,18 +114,27 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
                r2 = r;
                r += p->r + p->dr + p->jdr;
 
-               if (i & 0x1)
-                       r += c->r + c->dr + c->jdr;
+               jr2 = jr;
+               jr += p->r + p->dr;
+
+               if (i & 0x1) {
+                       r  += c->r + c->dr + c->jdr;
+                       jr += c->r + c->dr;
+               }
 
                if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E != p->id) {
                        p->sr  = r2;
                        p->pr  = r2;
+                       p->jsr = jr2;
+                       p->jpr = jr2;
                } else {
                        p->sr  = r;
                        p->pr  = r;
+                       p->jsr = jr;
+                       p->jpr = jr;
                }
 
-               scf_loge("path: %d, i: %d, c%ldp%ld, sr: %lg\n", path->index, i, p->cid, p->id, p->sr);
+               scf_loge("path: %d, i: %d, c%ldp%ld, sr: %lg, jsr: %lg\n", path->index, i, p->cid, p->id, p->sr, p->jsr);
        }
 
        if (path->childs) {
@@ -137,35 +179,47 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
                        double pr;
                        double jpr;
 
-                       __ses_path_pr(f, path, k, j, NULL, &pr);
+                       __ses_path_pr (f, path, k, j, NULL, &pr);
+                       __ses_path_jpr(f, path, k, j, NULL, &jpr);
+
+                       ses_merge_r(&r,  NULL, pr,  0, child->pr,  0);
+                       ses_merge_r(&jr, NULL, jpr, 0, child->jpr, 0);
 
-                       ses_merge_r(&r, NULL, pr, 0, child->pr, 0);
+                       double dr  = pr  - r;
+                       double jdr = jpr - jr;
 
-                       double dr = pr  - r;
+                       p1->pr  -= dr;
+                       p1->jpr -= jdr;
 
-                       p1->pr -= dr;
-                       child->parent_pr = p1->pr;
+                       child->parent_pr  = p1->pr;
+                       child->parent_jpr = p1->jpr;
 
-                       scf_logi("j: %d, c%ldp%ld, p->pr: %lg, p->sr: %lg, pr: %lg, dr: %lg\n", j, p1->cid, p1->id, p1->pr, p1->sr, pr, dr);
+                       scf_logi("j: %d, c%ldp%ld,  p->pr: %lg,  p->sr: %lg,  pr: %lg,  dr: %lg\n", j, p1->cid, p1->id, p1->pr, p1->sr, pr, dr);
+                       scf_logi("j: %d, c%ldp%ld, p->jpr: %lg, p->jsr: %lg, jpr: %lg, jdr: %lg\n", j, p1->cid, p1->id, p1->jpr, p1->jsr, jpr, jdr);
 
                        for (++j; j < path->pins->size; j++) {
                                p       = path->pins->data[j];
 
-                               p->pr -= dr;
-                               p->sr -= dr;
+                               p->pr  -= dr;
+                               p->sr  -= dr;
+                               p->jpr -= jdr;
+                               p->jsr -= jdr;
 
-                               scf_logd("j: %d, c%ldp%ld, p->pr: %lg, p->sr: %lg\n", j, p->cid, p->id, p->pr, p->sr);
+                               scf_logd("j: %d, c%ldp%ld,  p->pr: %lg,  p->sr: %lg\n", j, p->cid, p->id, p->pr, p->sr);
+                               scf_logd("j: %d, c%ldp%ld, p->jpr: %lg, p->jsr: %lg\n", j, p->cid, p->id, p->jpr, p->jsr);
                        }
 
-                       scf_logw("child: %d, pr: %lg, dr: %lg\n", child->index, child->pr, dr);
+                       scf_logw("child: %d, pr: %lg, dr: %lg, jpr: %lg, jdr: %lg\n", child->index, child->pr, dr, child->jpr, jdr);
                }
        }
 
        p         = path->pins->data[path->pins->size - 1];
        path->pr  = p->pr;
        path->sr  = p->sr;
+       path->jpr = p->jpr;
+       path->jsr = p->jsr;
 
-       scf_loge("path: %d, pr: %lg, sr: %lg\n\n", path->index, path->pr, path->sr);
+       scf_loge("path: %d, pr: %lg, sr: %lg, jpr: %lg, jsr: %lg\n\n", path->index, path->pr, path->sr, path->jpr, path->jsr);
        return 0;
 }
 
index f3611bda656e6aa1e1a24aa167dbf69b17bf9adb..e90a53224e12789088998fcae32cd008880547ba 100644 (file)
@@ -41,27 +41,42 @@ static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, double*
                double r;
                double v;
 
-               __ses_path_pr(f, path, i, k, child, &r);
+               if (path->n_capacitors > 0) {
+                       __ses_path_jpr(f, path, i, k, child, &r);
 
-               ses_ir_u(&v, NULL, *a, 0, r, 0);
+                       ses_ir_u(&v, NULL, *a, 0, r, 0);
+
+                       ses_ur_i(&child->a0, NULL, v, 0, child->jpr, 0);
+               } else {
+                       __ses_path_pr(f, path, i, k, child, &r);
+
+                       ses_ir_u(&v, NULL, *a, 0, r, 0);
+
+                       ses_ur_i(&child->a0, NULL, v, 0, child->pr, 0);
+               }
 
                scf_logw("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d), v: %lg, a: %lg, r: %lg\n",
                                child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id, child->n_diodes, v, *a, r);
 
-               ses_ur_i(&child->a0, NULL, v, 0, child->pr, 0);
-
                *a    -= child->a0;
 
                el     = f->elines[p1->lid];
                el->v  = p0->v - v;
 
-               double _pr  = p1->pr;
-               double _sr  = p1->sr;
-               double _cpr = cp1->pr;
-               double _csr = cp1->sr;
+               double _pr   = p1->pr;
+               double _sr   = p1->sr;
+               double _jpr  = p1->jpr;
+               double _jsr  = p1->jsr;
+
+               double _cpr  = cp1->pr;
+               double _csr  = cp1->sr;
+               double _cjpr = cp1->jpr;
+               double _cjsr = cp1->jsr;
 
                cp1->pr  = child->pr;
                cp1->sr  = child->sr;
+               cp1->jpr = child->jpr;
+               cp1->jsr = child->jsr;
 
                if (child->n_diodes > 0) {
                        __ses_path_va_diode(f, child);
@@ -72,10 +87,15 @@ static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, double*
                if (ret < 0)
                        return ret;
 
-               cp1->pr = _cpr;
-               cp1->sr = _csr;
-               p1->pr  = _pr;
-               p1->sr  = _sr;
+               cp1->pr  = _cpr;
+               cp1->sr  = _csr;
+               cp1->jpr = _cjpr;
+               cp1->jsr = _cjsr;
+
+               p1->pr   = _pr;
+               p1->sr   = _sr;
+               p1->jpr  = _jpr;
+               p1->jsr  = _jsr;
 
                scf_loge("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d), p->v: %lg, v: %lg, child->a0: %lg, child->a: %lg\n\n",
                                child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id, child->n_diodes, p0->v, v, child->a0, child->a);
@@ -96,7 +116,10 @@ static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i,
        double v;
        double r;
 
-       __ses_path_sr(f, path, i0, i, &r);
+       if (path->n_capacitors > 0)
+               __ses_path_jsr(f, path, i0, i, &r);
+       else
+               __ses_path_sr(f, path, i0, i, &r);
 
        ses_ir_u(&v, NULL, a, 0, r, 0);
 
@@ -172,12 +195,12 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed, int64_t ns)
        if (path->n_capacitors > 0) {
                cv = __ses_path_v_capacitor(f, path);
                v -= cv;
-       }
-
-       ses_ur_i(&path->a, NULL, v, 0, path->pr, 0);
+               ses_ur_i(&path->a, NULL, v, 0, path->jpr, 0);
+       } else
+               ses_ur_i(&path->a, NULL, v, 0, path->pr, 0);
 
-       scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, r: %lg, a: %lg\n\n",
-                       path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, path->pr, path->a);
+       scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, r: %lg, jr: %lg, a: %lg\n\n",
+                       path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, path->pr, path->jpr, path->a);
 
        double a  = path->a;
        double r  = 0;
@@ -210,28 +233,38 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed, int64_t ns)
                r += p->r + p->dr + p->jdr;
 
                if (i & 0x1) {
+                       p2  = path->pins->data[i - 1];
                        c   = f->components[p->cid];
-                       r  += c->r + c->dr + c->jdr;
                        dv -= p->v;
+                       r  += c->r + c->dr + c->jdr;
 
                        ses_ur_i(&p->a, NULL, dv, 0, r, 0);
 
-                       p2 = path->pins->data[i - 1];
-
                        if (SCF_EDA_Capacitor == c->type) {
                                int sign = !p->id - p->id;
 
                                dv -= c->v * sign;
-
+                               r  -= c->jdr;
                                ses_ur_i(&p->a, NULL, dv, 0, r, 0);
 
                                c->v   += p->a * ns / 1e3 / c->uf * sign;
                                c->jdr  = c->v / p->a * sign - c->r;
 
-                               scf_logi("c%ld->v: %lg, dv: %lg, ja: %lg, ns: %ld, uf: %lg, c->jdr: %lg\n", c->id, c->v, dv, p->a, ns, c->uf, c->jdr);
+                               if (p->a > 0)
+                                       p2->v = p->v + c->v * sign;
+                               else
+                                       p->v  = p2->v - c->v * sign;
+
+                               scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ns: %ld, uf: %lg, c->jdr: %lg\n",
+                                               c->id, c->v, p->v, p2->v, dv, p->a, ns, c->uf, c->jdr);
+
+                               el    = f->elines[p->lid];
+                               el->v = p->v;
+                               __ses_status_check_line(f, el, changed);
 
-                               __ses_status_check_line(f, f->elines[p ->lid], changed);
-                               __ses_status_check_line(f, f->elines[p2->lid], changed);
+                               el    = f->elines[p2->lid];
+                               el->v = p2->v;
+                               __ses_status_check_line(f, el, changed);
                        }
 
                        p2->a = p->a;
index 1951253ab60e0f5f47365c98feba7e0fca72a9a8..2855a43a3a0ec439715c01d227f722620c58b2e4 100644 (file)
@@ -104,7 +104,7 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat
        if (p0->v - p1->v > cv) {
 
                jv = Bp->v - cv;
-               jr = flow0->pos_r + flow1->neg_r + bridge->pr;
+               jr = flow0->pos_r + flow1->neg_r + bridge->jpr;
                ja = jv / jr;
 
                p0->v = Bp->v - ja * flow0->pos_r;
@@ -115,7 +115,7 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat
 
        } else {
                jv = Bp->v + cv;
-               jr = flow1->pos_r + flow0->neg_r + bridge->pr;
+               jr = flow1->pos_r + flow0->neg_r + bridge->jpr;
                ja = jv / jr;
 
                p1->v = Bp->v - ja * flow1->pos_r;
index 651b143c6aa06d74c2fd01b2640f53de9c0c3280..2b2cff3bd163dbd9a2db22a712dd86191a3a89f1 100644 (file)
@@ -55,6 +55,8 @@ int main(int argc, char* argv[])
        T0->pins[SCF_EDA_NPN_C]->flags |= SCF_EDA_PIN_OUT;
        T1->pins[SCF_EDA_NPN_C]->flags |= SCF_EDA_PIN_OUT;
 
+       R0->r  = 1000;
+       R3->r  = 1000;
        C0->uf = 0.001;
        C1->uf = 0.001;