support Inductor for examples/colpitts_oscillator.cpk
authoryu.dongliang <18588496441@163.com>
Wed, 5 Jun 2024 13:52:32 +0000 (21:52 +0800)
committeryu.dongliang <18588496441@163.com>
Wed, 5 Jun 2024 13:52:32 +0000 (21:52 +0800)
22 files changed:
Makefile
examples/colpitts_oscillator.cpk [new file with mode: 0644]
main.c
scf_eda_pack.c
ses_core.h
ses_layout.c
ses_layout_topo.c [new file with mode: 0644]
ses_node_analysis.c
ses_path.c
ses_step_dc_npn.c
ses_step_dc_pnp.c
ses_step_simplify.c
ses_step_topo.c
ses_step_va.c
ses_step_va_diode.c
ses_step_va_nodes.c
ses_steps.c
ses_utils.c
test/Makefile
test/colpitts.c [new file with mode: 0644]
test/dct.c [new file with mode: 0644]
test/fft.c

index 9619bf1164711b84af384ee63e5e7b71076ebbad..4535c6cf84d97a4c39dee79a6183dd28fa8222a3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,12 +4,12 @@ CFILES += scf_eda_pack.c
 CFILES += pack/scf_pack.c
 
 CFILES += ses_layout.c
+CFILES += ses_layout_topo.c
 CFILES += ses_graph.c
 
 CFILES += ses_utils.c
 CFILES += ses_path.c
 CFILES += ses_flow.c
-CFILES += ses_mesh_analysis.c
 CFILES += ses_node_analysis.c
 
 CFILES += ses_steps.c
@@ -30,7 +30,6 @@ CFILES += ses_step_va_line.c
 
 CFILES += ses_step_open.c
 CFILES += ses_step_va_nodes.c
-CFILES += ses_step_va_capacitor.c
 
 CFILES += ses_step_a_stat.c
 
diff --git a/examples/colpitts_oscillator.cpk b/examples/colpitts_oscillator.cpk
new file mode 100644 (file)
index 0000000..4d1e411
Binary files /dev/null and b/examples/colpitts_oscillator.cpk differ
diff --git a/main.c b/main.c
index c608d2a58d1d8c028e1c516a94cfb89550c54bf3..9757d9a2e6cce6bc2e54db26c6f859bdb4fe1f2e 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, 1);
+               ses_steps_analyse(f, 100, 76000);
        }
 #endif
 
index c837e73ea6eef4f4a91304d96a02833643aaf3bc..ab2f548bf4aab062789e26d220988d6ba2a7df9a 100644 (file)
@@ -21,7 +21,7 @@ static scf_edata_t  component_datas[] =
 
        {SCF_EDA_Resistor,   0,                   0, 0, 0,  1e4,   0,   0, 0},
        {SCF_EDA_Capacitor,  0,                   0, 0, 0,   10, 0.1,   0, 0},
-       {SCF_EDA_Inductor,   0,                   0, 0, 0,    0,   0, 1e3, 0},
+       {SCF_EDA_Inductor,   0,                   0, 0, 0,   10,   0, 1e3, 0},
 };
 
 static scf_edata_t  pin_datas[] =
index abdbf998544cbb77c69f33962f9d613b9d7324f0..f4eff2a3be23c1c3957307eb2d4e0f8323e66eba 100644 (file)
@@ -10,7 +10,6 @@ typedef struct ses_path_s    ses_path_t;
 typedef struct ses_edge_s    ses_edge_t;
 typedef struct ses_flow_s    ses_flow_t;
 typedef struct ses_node_s    ses_node_t;
-typedef struct ses_mesh_s    ses_mesh_t;
 
 typedef struct ses_info_s    ses_info_t;
 typedef struct ses_data_s    ses_data_t;
@@ -105,9 +104,7 @@ struct ses_path_s
 
        double         v;
        double         a;
-
        double         a0;
-       double         cda;
 
        int            type;
        int            index;
@@ -124,9 +121,6 @@ struct ses_path_s
 
 struct ses_edge_s
 {
-       int            refs;
-       int            index;
-
        ses_path_t*    path;
        int            vip_m;
        int            vip_n;
@@ -144,7 +138,8 @@ struct ses_edge_s
        double         a;
        double         a0;
 
-       uint8_t        vflag:1;
+       int            index;
+
        uint8_t        bflag:1;
 };
 
@@ -156,25 +151,13 @@ struct ses_node_s
        double         a;
        double         a0;
 
+       int64_t        lid;
+
        int            index;
        int            vip_i;
        ses_path_t*    path;
 };
 
-struct ses_mesh_s
-{
-       scf_vector_t*  edges;
-
-       int            n_diodes;
-       int            n_NPNs;
-
-       double         cv;
-       double         r;
-
-       double         a;
-       double         a0;
-};
-
 struct ses_ctx_s
 {
        scf_vector_t*  paths;
@@ -213,15 +196,6 @@ ses_edge_t* ses_edge_alloc(ses_path_t* path, int first, int last);
 void        ses_edge_free (ses_edge_t* edge);
 void        ses_edge_print(ses_edge_t* edge);
 
-ses_mesh_t* ses_mesh_alloc();
-void        ses_mesh_free (ses_mesh_t* mesh);
-void        ses_mesh_print(ses_mesh_t* mesh);
-
-int         ses_mesh_ref_edge(ses_mesh_t* mesh, ses_edge_t* edge);
-int         ses_mesh_add_edge(ses_mesh_t* mesh, ses_path_t* path, int m, int n, ses_edge_t** pp);
-void        ses_meshs_print(scf_vector_t* meshs);
-void        ses_meshs_free (scf_vector_t* meshs);
-
 ses_node_t* ses_node_alloc();
 void        ses_node_free (ses_node_t* node);
 void        ses_node_print(ses_node_t* node);
@@ -243,6 +217,7 @@ void        ses_ctx_free (ses_ctx_t* ctx);
 void ses_components_print(ScfEfunction* f);
 void ses_elines_print    (ScfEfunction* f);
 
+int ses_layout_paths (ScfEfunction* f, scf_vector_t*  paths);
 int ses_layout_board (ScfEboard*    b);
 int ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count);
 
@@ -252,33 +227,23 @@ int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip,  se
 int ses_flow_find_pos  (ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f);
 int ses_flow_find_neg  (ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f);
 
-int  __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path);
-int  __ses_path_va_diode     (ScfEfunction* f, ses_path_t* path);
-int  __ses_path_va_bridge    (ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns, int64_t count);
-int  __ses_path_va_branch    (ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count);
+int  __ses_path_va_diode (ScfEfunction* f, ses_path_t* path);
+int  __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns, int64_t count);
+int  __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count);
 
 void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double la, double* a);
 int  __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe, int vinit);
-int  __ses_topo_paths  (ScfEfunction* f, scf_vector_t*  paths);
 
 void __ses_status_check_line(ScfEfunction* f, ScfEline* el, int* changed);
 
-int  __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv);
-
-int __ses_meshs_PPN  (ScfEfunction* f, ses_flow_t* flow, ses_path_t* bridge, scf_vector_t** meshs);
-int __ses_meshs_path (ScfEfunction* f, ses_path_t* path, scf_vector_t** meshs);
-
-int __ses_meshs_path_solve(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int* changed, int64_t ns, int64_t count);
-int __ses_meshs_PPN_solve (ScfEfunction* f, ses_flow_t* flow, ses_path_t* bridge, int* changed, int64_t ns, int64_t count);
 
-int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t** nodes);
+int __ses_nodes_path      (ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t** pnodes, scf_vector_t** pedges);
 int __ses_nodes_path_solve(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int* changed, int64_t ns, int64_t count);
 
-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_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_sr(ScfEfunction* f, ses_path_t* path, int i, int j, double* r);
+void __ses_path_lc(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv, double* lv, double* uf, double* uh, double* la);
 
 int  __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count);
 int  __ses_path_va2(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count);
index b4aaeb71b72880f8bd1b0ab89edbf65784b8a96d..12c13892a74aef492341a969531bb65240e18395 100644 (file)
@@ -636,7 +636,7 @@ static int __ses_layout_lines4(ScfEfunction* f)
        if (!paths)
                return -ENOMEM;
 
-       int ret = __ses_topo_paths(f, paths);
+       int ret = ses_layout_paths(f, paths);
        if (ret < 0)
                goto end;
 
@@ -1604,8 +1604,6 @@ int ses_layout_function(ScfEfunction* f, int d)
        f->w = 0;
        f->h = 0;
 
-//     qsort(f->elines, f->n_elines, sizeof(ScfEline*), eline_cmp);
-
        int ret = __ses_layout_lines(f, d);
        if (ret < 0)
                return ret;
diff --git a/ses_layout_topo.c b/ses_layout_topo.c
new file mode 100644 (file)
index 0000000..79d7a19
--- /dev/null
@@ -0,0 +1,400 @@
+#include"ses_core.h"
+
+static int __ses_dfs_add_path(scf_vector_t* paths, ses_path_t* path)
+{
+       ScfEpin* p;
+       int      j;
+
+       if (scf_vector_add(paths, path) < 0)
+               return -ENOMEM;
+
+       for (j = 0; j < path->pins->size; j++) {
+               p         = path->pins->data[j];
+               p->pflag  = 1;
+               p->path   = (uintptr_t)path;
+       }
+
+       return 0;
+}
+
+static int __layout_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __paths, ses_path_t** ppath)
+{
+       ScfEcomponent*   c;
+       ScfEline*        el;
+       ScfEpin*         np;
+       ScfEpin*         p;
+
+       int64_t i;
+       int64_t j;
+
+       if (SCF_EDA_Status_OFF == rc->status)
+               return SCF_EDA_Status_OFF;
+
+       if (SCF_EDA_Diode == rc->type && SCF_EDA_Diode_NEG == rp->id)
+               return SCF_EDA_Path_OFF;
+
+       if (SCF_EDA_NPN == rc->type && SCF_EDA_NPN_E == rp->id)
+               return SCF_EDA_Path_OFF;
+
+       if (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E != rp->id)
+               return SCF_EDA_Path_OFF;
+
+       if (!*ppath) {
+               *ppath = ses_path_alloc();
+               if (!*ppath)
+                       return -ENOMEM;
+       }
+
+       if (scf_vector_add((*ppath)->pins, rp) < 0)
+               return -ENOMEM;
+
+       if (!((SCF_EDA_NPN == rc->type && SCF_EDA_NPN_E == rp->id)
+          || (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E == rp->id)))
+               rp->vflag = 1;
+
+       scf_logd("c%ldp%ld, l%ld, vflag: %d, pflag: %d\n", rp->cid, rp->id, rp->lid, rp->vflag, rp->pflag);
+
+       int ret = 0;
+
+       for (i = 0; i < rc->n_pins; i++) {
+               np =        rc->pins[i];
+
+               if (np->vflag)
+                       continue;
+
+               if (SCF_EDA_NPN == rc->type && SCF_EDA_NPN_E != np->id)
+                       continue;
+               if (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E == np->id)
+                       continue;
+
+               scf_logd("c%ldp%ld, l%ld, vflag: %d, pflag: %d\n", np->cid, np->id, np->lid, np->vflag, np->pflag);
+
+               el = f->elines[np->lid];
+
+               if (SCF_EDA_PIN_POS & el->flags) {
+                       scf_logd("pos l%ld\n\n", el->id);
+
+                       ret = SCF_EDA_Path_OFF;
+                       continue;
+               }
+
+               if (!*ppath) {
+                       *ppath = ses_path_alloc();
+                       if (!*ppath)
+                               return -ENOMEM;
+               }
+
+               if (SCF_EDA_PNP == rc->type && 0 == (*ppath)->pins->size) {
+
+                       if (scf_vector_add((*ppath)->pins, rp) < 0)
+                               return -ENOMEM;
+               }
+
+               if (scf_vector_add((*ppath)->pins, np) < 0)
+                       return -ENOMEM;
+
+               if (!((SCF_EDA_NPN == rc->type && SCF_EDA_NPN_E == np->id)
+                  || (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E == np->id)))
+                       np->vflag = 1;
+
+               if (SCF_EDA_PIN_NEG & el->flags) {
+                       scf_logd("neg l%ld\n\n", el->id);
+
+                       ret = __ses_dfs_add_path(__paths, *ppath);
+                       if (ret < 0)
+                               return ret;
+
+                       *ppath = NULL;
+                       return 0;
+               }
+
+               ret = 0;
+
+               for (j = 0; j + 1 < el->n_pins; j += 2) {
+
+                       c  = f->components[el->pins[j]];
+                       p  = c->pins      [el->pins[j + 1]];
+
+                       if (p->pflag) {
+                               if (p != np && *ppath) {
+                                       scf_logd("branch: c%ld_p%ld, l%ld\n\n", c->id, p->id, el->id);
+
+                                       if ((*ppath)->pins->size > 0) {
+
+                                               ret = __ses_dfs_add_path(__paths, *ppath);
+                                               if (ret < 0)
+                                                       return ret;
+                                       } else
+                                               ses_path_free(*ppath);
+
+                                       *ppath = NULL;
+                               }
+                               continue;
+                       }
+
+                       if (p->vflag)
+                               continue;
+
+                       if (!((SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id)
+                          || (SCF_EDA_PNP == c->type && SCF_EDA_PNP_E == p->id)))
+                               p->vflag = 1;
+
+                       ret = __layout_dfs_path(f, c, p, __paths, ppath);
+                       if (ret < 0)
+                               return ret;
+
+                       if (SCF_EDA_Path_OFF == ret)
+                               p->vflag = 0;
+               }
+
+               if (*ppath) {
+                       scf_vector_del((*ppath)->pins, np);
+
+                       if (SCF_EDA_Status_OFF != ret)
+                               ret = SCF_EDA_Path_OFF;
+               }
+
+               if (SCF_EDA_Path_OFF == ret)
+                       np->vflag = 0;
+       }
+
+       if (SCF_EDA_Status_OFF == ret || SCF_EDA_Path_OFF == ret) {
+               if (*ppath)
+                       scf_vector_del((*ppath)->pins, rp);
+
+               if (SCF_EDA_Path_OFF == ret) {
+                       rp->vflag = 0;
+
+                       scf_logd("off: c%ld_p%ld, l%ld\n\n", rp->cid, rp->id, rp->lid);
+
+               } else if (SCF_EDA_Status_OFF == ret)
+                       scf_logd("off: c%ld_p%ld, l%ld\n\n", rp->cid, rp->id, rp->lid);
+       }
+
+       return ret;
+}
+
+static int __layout_add_path(ses_path_t* parent, ses_path_t* child)
+{
+       ses_path_t* path;
+       ScfEpin*    cp0 = child->pins->data[0];
+       ScfEpin*    cp1 = child->pins->data[child->pins->size - 1];
+       ScfEpin*    p0;
+       ScfEpin*    p1;
+
+       int i;
+       int j;
+
+       if (!parent->childs) {
+               parent->childs = scf_vector_alloc();
+               if (!parent->childs)
+                       return -ENOMEM;
+       }
+
+       for (i = 0; i < parent->childs->size; i++) {
+               path      = parent->childs->data[i];
+
+               p0 = path->pins->data[0];
+               p1 = path->pins->data[path->pins->size - 1];
+
+               if (p0->lid == cp0->lid && p1->lid == cp1->lid)
+                       return __layout_add_path(path, child);
+       }
+
+       child->parent_p0 = -1;
+       child->parent_p1 = -1;
+
+       for (j = 0; j < parent->pins->size; j++) {
+               p0 =        parent->pins->data[j];
+
+               if (p0->lid == cp0->lid)
+                       child->parent_p0 = (j + 1) & ~0x1;
+
+               else if (p0->lid == cp1->lid)
+                       child->parent_p1 = j;
+
+               if (child->parent_p0 >= 0 && child->parent_p1 >= 0)
+                       break;
+       }
+
+       child->parent = parent;
+       return scf_vector_add(parent->childs, child);
+}
+
+static int _layout_layers(ScfEfunction* f, scf_vector_t* paths)
+{
+       ScfEcomponent* B;
+       ses_path_t*    child;
+       ses_path_t*    parent;
+       ScfEpin*       Bp;
+       ScfEpin*       Bn;
+       ScfEpin*       p0;
+       ScfEpin*       p1;
+       ScfEpin*       p2;
+       ScfEpin*       p3;
+       ScfEpin*       p;
+
+       int i;
+       int j;
+       int k;
+
+       B  = f->components[0];
+       Bp = B->pins[SCF_EDA_Battery_POS];
+       Bn = B->pins[SCF_EDA_Battery_NEG];
+
+       for (i    = paths->size - 1; i >= 0; i--) {
+               child = paths->data[i];
+
+               assert(child->pins->size >= 2);
+
+               p0   = child->pins->data[0];
+               p1   = child->pins->data[child->pins->size - 1];
+
+               if (p0->lid == Bp->lid && p1->lid == Bn->lid)
+                       continue;
+
+               for (j     = paths->size - 1; j >= 0; j--) {
+                       parent = paths->data[j];
+
+                       if (parent == child)
+                               continue;
+
+                       int n  = 0;
+
+                       for (k = 0; k < parent->pins->size; k++) {
+                               p  =        parent->pins->data[k];
+
+                               if (p->lid == p0->lid)
+                                       n |= 0x1;
+
+                               if (p->lid == p1->lid)
+                                       n |= 0x2;
+
+                               if (0x3 == n)
+                                       goto branch;
+                       }
+               }
+
+               continue;
+
+branch:
+               if (scf_vector_del(paths, child) < 0)
+                       return -1;
+
+               if (__layout_add_path(parent, child) < 0) {
+                       ses_path_free(child);
+                       return -ENOMEM;
+               }
+       }
+
+       return 0;
+}
+
+static int ses_layout_layers(ScfEfunction* f, scf_vector_t* paths)
+{
+       ses_path_t* path;
+
+       int size;
+
+       do {
+               size = paths->size;
+
+               int ret = _layout_layers(f, paths);
+               if (ret < 0)
+                       return ret;
+
+       } while (size > paths->size);
+
+       return 0;
+}
+
+static int _layout_paths(ScfEfunction* f, ScfEline* el, scf_vector_t* paths)
+{
+       if (!f || !el || !paths)
+               return -EINVAL;
+
+       ses_path_t*      path;
+       ScfEcomponent*   c;
+       ScfEcomponent*   B;
+       ScfEpin*         p;
+
+       size_t i;
+
+       B    = f->components[0];
+       path = NULL;
+
+       for (i = 0; i + 1 < el->n_pins; i += 2) {
+
+               c  = f->components[el->pins[i]];
+               p  = c->pins      [el->pins[i + 1]];
+
+               if (c == B)
+                       continue;
+
+               int ret = __layout_dfs_path(f, c, p, paths, &path);
+               if (ret < 0)
+                       return ret;
+
+               if (!path)
+                       continue;
+
+               if (SCF_EDA_Status_OFF == ret || SCF_EDA_Path_OFF == ret) {
+                       ses_path_free(path);
+                       path = NULL;
+                       continue;
+               }
+
+               if (scf_vector_add(paths, path) < 0) {
+                       ses_path_free(path);
+                       return -ENOMEM;
+               }
+
+               path = NULL;
+       }
+
+       if (path) {
+               ses_path_free(path);
+               path = NULL;
+       }
+
+       for (i = 0; i < paths->size; i++) {
+               path      = paths->data[i];
+
+               path->index = i;
+       }
+
+       return 0;
+}
+
+int ses_layout_paths(ScfEfunction* f, scf_vector_t*  paths)
+{
+       if (!f || !paths)
+               return -EINVAL;
+
+       ses_path_t*      path;
+       ScfEcomponent*   B;
+       ScfEline*        el;
+
+       scf_vector_clear(paths, ( void (*)(void*) )ses_path_free);
+
+       B  = f->components[0];
+       el = f->elines[B->pins[SCF_EDA_Battery_POS]->lid];
+
+       int ret = _layout_paths(f, el, paths);
+       if (ret < 0)
+               return ret;
+
+       int i;
+       for (i = 0; i < f->n_elines; i++) {
+               el =        f->elines[i];
+
+               if (el->flags & SCF_EDA_PIN_IN) {
+
+                       ret = _layout_paths(f, el, paths);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
+       return ses_layout_layers(f, paths);
+}
index 0da595c32f108bec11d1e5e77d686f06a67d3161..4167499d5822668a4f7ed656723997c7c774971b 100644 (file)
@@ -1,83 +1,43 @@
 #include"ses_core.h"
 #include <gsl/gsl_linalg.h>
 
-int ses_node_ref_edge(ses_node_t* node, ses_edge_t* edge)
+ses_edge_t* ses_edges_find_edge(scf_vector_t* edges, ses_path_t* path, int vip_i)
 {
-       int ret = scf_vector_add(node->edges, edge);
-       if (ret < 0)
-               return ret;
-
-       edge->refs++;
-       return 0;
-}
-
-int ses_node_add_edge(ses_node_t* node, ses_path_t* path, int m, int n, ses_edge_t** pp)
-{
-       ses_edge_t* edge = ses_edge_alloc(path, m, n);
-       if (!edge)
-               return -ENOMEM;
-
-       int ret = scf_vector_add(node->edges, edge);
-       if (ret < 0) {
-               ses_edge_free(edge);
-               return ret;
-       }
-
-       if (pp)
-               *pp = edge;
-       return 0;
-}
-
-ses_edge_t* ses_nodes_find_edge(scf_vector_t* nodes, ses_path_t* path, int vip_i)
-{
-       ses_node_t* node;
        ses_edge_t* edge;
 
-       int i;
        int j;
+       for (j = 0; j < edges->size; j++) {
+               edge      = edges->data[j];
 
-       for (i = 0; i < nodes->size; i++) {
-               node      = nodes->data[i];
-
-               for (j = 0; j < node->edges->size; j++) {
-                       edge      = node->edges->data[j];
-
-                       if (edge->path == path
-                                       && (edge->vip_m == vip_i || edge->vip_n == vip_i))
-                               return edge;
-               }
+               if (edge->path == path
+                               && (edge->vip_m == vip_i || edge->vip_n == vip_i))
+                       return edge;
        }
 
        return NULL;
 }
 
-ses_edge_t* ses_nodes_find_edge_by_pin(scf_vector_t* nodes, ScfEpin* vip)
+ses_edge_t* ses_edges_find_edge_by_pin(scf_vector_t* edges, ScfEpin* vip)
 {
-       ses_node_t* node;
        ses_edge_t* edge;
 
-       int i;
        int j;
        int k;
 
-       for (i = 0; i < nodes->size; i++) {
-               node      = nodes->data[i];
+       for (j = 0; j < edges->size; j++) {
+               edge      = edges->data[j];
 
-               for (j = 0; j < node->edges->size; j++) {
-                       edge      = node->edges->data[j];
+               for (k = edge->vip_n; k >= edge->vip_m; k--) {
 
-                       for (k = edge->vip_n; k >= edge->vip_m; k--) {
-
-                               if (vip == edge->path->pins->data[k])
-                                       return edge;
-                       }
+                       if (vip == edge->path->pins->data[k])
+                               return edge;
                }
        }
 
        return NULL;
 }
 
-int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* nodes, int* n_edges)
+int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* nodes, scf_vector_t* edges)
 {
        ses_path_t*    child;
        ses_path_t*    bridge;
@@ -107,7 +67,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                        if (conn->vflag)
                                continue;
 
-                       ret = __ses_nodes_path2(f, conn, 0, conn->pins->size - 1, nodes, n_edges);
+                       ret = __ses_nodes_path2(f, conn, 0, conn->pins->size - 1, nodes, edges);
                        if (ret < 0)
                                return ret;
                }
@@ -120,7 +80,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                        if (child->vflag)
                                continue;
 
-                       ret = __ses_nodes_path2(f, child, 0, child->pins->size - 1, nodes, n_edges);
+                       ret = __ses_nodes_path2(f, child, 0, child->pins->size - 1, nodes, edges);
                        if (ret < 0)
                                return ret;
                }
@@ -133,7 +93,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                        if (bridge->vflag)
                                continue;
 
-                       ret = __ses_nodes_path2(f, bridge, 0, bridge->pins->size - 1, nodes, n_edges);
+                       ret = __ses_nodes_path2(f, bridge, 0, bridge->pins->size - 1, nodes, edges);
                        if (ret < 0)
                                return ret;
                }
@@ -142,7 +102,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
        scf_logd("path: %d, vflag: %d, vip_m: %d, vip_n: %d\n", path->index, path->vflag, vip_m, vip_n);
 
        int bflag = 0;
-       for (i = vip_n - 1; i > vip_m; i -= 2) {
+       for (i = vip_n - 1; i >= vip_m; i -= 2) {
 
                p = path->pins->data[i];
                c = f->components[p->cid];
@@ -154,7 +114,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                        case SCF_EDA_NPN:
 
                                if (SCF_EDA_NPN_B == p->id) {
-                                       edge_c = ses_nodes_find_edge_by_pin(nodes, c->pins[SCF_EDA_NPN_C]);
+                                       edge_c = ses_edges_find_edge_by_pin(edges, c->pins[SCF_EDA_NPN_C]);
                                        if (!edge_c) {
                                                scf_loge("\n");
                                                return -EINVAL;
@@ -164,6 +124,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                                        edge_c->hfe = c->pins[SCF_EDA_NPN_C]->hfe;
                                }
 
+                       case SCF_EDA_Inductor:
                                if (!node) {
                                        node = ses_node_alloc();
                                        if (!node)
@@ -185,9 +146,9 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                                                if (!node) \
                                                        return -ENOMEM; \
                                        } \
-                                       edge = ses_nodes_find_edge(nodes, _path, _m); \
+                                       edge = ses_edges_find_edge(edges, _path, _m); \
                                        if (edge) { \
-                                               ret = ses_node_ref_edge(node, edge); \
+                                               ret = scf_vector_add(node->edges, edge); \
                                                if (ret < 0) { \
                                                        ses_node_free(node); \
                                                        return ret; \
@@ -245,25 +206,50 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                        }
                }
 
-               if (!node)
-                       continue;
+               if (!node) {
+                       if (i > vip_m)
+                               continue;
 
-               ret = ses_node_add_edge(node, path, i, j, &edge);
+                       node = ses_node_alloc();
+                       if (!node)
+                               return -ENOMEM;
+               }
+
+               ret = scf_vector_add(nodes, node);
                if (ret < 0) {
                        ses_node_free(node);
                        return ret;
                }
-               edge->index = (*n_edges)++;
+
+               p = path->pins->data[i];
+
+               node->vip_i = i;
+               node->path  = path;
+               node->lid   = p->lid;
+
+               edge = ses_edge_alloc(path, i, j);
+               if (!edge)
+                       return -ENOMEM;
+
+               ret = scf_vector_add(edges, edge);
+               if (ret < 0) {
+                       ses_edge_free(edge);
+                       return ret;
+               }
+
+               edge->index = edges->size - 1;
                edge->node1 = node;
                edge->bflag = bflag;
                bflag = 0;
 
+               ret = scf_vector_add(node->edges, edge);
+               if (ret < 0)
+                       return ret;
+
                if (prev) {
-                       ret = ses_node_ref_edge(prev, edge);
-                       if (ret < 0) {
-                               ses_node_free(node);
+                       ret = scf_vector_add(prev->edges, edge);
+                       if (ret < 0)
                                return ret;
-                       }
                        edge->node0 = prev;
                }
 
@@ -272,77 +258,50 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                        edge_c = NULL;
                }
 
-               ret = scf_vector_add(nodes, node);
-               if (ret < 0) {
-                       ses_node_free(node);
-                       return ret;
-               }
-               node->vip_i = i;
-               node->path  = path;
-
                prev = node;
                node = NULL;
 
                j = i - 1;
        }
 
-       if (j > vip_m) {
-               if (!prev) {
-                       prev = ses_node_alloc();
-                       if (!prev)
-                               return -ENOMEM;
-
-                       ret = scf_vector_add(nodes, prev);
-                       if (ret < 0) {
-                               ses_node_free(prev);
-                               return ret;
-                       }
-                       prev->vip_i = j;
-                       prev->path  = path;
-               }
-
-               ret = ses_node_add_edge(prev, path, vip_m, j, &edge);
-               if (ret < 0)
-                       return ret;
-               edge->index = (*n_edges)++;
-               edge->node0 = prev;
-               edge->bflag = bflag;
-               bflag = 0;
-
-               if (edge_c) {
-                       edge_c->edge_b = edge;
-                       edge_c = NULL;
-               }
-       }
-
        return 0;
 }
 
-int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t** nodes)
+int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t** pnodes, scf_vector_t** pedges)
 {
-       scf_vector_t* vec = scf_vector_alloc();
-       if (!vec)
-               return -ENOMEM;
-
-       ses_node_t* node;
-       ses_edge_t* edge;
+       scf_vector_t* nodes;
+       scf_vector_t* edges;
+       ses_node_t*   node;
+       ses_edge_t*   edge;
 
-       int n_edges = 0;
        int i;
        int j;
 
-       int ret = __ses_nodes_path2(f, path, vip_m, vip_n, vec, &n_edges);
+       nodes = scf_vector_alloc();
+       if (!nodes)
+               return -ENOMEM;
+
+       edges = scf_vector_alloc();
+       if (!edges) {
+               scf_vector_free(nodes);
+               return -ENOMEM;
+       }
+
+       int ret = __ses_nodes_path2(f, path, vip_m, vip_n, nodes, edges);
        if (ret < 0) {
-               scf_vector_clear(vec, (void (*)(void*) )ses_node_free);
-               scf_vector_free(vec);
+               scf_vector_clear(nodes, (void (*)(void*) )ses_node_free);
+               scf_vector_clear(edges, (void (*)(void*) )ses_edge_free);
+               scf_vector_free(nodes);
+               scf_vector_free(edges);
                return ret;
        }
 
-       for (i = 0; i < vec->size; ) {
-               node      = vec->data[i];
+       for (i = 0; i < nodes->size; ) {
+               node      = nodes->data[i];
+
+               if (nodes->size > 1 && node->edges->size <= 1) {
 
-               if (node->edges->size <= 1) {
-                       assert(0 == scf_vector_del(vec, node));
+                       assert(0 == scf_vector_del(nodes, node));
 
                        for (j = 0; j < node->edges->size; j++) {
                                edge      = node->edges->data[j];
@@ -361,7 +320,8 @@ int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, sc
                }
        }
 
-       *nodes = vec;
+       *pnodes = nodes;
+       *pedges = edges;
        return 0;
 }
 
@@ -384,45 +344,38 @@ int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, sc
  ...
  v[m - 1][0] - v[m - 1][1] - a[m - 1] * R[m - 1] = C[m - 1]
  */
-static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* nodes, int* changed, int64_t ns, int64_t count)
+static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* nodes, scf_vector_t* edges, int* changed, int64_t ns, int64_t count)
 {
        ses_node_t*    node;
        ses_edge_t*    edge;
 
        ScfEcomponent* c;
-       ScfEline*      el;
+       ScfEcomponent* B  = f->components[0];
+       ScfEpin*       Bp = B->pins[SCF_EDA_Battery_POS];
+       ScfEpin*       Bn = B->pins[SCF_EDA_Battery_NEG];
+
        ScfEpin*       pm = path->pins->data[vip_m];
        ScfEpin*       pn = path->pins->data[vip_n];
        ScfEpin*       p0;
        ScfEpin*       p1;
+       ScfEline*      el;
 
        int ret = 0;
        int i;
        int j;
 
-       int t = 0;
-       int m = 0;
+       int m = edges->size;
        int n = nodes->size;
 
-       for (i = 0; i < nodes->size; i++) {
-               node      = nodes->data[i];
-
-               for (j = 0; j < node->edges->size; j++) {
-                       edge      = node->edges->data[j];
-
-                       if (!edge->vflag) {
-                               m++;
-                               edge->vflag = 1;
-
-                               if (edge->edge_b)
-                                       t++;
-                       }
-               }
-       }
+       if (pm->lid == Bp->lid)
+               n = nodes->size - 1;
 
        int N = n + m;
 
-       scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, n_nodes: %d, n_edges: %d, t: %d, N: %d\n", pm->cid, pm->id, pm->v, pn->cid, pn->id, pn->v, n, m, t, N);
+       pm->v = f->elines[pm->lid]->v;
+       pn->v = f->elines[pn->lid]->v;
+
+       scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, n: %d, m: %d, N: %d\n", pm->cid, pm->id, pm->v, pn->cid, pn->id, pn->v, n, m, N);
 
        double* A = calloc(N * N + N + N + (N + N + N * N + N * N), sizeof(double));
        if (!A)
@@ -435,12 +388,16 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
        double* V = S + N;
        double* U = V + N * N;
        double cv;
+       double lv;
+       double uf;
+       double uh;
+       double la;
        double r;
 
        __ses_path_jr(f, path);
 
-       for (i = 0; i < nodes->size; i++) {
-               node      = nodes->data[i];
+       for (i = 0; i < n; i++) {
+               node = nodes->data[i];
 
                b[i] = 0;
 
@@ -455,92 +412,71 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
                }
        }
 
-       for (i = 0; i < nodes->size; i++) {
-               node      = nodes->data[i];
-
-               scf_logd("node->index: %d\n", node->index);
-
-               for (j = 0; j < node->edges->size; j++) {
-                       edge      = node->edges->data[j];
-
-                       if (!edge->vflag)
-                               continue;
-                       edge->vflag = 0;
+       for (j = 0; j < edges->size; j++) {
+               edge      = edges->data[j];
 
-                       __ses_path_capacitors(f, edge->path, edge->vip_m, edge->vip_n, &cv);
+               __ses_path_lc(f, edge->path, edge->vip_m, edge->vip_n, &cv, &lv, &uf, &uh, &la);
 
-                       p0 = edge->path->pins->data[edge->vip_m];
-                       p1 = edge->path->pins->data[edge->vip_n];
+               p0 = edge->path->pins->data[edge->vip_m];
+               p1 = edge->path->pins->data[edge->vip_n];
 
-                       double _pr0 = p0->pr;
-                       double _sr0 = p0->sr;
-                       double _pr1 = p1->pr;
-                       double _sr1 = p1->sr;
+               double _pr0 = p0->pr;
+               double _sr0 = p0->sr;
+               double _pr1 = p1->pr;
+               double _sr1 = p1->sr;
 
-                       if (0 == edge->vip_m) {
-                               p0->pr = 0;
-                               p0->sr = 0;
-                       }
+               if (0 == edge->vip_m) {
+                       p0->pr = 0;
+                       p0->sr = 0;
+               }
 
-                       if (edge->vip_n == edge->path->pins->size - 1) {
-                               p1->pr = edge->path->pr;
-                               p1->sr = edge->path->sr;
-                       }
+               if (edge->vip_n == edge->path->pins->size - 1) {
+                       p1->pr = edge->path->pr;
+                       p1->sr = edge->path->sr;
+               }
 
-                       if (0 == edge->vip_m && edge->vip_n == edge->path->pins->size - 1)
-                               r  = edge->path->pr;
+               if (0 == edge->vip_m && edge->vip_n == edge->path->pins->size - 1)
+                       r  = edge->path->sr;
+               else
+                       __ses_path_sr(f, edge->path, edge->vip_m, edge->vip_n, &r);
+
+               p0->pr = _pr0;
+               p0->sr = _sr0;
+               p1->pr = _pr1;
+               p1->sr = _sr1;
+
+               edge->r = r;
+
+               scf_logd("c%ldp%ld-c%ldp%ld, r: %lg, cv: %lg, uh: %lg, la: %lg, edge->index: %d\n", p0->cid, p0->id, p1->cid, p1->id, r, cv, uh, la, edge->index);
+/* dv = idt / C
+    v = Ldi/dt
+   v0 - v1 - ir = cv + idt/C + Ldi/dt
+   v0 - v1 - ir = cv + idt/C + Li/dt - Li0/dt
+
+   v0 - v1 - i * (r + dt/C + L/dt) = cv - Li0/dt
+*/
+               if (edge->bflag)
+                       b[n + edge->index] = cv + SCF_EDA_V_NPN_ON;
+               else {
+                       b[n + edge->index] = cv - uh * 1000.0 * la / ns;
+
+                       if (uf > 0.0)
+                               A[(n + edge->index) * N + n + edge->index] = -r - uh * 1000.0 / ns - ns / 1000.0 / uf;
                        else
-                               __ses_path_sr(f, edge->path, edge->vip_m, edge->vip_n, &r);
-
-                       p0->pr = _pr0;
-                       p0->sr = _sr0;
-                       p1->pr = _pr1;
-                       p1->sr = _sr1;
-
-                       edge->r = r;
-
-                       scf_logd("c%ldp%ld-c%ldp%ld, r: %lg, cv: %lg, edge->index: %d\n", p0->cid, p0->id, p1->cid, p1->id, r, cv, edge->index);
-
-                       if (edge->bflag)
-                               b[n + edge->index] = cv + SCF_EDA_V_NPN_ON;
-                       else {
-                               b[n + edge->index]                         = cv;
-                               A[(n + edge->index) * N + n + edge->index] = -r;
-                       }
-
-                       if (edge->path == path) {
-
-                               if (edge->node0)
-                                       A[(n + edge->index) * N + edge->node0->index] = -1;
-
-                               else if (edge->vip_n == vip_n)
-                                       b[n + edge->index] += pn->v;
-
-
-                               if (edge->node1)
-                                       A[(n + edge->index) * N + edge->node1->index] = 1;
-
-                               else if (edge->vip_m == vip_m)
-                                       b[n + edge->index] -= pm->v;
-
-                       } else {
-                               if (edge->node0)
-                                       A[(n + edge->index) * N + edge->node0->index] = -1;
-
-                               else if (edge->path->parent_p1 == vip_n)
-                                       b[n + edge->index] -= pn->v;
-
+                               A[(n + edge->index) * N + n + edge->index] = -r - uh * 1000.0 / ns;
+               }
 
-                               if (edge->node1)
-                                       A[(n + edge->index) * N + edge->node1->index] = 1;
+               if (edge->node0 && edge->node0->lid != Bn->lid)
+                       A[(n + edge->index) * N + edge->node0->index] = -1;
+               else
+                       b[n + edge->index] += Bn->v;
 
-                               else if (edge->path->parent_p0 == vip_m)
-                                       b[n + edge->index] -= pm->v;
-                       }
-               }
+               if (edge->node1 && edge->node1->lid != Bp->lid)
+                       A[(n + edge->index) * N + edge->node1->index] = 1;
+               else
+                       b[n + edge->index] -= Bp->v;
        }
 
-
        int n_amplifiers;
 
        do {
@@ -572,31 +508,27 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
 //             scf_logi("X:\n");
 //             gsl_vector_fprintf(stdout, &_X.vector, "%lg");
 
-               for (i = 0; i < nodes->size; i++) {
-                       node      = nodes->data[i];
-
-                       for (j = 0; j < node->edges->size; j++) {
-                               edge      = node->edges->data[j];
+               for (j = 0; j < edges->size; j++) {
+                       edge      = edges->data[j];
 
-                               if (edge->edge_b) {
-                                       double Ic = X[n + edge->index];
-                                       double Ib = X[n + edge->edge_b->index];
+                       if (edge->edge_b) {
+                               double Ic = X[n + edge->index];
+                               double Ib = X[n + edge->edge_b->index];
 
-                                       double dI = Ib * edge->hfe - Ic;
+                               double dI = Ib * edge->hfe - Ic;
 
-                                       if (dI < -1e-10) {
-                                               scf_logi("Ic: %lg, Ib: %lg, dI: %lg\n", Ic, Ib, dI);
+                               if (dI < -1e-10) {
+                                       scf_logi("Ic: %lg, Ib: %lg, dI: %lg\n", Ic, Ib, dI);
 
-                                               int k;
-                                               for (k = 0; k < N; k++)
-                                                       A[(n + edge->index) * N + k] = 0;
+                                       int k;
+                                       for (k = 0; k < N; k++)
+                                               A[(n + edge->index) * N + k] = 0;
 
-                                               A[(n + edge->index) * N + n + edge->index]         = -1;
-                                               A[(n + edge->index) * N + n + edge->edge_b->index] = edge->hfe;
-                                               b[ n + edge->index] = 0;
+                                       A[(n + edge->index) * N + n + edge->index]         = -1;
+                                       A[(n + edge->index) * N + n + edge->edge_b->index] = edge->hfe;
+                                       b[ n + edge->index] = 0;
 
-                                               n_amplifiers++;
-                                       }
+                                       n_amplifiers++;
                                }
                        }
                }
@@ -605,63 +537,115 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
        for (i = 0; i < N; i++)
                scf_logi("%lg\n", X[i]);
 
-       for (i = 0; i < nodes->size; i++) {
-               node      = nodes->data[i];
+       for (i = 0; i < n; i++) {
+               node  = nodes->data[i];
 
-               p0    = node->path->pins->data[node->vip_i];
-
-               el    = f->elines[p0->lid];
+               el    = f->elines[node->lid];
                el->v = X[i];
+       }
+
+       int __changed = 0;
+
+       for (j = 0; j < edges->size; j++) {
+               edge      = edges->data[j];
+
+               p0 = edge->path->pins->data[edge->vip_m];
+               p1 = edge->path->pins->data[edge->vip_n];
+
+               c  = f->components[p0->cid];
+
+               edge->a = X[n + edge->index];
+
+               scf_logd("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, a: %lg, edge->index: %d\n", p0->cid, p0->id, p0->v, p1->cid, p1->id, p1->v, edge->a, edge->index);
+
+               if (SCF_EDA_NPN == c->type) {
+                       p0->a = edge->a;
+                       p1->a = c->pins[SCF_EDA_NPN_B]->a + c->pins[SCF_EDA_NPN_C]->a;
+
+                       if (SCF_EDA_NPN_B == p0->id && edge->a < 0) {
+                               c->status = SCF_EDA_Status_OFF;
+                               c->lock   = 1;
+                               __changed++;
+
+                               scf_loge("\033[34mc%ld, status: %d, a: %lg, edge->index: %d\033[0m\n", c->id, c->status, edge->a, edge->index);
+                       }
+
+               } else if (SCF_EDA_PNP == c->type) {
+                       p1->a = edge->a;
+                       p0->a = c->pins[SCF_EDA_PNP_B]->a + c->pins[SCF_EDA_PNP_C]->a;
+
+                       if (SCF_EDA_PNP_B == p1->id && edge->a < 0) {
+                               c->status = SCF_EDA_Status_OFF;
+                               c->lock   = 1;
+                               __changed++;
+
+                               scf_loge("\033[34mc%ld, status: %d, a: %lg, edge->index: %d\033[0m\n", c->id, c->status, edge->a, edge->index);
+                       }
+               }
+       }
 
-               scf_logi("c%ldp%ld, e%ld->v: %lg, node->index: %d\n", p0->cid, p0->id, el->id, el->v, node->index);
+       if (__changed > 0) {
+               *changed += __changed;
+               return 0;
        }
 
-#if 1
-       for (i = 0; i < nodes->size; i++) {
-               node      = nodes->data[i];
+       for (j = 0; j < edges->size; j++) {
+               edge      = edges->data[j];
 
-               for (j = 0; j < node->edges->size; j++) {
-                       edge      = node->edges->data[j];
+               p0 = edge->path->pins->data[edge->vip_m];
+               p1 = edge->path->pins->data[edge->vip_n];
 
-                       if (edge->vflag)
-                               continue;
-                       edge->vflag = 1;
+               c  = f->components[p0->cid];
 
-                       p0 = edge->path->pins->data[edge->vip_m];
-                       p1 = edge->path->pins->data[edge->vip_n];
+               p0->v = f->elines[p0->lid]->v;
+               p1->v = f->elines[p1->lid]->v;
 
-                       c  = f->components[p0->cid];
+               scf_logd("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, a: %lg, edge->index: %d\n", p0->cid, p0->id, p0->v, p1->cid, p1->id, p1->v, edge->a, edge->index);
 
-                       p0->v = f->elines[p0->lid]->v;
-                       p1->v = f->elines[p1->lid]->v;
+               if (SCF_EDA_NPN == c->type) {
+                       ses_ui_r(&edge->r, 0, p0->v - p1->v, 0, edge->a, 0);
 
-                       edge->a = X[n + edge->index];
+                       p0->dr = edge->r - p0->r;
+                       p0->a  = edge->a;
+                       p1->a  = c->pins[SCF_EDA_NPN_B]->a + c->pins[SCF_EDA_NPN_C]->a;
 
-                       scf_logd("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, a: %lg, edge->index: %d\n", p0->cid, p0->id, p0->v, p1->cid, p1->id, p1->v, edge->a, edge->index);
+                       if (SCF_EDA_NPN_B == p0->id && p0->a < 0) {
+                               c->status = SCF_EDA_Status_OFF;
 
-                       if (SCF_EDA_NPN == c->type) {
-                               ses_ui_r(&edge->r, 0, p0->v - p1->v, 0, edge->a, 0);
+                               scf_loge("\033[34mc%ld, status: %d, a: %lg, edge->index: %d\033[0m\n", c->id, c->status, edge->a, edge->index);
+                       }
+                       continue;
 
-                               p0->dr = edge->r - p0->r;
-                               p0->a  = edge->a;
-                               p1->a  = c->pins[SCF_EDA_NPN_B]->a + c->pins[SCF_EDA_NPN_C]->a;
-                               continue;
+               } else if (SCF_EDA_PNP == c->type) {
+                       ses_ui_r(&edge->r, 0, p0->v - p1->v, 0, edge->a, 0);
 
-                       } else if (SCF_EDA_PNP == c->type) {
-                               ses_ui_r(&edge->r, 0, p0->v - p1->v, 0, edge->a, 0);
+                       p1->dr = edge->r - p1->r;
+                       p1->a  = edge->a;
+                       p0->a  = c->pins[SCF_EDA_PNP_B]->a + c->pins[SCF_EDA_PNP_C]->a;
 
-                               p1->dr = edge->r - p1->r;
-                               p1->a  = edge->a;
-                               p0->a  = c->pins[SCF_EDA_PNP_B]->a + c->pins[SCF_EDA_PNP_C]->a;
-                               continue;
+                       if (SCF_EDA_PNP_B == p1->id && p1->a < 0) {
+                               c->status = SCF_EDA_Status_OFF;
+
+                               scf_loge("\033[34mc%ld, status: %d, a: %lg, edge->index: %d\033[0m\n", c->id, c->status, edge->a, edge->index);
                        }
+                       continue;
 
-                       ret = __ses_path_va_branch(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ns, count);
-                       if (ret < 0)
-                               goto error;
+               } else if (SCF_EDA_Inductor == c->type) {
+                       int sign = p0->id - !p0->id;
+
+                       c->v = (edge->a * sign - c->a) * c->uh * 1000.0 / ns;
+
+               } else if (SCF_EDA_Capacitor == c->type) {
+                       int sign = p0->id - !p0->id;
+
+                       c->v += edge->a * sign * ns / 1000.0 / c->uf;
                }
+
+               ret = __ses_path_va_branch(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ns, count);
+               if (ret < 0)
+                       goto error;
        }
-#endif
+
 error:
        free(A);
        return ret;
@@ -670,8 +654,7 @@ error:
 int __ses_nodes_path_solve(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int* changed, int64_t ns, int64_t count)
 {
        scf_vector_t* nodes = NULL;
-       ses_node_t*   node;
-       ses_edge_t*   edge;
+       scf_vector_t* edges = NULL;
 
        ScfEline*     el;
        ScfEpin*      pm = path->pins->data[vip_m];
@@ -679,16 +662,18 @@ int __ses_nodes_path_solve(ScfEfunction* f, ses_path_t* path, int vip_m, int vip
        ScfEpin*      p0;
        ScfEpin*      p1;
 
-       int ret = __ses_nodes_path(f, path, vip_m, vip_n, &nodes);
+       int ret = __ses_nodes_path(f, path, vip_m, vip_n, &nodes, &edges);
        if (ret < 0)
                return ret;
 
        ses_nodes_print(nodes);
 
-       ret = __ses_nodes_path_solve2(f, path, vip_m, vip_n, nodes, changed, ns, count);
+       ret = __ses_nodes_path_solve2(f, path, vip_m, vip_n, nodes, edges, changed, ns, count);
 
        scf_vector_clear(nodes, (void (*)(void*) )ses_node_free);
+       scf_vector_clear(edges, (void (*)(void*) )ses_edge_free);
        scf_vector_free(nodes);
+       scf_vector_free(edges);
 
        return ret;
 }
index b52dbf38e08ccc3952762a70d93c9b8d09c71b19..d17ce5d514dcda739581b2a29bd77bd00ed6e3ea 100644 (file)
@@ -375,29 +375,6 @@ int ses_path_add(ses_path_t* parent, ses_path_t* child, ScfEfunction* f)
 
        int j;
 
-       for (j = 0; j < parent->childs->size; j++) {
-               path      = parent->childs->data[j];
-
-               p0        = path->pins->data[0];
-               p1        = path->pins->data[path->pins->size - 1];
-
-               if (p0->lid == cp0->lid && p1->lid == cp1->lid) {
-
-                       if (child->pins->size == (child->n_diodes + child->n_NPNs) * 2
-                         && path->pins->size  > (path->n_diodes + path->n_NPNs) * 2) {
-
-                               parent->childs->data[j] = child;
-                               child->parent           = parent;
-                               child->parent_p0        = path->parent_p0;
-                               child->parent_p1        = path->parent_p1;
-                               child->type             = SES_PATH_BRANCH;
-
-                               return ses_path_add(child, path, f);
-                       } else
-                               return ses_path_add(path, child, f);
-               }
-       }
-
        if (scf_vector_add(parent->childs, child) < 0)
                return -ENOMEM;
 
index 147bf2e264d3fd1753c44326dc8f2eabf1a1afe6..1dcf56439b0d4186dc0e75d67372609bc383db68 100644 (file)
@@ -45,11 +45,13 @@ static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t
                        continue;
                }
 
-               scf_logd("c%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n",
-                               c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF);
+               if (c->lock) {
+                       scf_loge("\033[34mc%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n",
+                                       c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF);
+                       continue;
+               }
 
                if (lb->v < SCF_EDA_V_MIN) {
-
                        if (le->v < SCF_EDA_V_MIN)
                                continue;
 
@@ -60,10 +62,9 @@ static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t
                        if (le->v == Bn->v)
                                lb->vconst = 1;
 
-                       if (pb->v > Bp->v) {
-                               if (!c->lock)
-                                       c->status = SCF_EDA_Status_OFF;
-                       } else
+                       if (pb->v > Bp->v)
+                               c->status = SCF_EDA_Status_OFF;
+                       else
                                c->status = SCF_EDA_Status_ON;
 
                } else if (le->v < SCF_EDA_V_MIN) {
@@ -75,10 +76,9 @@ static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t
                        if (lb->v == Bp->v)
                                le->vconst = 1;
 
-                       if (pe->v < Bn->v) {
-                               if (!c->lock)
-                                       c->status = SCF_EDA_Status_OFF;
-                       } else
+                       if (pe->v < Bn->v)
+                               c->status = SCF_EDA_Status_OFF;
+                       else
                                c->status = SCF_EDA_Status_ON;
 
                } else if (lb->v >= le->v + SCF_EDA_V_NPN_OFF) {
@@ -92,16 +92,15 @@ static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t
                        pb->v = lb->v;
                        pe->v = le->v;
 
-                       if (pb->v > Bp->v) {
-                               if (!c->lock)
-                                       c->status = SCF_EDA_Status_OFF;
-                       } else
+                       if (pb->v > Bp->v)
+                               c->status = SCF_EDA_Status_OFF;
+                       else
                                c->status = SCF_EDA_Status_ON;
                } else {
                        pb->v = lb->v;
                        pe->v = le->v;
-                       if (!c->lock)
-                               c->status = SCF_EDA_Status_OFF;
+
+                       c->status = SCF_EDA_Status_OFF;
                }
 
                scf_loge("\033[34mc%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n",
index bbc7ef83bee2255e113e6821e0feadd0b47c40cb..5c1a75d28c7da6ebb5cd3b7a32cb5fdc70bda9af 100644 (file)
@@ -105,7 +105,7 @@ static int _dc_pnp_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t
                }
 
                scf_loge("\033[34mc%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n",
-                               c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_PNP_OFF);
+                               c->id, c->status, c->lock, pb->v, pe->v, pe->v - pb->v, SCF_EDA_V_PNP_OFF);
        }
 
        return 0;
index 471ed979e4adb28c23835bf36991463d33135d47..848de5e23672328d2bfd609e56612b2d9d8da5b6 100644 (file)
@@ -151,8 +151,8 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
                                break;
 
                        case SCF_EDA_Capacitor:
-
                                cairo_set_source_rgb(cr, 0.8, 0.0, 0.0);
+
                                p = c->pins[SCF_EDA_Battery_POS];
                                if (p->y < c->y) {
                                        cairo_move_to(cr, c->x - 8, c->y - 5);
@@ -199,7 +199,64 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
 
                                cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
 
-                               snprintf(text, sizeof(text) - 1, "%lguf", c->uf);
+                               if (c->uf < 1e-6)
+                                       snprintf(text, sizeof(text) - 1, "%lgpF", c->uf * 1e6);
+                               else if (c->uf < 1e-3)
+                                       snprintf(text, sizeof(text) - 1, "%lgnF", c->uf * 1000.0);
+                               else
+                                       snprintf(text, sizeof(text) - 1, "%lguF", c->uf);
+
+                               cairo_move_to  (cr, c->x + 4, c->y - 5);
+                               cairo_show_text(cr, text);
+                               cairo_stroke(cr);
+                               break;
+
+                       case SCF_EDA_Inductor:
+                               cairo_set_source_rgb(cr, 0.8, 0.0, 0.0);
+                               p = c->pins[SCF_EDA_Battery_POS];
+#define DRAW_Inductor() \
+                               do { \
+                                       if (p->y < c->y) { \
+                                               cairo_arc(cr, c->x + 1, c->y - 15, 5, M_PI * 0.45, M_PI * 1.55); \
+                                               cairo_stroke(cr); \
+                                               cairo_arc(cr, c->x + 1, c->y - 5, 5, M_PI * 0.45, M_PI * 1.55); \
+                                               cairo_stroke(cr); \
+                                               cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); \
+                                               cairo_move_to(cr, c->x, c->y - 19); \
+                                       } else { \
+                                               cairo_arc(cr, c->x + 1, c->y + 15, 5, M_PI * 0.45, M_PI * 1.55); \
+                                               cairo_stroke(cr); \
+                                               cairo_arc(cr, c->x + 1, c->y + 5, 5, M_PI * 0.45, M_PI * 1.55); \
+                                               cairo_stroke(cr); \
+                                               cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); \
+                                               cairo_move_to(cr, c->x, c->y + 19); \
+                                       } \
+                                       cairo_line_to(cr, p->x, p->y); \
+                               } while (0)
+
+                               DRAW_Inductor();
+                               cairo_stroke(cr);
+
+                               cairo_set_source_rgb(cr, 0.0, 0.0, 0.8);
+                               p = c->pins[SCF_EDA_Battery_NEG];
+                               DRAW_Inductor();
+                               cairo_stroke(cr);
+
+                               cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+
+                               ses_text_v(cr, c->x + 10, c->y + 10, c->v);
+                               ses_text_a(cr, c->x + 10, c->y + 25, c->a);
+
+                               cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
+
+                               if (c->uh > 100000.0)
+                                       snprintf(text, sizeof(text) - 1, "%lgH", c->uh / 1000000.0);
+                               else if (c->uh > 100.0)
+                                       snprintf(text, sizeof(text) - 1, "%lgmH", c->uh / 1000.0);
+                               else if (c->uh < 1e-3)
+                                       snprintf(text, sizeof(text) - 1, "%lgnH", c->uh * 1000.0);
+                               else
+                                       snprintf(text, sizeof(text) - 1, "%lguH", c->uh);
 
                                cairo_move_to  (cr, c->x + 4, c->y - 5);
                                cairo_show_text(cr, text);
@@ -435,7 +492,7 @@ int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t b
        t %= 1000;
 
        uint8_t time[512];
-       snprintf(time, sizeof(time) - 1, "%ld,%ld,%ld,%ldns", s, ms, us, t);
+       snprintf(time, sizeof(time) - 1, "%03ld,%03ld,%03ld,%03ldns", s, ms, us, t);
        cairo_move_to  (cr, 10, 20);
        cairo_show_text(cr, time);
        cairo_stroke(cr);
@@ -589,13 +646,13 @@ static int _simplify_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx
 
        char file[128];
        snprintf(file, sizeof(file) - 1, "./simplify_%ld.png", i);
-#if 0
-       if (count < 60 * 1000)
+#if 1
+       if (count < 70000)
                return 0;
 #endif
 
        if (count % 10 == 0) {
-#if 0
+#if 1
                static FILE* fp = NULL;
                if (!fp)
                        fp = fopen("v.txt", "w");
index 44da2bf9ec72f731bc766e38d6cd783382a3ccda..ffffc88879f682bdeac29167457ae9c7475e2b70 100644 (file)
@@ -1,17 +1,24 @@
 #include"ses_core.h"
 
-static int __ses_dfs_add_path(scf_vector_t* paths, ses_path_t* path)
+static int __ses_dfs_add_ppath(scf_vector_t* paths, ses_path_t** ppath)
 {
        ScfEpin* p;
        int      j;
 
-       if (scf_vector_add(paths, path) < 0)
-               return -ENOMEM;
+       if (*ppath) {
+               if ((*ppath)->pins->size > 0) {
+
+                       if (scf_vector_add(paths, *ppath) < 0)
+                               return -ENOMEM;
 
-       for (j = 0; j < path->pins->size; j++) {
-               p         = path->pins->data[j];
-               p->pflag  = 1;
-               p->path   = (uintptr_t)path;
+                       for (j = 0; j < (*ppath)->pins->size; j++) {
+                               p         = (*ppath)->pins->data[j];
+                               p->pflag  = 1;
+                               p->path   = (uintptr_t)*ppath;
+                       }
+               } else
+                       ses_path_free(*ppath);
+               *ppath = NULL;
        }
 
        return 0;
@@ -24,11 +31,8 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
        ScfEpin*         np;
        ScfEpin*         p;
 
-       size_t i;
-       size_t j;
-
-       if (SCF_EDA_Status_OFF == rc->status)
-               return SCF_EDA_Status_OFF;
+       int64_t i;
+       int64_t j;
 
        if (SCF_EDA_Diode == rc->type && SCF_EDA_Diode_NEG == rp->id)
                return SCF_EDA_Path_OFF;
@@ -39,20 +43,22 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
        if (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E != rp->id)
                return SCF_EDA_Path_OFF;
 
-       if (!*ppath) {
-               *ppath = ses_path_alloc();
-               if (!*ppath)
+       if (SCF_EDA_Status_OFF != rc->status) {
+               if (!*ppath) {
+                       *ppath = ses_path_alloc();
+                       if (!*ppath)
+                               return -ENOMEM;
+               }
+
+               if (scf_vector_add((*ppath)->pins, rp) < 0)
                        return -ENOMEM;
        }
 
-       if (scf_vector_add((*ppath)->pins, rp) < 0)
-               return -ENOMEM;
-
        if (!((SCF_EDA_NPN == rc->type && SCF_EDA_NPN_E == rp->id)
           || (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E == rp->id)))
                rp->vflag = 1;
 
-       scf_logd("c%ld_p%ld, l%ld, vflag: %d, pflag: %d\n", rp->cid, rp->id, rp->lid, rp->vflag, rp->pflag);
+       scf_logd("c%ldp%ld, l%ld, vflag: %d, pflag: %d\n", rp->cid, rp->id, rp->lid, rp->vflag, rp->pflag);
 
        int ret = 0;
 
@@ -67,7 +73,7 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
                if (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E == np->id)
                        continue;
 
-               scf_logd("c%ld_p%ld, l%ld, vflag: %d, pflag: %d\n", np->cid, np->id, np->lid, np->vflag, np->pflag);
+               scf_logd("c%ldp%ld, l%ld, vflag: %d, pflag: %d\n", np->cid, np->id, np->lid, np->vflag, np->pflag);
 
                el = f->elines[np->lid];
 
@@ -78,33 +84,37 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
                        continue;
                }
 
-               if (!*ppath) {
-                       *ppath = ses_path_alloc();
-                       if (!*ppath)
-                               return -ENOMEM;
-               }
+               if (SCF_EDA_Status_OFF != rc->status) {
+                       if (!*ppath) {
+                               *ppath = ses_path_alloc();
+                               if (!*ppath)
+                                       return -ENOMEM;
+                       }
 
-               if (SCF_EDA_PNP == rc->type && 0 == (*ppath)->pins->size) {
+                       if (SCF_EDA_PNP == rc->type && 0 == (*ppath)->pins->size) {
 
-                       if (scf_vector_add((*ppath)->pins, rp) < 0)
+                               if (scf_vector_add((*ppath)->pins, rp) < 0)
+                                       return -ENOMEM;
+                       }
+
+                       if (scf_vector_add((*ppath)->pins, np) < 0)
                                return -ENOMEM;
                }
 
-               if (scf_vector_add((*ppath)->pins, np) < 0)
-                       return -ENOMEM;
-
                if (!((SCF_EDA_NPN == rc->type && SCF_EDA_NPN_E == np->id)
                   || (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E == np->id)))
                        np->vflag = 1;
 
                if (SCF_EDA_PIN_NEG & el->flags) {
+                       scf_logd("neg l%ld\n\n", el->id);
 
-                       ret = __ses_dfs_add_path(__paths, *ppath);
-                       if (ret < 0)
-                               return ret;
+                       return __ses_dfs_add_ppath(__paths, ppath);
+               }
+
+               if (SCF_EDA_NPN == rc->type && SCF_EDA_NPN_C == rp->id) {
+                       scf_logd("NPN C, c%ldp%ld\n\n", rp->cid, rp->id);
 
-                       *ppath = NULL;
-                       return 0;
+                       return __ses_dfs_add_ppath(__paths, ppath);
                }
 
                ret = 0;
@@ -115,16 +125,12 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
                        p  = c->pins      [el->pins[j + 1]];
 
                        if (p->pflag) {
-                               if (p != np && *ppath) {
+                               if (p != np) {
                                        scf_logd("branch: c%ld_p%ld, l%ld\n\n", c->id, p->id, el->id);
 
-                                       if ((*ppath)->pins->size > 0) {
-
-                                               ret = __ses_dfs_add_path(__paths, *ppath);
-                                               if (ret < 0)
-                                                       return ret;
-                                       } else
-                                               ses_path_free(*ppath);
+                                       ret = __ses_dfs_add_ppath(__paths, ppath);
+                                       if (ret < 0)
+                                               return ret;
 
                                        *ppath = NULL;
                                }
@@ -134,18 +140,14 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
                        if (p->vflag)
                                continue;
 
-                       if (SCF_EDA_Capacitor == rc->type && SCF_EDA_Capacitor != c->type) {
-                               if (*ppath) {
-                                       if ((*ppath)->pins->size > 0) {
+                       if ((SCF_EDA_Capacitor == rc->type || SCF_EDA_Inductor == rc->type)
+                         && SCF_EDA_Capacitor != c->type  && SCF_EDA_Inductor != c->type) {
 
-                                               ret = __ses_dfs_add_path(__paths, *ppath);
-                                               if (ret < 0)
-                                                       return ret;
-                                       } else
-                                               ses_path_free(*ppath);
+                               ret = __ses_dfs_add_ppath(__paths, ppath);
+                               if (ret < 0)
+                                       return ret;
 
-                                       *ppath = NULL;
-                               }
+                               *ppath = NULL;
                        }
 
                        if (!((SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id)
@@ -154,7 +156,8 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
 
                        ses_path_t* tmp = NULL;
 
-                       if (SCF_EDA_Capacitor != rc->type && SCF_EDA_Capacitor == c->type) {
+                       if ((SCF_EDA_Capacitor == c->type  || SCF_EDA_Inductor == c->type)
+                         && SCF_EDA_Capacitor != rc->type && SCF_EDA_Inductor != rc->type) {
                                tmp    = *ppath;
                                *ppath = NULL;
                        }
@@ -166,8 +169,17 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
                        if (SCF_EDA_Path_OFF == ret)
                                p->vflag = 0;
 
-                       if (tmp)
+                       if (tmp) {
                                *ppath = tmp;
+
+                               if (j + 2 >= el->n_pins) {
+
+                                       ret = __ses_dfs_add_ppath(__paths, ppath);
+                                       if (ret < 0)
+                                               return ret;
+                                       *ppath = NULL;
+                               }
+                       }
                }
 
                if (*ppath) {
@@ -243,6 +255,14 @@ static int ses_path_to_npn(const ScfEfunction* f, const ses_path_t* path, int pi
        return ses_pin_to_npn(f, p0, pid) || ses_pin_to_npn(f, p1, pid);
 }
 
+static int ses_path_to_pnp(const ScfEfunction* f, const ses_path_t* path, int pid)
+{
+       const ScfEpin* p0 = path->pins->data[0];
+       const ScfEpin* p1 = path->pins->data[path->pins->size - 1];
+
+       return ses_pin_to_pnp(f, p0, pid) || ses_pin_to_pnp(f, p1, pid);
+}
+
 static int _ses_child_cmp(const void* v0, const void* v1)
 {
        const ses_path_t* p0 = *(const ses_path_t**)v0;
@@ -445,28 +465,28 @@ static int _ses_connect_cmp(const void* v0, const void* v1, void* arg)
        if (0 == p0->n_capacitors) {
                if (0 == p1->n_capacitors) {
 
-                       if (ses_path_to_npn(f, p0, SCF_EDA_NPN_B))
+                       if (ses_path_to_npn(f, p0, SCF_EDA_NPN_B) || ses_path_to_pnp(f, p0, SCF_EDA_PNP_B))
                                return -1;
-                       if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B))
+                       if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B) || ses_path_to_pnp(f, p1, SCF_EDA_PNP_B))
                                return 1;
 
-                       if (ses_path_to_npn(f, p0, SCF_EDA_NPN_C))
+                       if (ses_path_to_npn(f, p0, SCF_EDA_NPN_C) || ses_path_to_pnp(f, p0, SCF_EDA_PNP_C))
                                return -1;
-                       if (ses_path_to_npn(f, p1, SCF_EDA_NPN_C))
+                       if (ses_path_to_npn(f, p1, SCF_EDA_NPN_C) || ses_path_to_pnp(f, p1, SCF_EDA_PNP_C))
                                return 1;
                }
                return -1;
        } else if (0 == p1->n_capacitors)
                return 1;
 
-       if (ses_path_to_npn(f, p0, SCF_EDA_NPN_C))
+       if (ses_path_to_npn(f, p0, SCF_EDA_NPN_C) || ses_path_to_pnp(f, p0, SCF_EDA_PNP_C))
                return -1;
-       if (ses_path_to_npn(f, p1, SCF_EDA_NPN_C))
+       if (ses_path_to_npn(f, p1, SCF_EDA_NPN_C) || ses_path_to_pnp(f, p1, SCF_EDA_PNP_C))
                return 1;
 
-       if (ses_path_to_npn(f, p0, SCF_EDA_NPN_B))
+       if (ses_path_to_npn(f, p0, SCF_EDA_NPN_B) || ses_path_to_pnp(f, p0, SCF_EDA_PNP_B))
                return 1;
-       if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B))
+       if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B) || ses_path_to_pnp(f, p1, SCF_EDA_PNP_B))
                return -1;
 
        if (p0->n_capacitors > p1->n_capacitors)
@@ -678,6 +698,11 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths)
        for (i    = 0; i < paths->size; ) {
                path0 = paths->data[i];
 
+               if (path0->n_transistors > 0) {
+                       i++;
+                       continue;
+               }
+
                p0 = path0->pins->data[0];
                p1 = path0->pins->data[path0->pins->size - 1];
 
@@ -697,6 +722,9 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths)
                        if (path1 == path0)
                                continue;
 
+                       if (path1->n_transistors > 0)
+                               continue;
+
                        p2 = path1->pins->data[0];
                        p3 = path1->pins->data[path1->pins->size - 1];
 
@@ -978,6 +1006,8 @@ static int _topo_layers(ScfEfunction* f, scf_vector_t* paths)
        ScfEpin*       Bn;
        ScfEpin*       p0;
        ScfEpin*       p1;
+       ScfEpin*       p2;
+       ScfEpin*       p3;
        ScfEpin*       p;
 
        int i;
@@ -1005,6 +1035,14 @@ static int _topo_layers(ScfEfunction* f, scf_vector_t* paths)
                        if (parent == child)
                                continue;
 
+                       p2 = parent->pins->data[0];
+                       p3 = parent->pins->data[parent->pins->size - 1];
+
+                       if (p2->lid == p0->lid && p3->lid == p1->lid)
+                               continue;
+                       if (p3->lid == p0->lid && p2->lid == p1->lid)
+                               continue;
+
                        int n  = 0;
 
                        for (k = 0; k < parent->pins->size; k++) {
@@ -1160,7 +1198,7 @@ static void _topo_clear(ScfEfunction* f)
                c         = f->components[i];
                c->vflag  = 0;
                c->lock   = 0;
-               c->a      = 0;
+//             c->a      = 0;
 
                for (j = 0; j < c->n_pins; j++) {
                        p         = c->pins[j];
@@ -1230,6 +1268,57 @@ static int _topo_paths(ScfEfunction* f, ScfEline* el, scf_vector_t* paths)
        return 0;
 }
 
+static int __topo_bridge_connection(scf_vector_t* paths, ses_path_t* bridge, ScfEpin* vip, ses_path_t** ppath)
+{
+       ses_path_t* path;
+       ses_path_t* conn;
+       ScfEpin*    p0 = bridge->pins->data[0];
+       ScfEpin*    p1 = bridge->pins->data[bridge->pins->size - 1];
+       ScfEpin*    p2;
+       ScfEpin*    p3;
+
+       int j;
+       int k;
+
+       for (j = 0; j < paths->size; j++) {
+               path      = paths->data[j];
+
+               if (path == bridge)
+                       continue;
+
+               p2 = path->pins->data[0];
+               p3 = path->pins->data[path->pins->size - 1];
+
+               if (p2->lid == p0->lid && p3->lid == p1->lid)
+                       continue;
+               if (p3->lid == p0->lid && p2->lid == p1->lid)
+                       continue;
+
+               for (k = 0; k < path->pins->size; k++) {
+                       p2 =        path->pins->data[k];
+
+                       if (p2->lid == vip->lid) {
+                               *ppath =  path;
+                               return k;
+                       }
+               }
+
+               if (path->childs) {
+                       k = __topo_bridge_connection(path->childs, bridge, vip, ppath);
+                       if (k >= 0)
+                               return k;
+               }
+
+               if (path->bridges) {
+                       k = __topo_bridge_connection(path->bridges, bridge, vip, ppath);
+                       if (k >= 0)
+                               return k;
+               }
+       }
+
+       return -1;
+}
+
 static int _topo_bridge_piers(ScfEfunction* f, scf_vector_t* paths)
 {
        ses_path_t*    pier;
@@ -1240,8 +1329,6 @@ static int _topo_bridge_piers(ScfEfunction* f, scf_vector_t* paths)
        ScfEpin*       Bn = B->pins[SCF_EDA_Battery_NEG];
        ScfEpin*       p0;
        ScfEpin*       p1;
-       ScfEpin*       p2;
-       ScfEpin*       p3;
 
        int i;
        int j;
@@ -1253,40 +1340,30 @@ static int _topo_bridge_piers(ScfEfunction* f, scf_vector_t* paths)
                p0 = pier->pins->data[0];
                p1 = pier->pins->data[pier->pins->size - 1];
 
-               if (p0->lid != Bp->lid && p1->lid != Bn->lid)
-                       continue;
-
-               pier->parent_p0 = -2;
-               pier->parent_p1 = -2;
+               bridge = NULL;
 
-               for (j     = paths->size - 1; j >= 0; j--) {
-                       bridge = paths->data[j];
-
-                       if (pier == bridge)
+               if (p0->lid == Bp->lid) {
+                       if (p1->lid == Bn->lid)
                                continue;
 
-                       p2 = bridge->pins->data[0];
-                       p3 = bridge->pins->data[bridge->pins->size - 1];
-
-                       if (p2->lid == Bp->lid || p3->lid == Bn->lid)
+                       k = __topo_bridge_connection(paths, pier, p1, &bridge);
+                       if (k < 0)
                                continue;
 
-                       for (k = 0; k < bridge->pins->size; k++) {
-                               p2 =        bridge->pins->data[k];
+                       pier->parent_p0 = -2;
+                       pier->parent_p1 = k;
 
-                               if (p2->lid == p0->lid) {
-                                       pier->parent_p0 = (k + 1) & ~0x1;
-                                       goto found;
+               } else if (p1->lid == Bn->lid) {
 
-                               } else if (p2->lid == p1->lid) {
-                                       pier->parent_p1 = k;
-                                       goto found;
-                               }
-                       }
-               }
+                       k = __topo_bridge_connection(paths, pier, p0, &bridge);
+                       if (k < 0)
+                               continue;
+
+                       pier->parent_p0 = (k + 1) & ~0x1;
+                       pier->parent_p1 = -2;
+               } else
+                       continue;
 
-               continue;
-found:
                if (!bridge->bridges) {
                        bridge->bridges = scf_vector_alloc();
                        if (!bridge->bridges)
@@ -1305,46 +1382,6 @@ found:
        return 0;
 }
 
-static int __topo_bridge_connection(scf_vector_t* paths, ses_path_t* bridge, ScfEpin* vip, ses_path_t** ppath)
-{
-       ses_path_t* path;
-       ses_path_t* conn;
-       ScfEpin*    p;
-
-       int j;
-       int k;
-
-       for (j = 0; j < paths->size; j++) {
-               path      = paths->data[j];
-
-               if (path == bridge)
-                       continue;
-
-               for (k = 0; k < path->pins->size; k++) {
-                       p  =        path->pins->data[k];
-
-                       if (p->lid == vip->lid) {
-                               *ppath =  path;
-                               return k;
-                       }
-               }
-
-               if (path->childs) {
-                       k = __topo_bridge_connection(path->childs, bridge, vip, ppath);
-                       if (k >= 0)
-                               return k;
-               }
-
-               if (path->bridges) {
-                       k = __topo_bridge_connection(path->bridges, bridge, vip, ppath);
-                       if (k >= 0)
-                               return k;
-               }
-       }
-
-       return -1;
-}
-
 static int _topo_add_connection(ses_path_t* path, ses_path_t* conn)
 {
        if (!conn->connections) {
@@ -1359,6 +1396,8 @@ static int _topo_add_connection(ses_path_t* path, ses_path_t* conn)
 static int _topo_bridge_connections(ScfEfunction* f, scf_vector_t* paths)
 {
        ses_path_t*    path;
+       ses_path_t*    conn0;
+       ses_path_t*    conn1;
 
        ScfEcomponent* B  = f->components[0];
        ScfEpin*       Bp = B->pins[SCF_EDA_Battery_POS];
@@ -1367,6 +1406,7 @@ static int _topo_bridge_connections(ScfEfunction* f, scf_vector_t* paths)
        ScfEpin*       p1;
 
        int i;
+       int j;
 
        for (i   = paths->size - 1; i >= 0; i--) {
                path = paths->data[i];
@@ -1379,26 +1419,68 @@ static int _topo_bridge_connections(ScfEfunction* f, scf_vector_t* paths)
 
                int k0 = __topo_bridge_connection(paths, path, p0, &path->conn0);
                if (k0 < 0)
-                       return -EINVAL;
+                       continue;
 
                int k1 = __topo_bridge_connection(paths, path, p1, &path->conn1);
                if (k1 < 0)
-                       return -EINVAL;
+                       continue;
 
-               path->parent = ses_path_same_net(path->conn0, path->conn1);
-               if (path->parent) {
-                       path->parent_p0 = (k0 + 1) & ~0x1;
-                       path->parent_p1 =  k1;
+               path->parent_p0 = (k0 + 1) & ~0x1;
+               path->parent_p1 =  k1;
+               path->parent    =  path->conn0;
 
-                       int ret = _topo_add_connection(path, path->conn0);
-                       if (ret < 0)
-                               return ret;
+               int ret = _topo_add_connection(path, path->conn0);
+               if (ret < 0)
+                       return ret;
 
-                       ret = _topo_add_connection(path, path->conn1);
-                       if (ret < 0)
-                               return ret;
+               ret = _topo_add_connection(path, path->conn1);
+               if (ret < 0)
+                       return ret;
+
+               assert(0 == scf_vector_del(paths, path));
+       }
 
-                       assert(0 == scf_vector_del(paths, path));
+       return 0;
+}
+
+static int _topo_path_parallel(ScfEfunction* f, scf_vector_t* paths)
+{
+       ses_path_t*    child;
+       ses_path_t*    parent;
+       ScfEpin*       p0;
+       ScfEpin*       p1;
+       ScfEpin*       p2;
+       ScfEpin*       p3;
+       ScfEpin*       p;
+
+       int i;
+       int j;
+
+       for (i    = paths->size - 1; i >= 0; i--) {
+               child = paths->data[i];
+
+               assert(child->pins->size >= 2);
+
+               p0 = child->pins->data[0];
+               p1 = child->pins->data[child->pins->size - 1];
+
+               for (j     = paths->size - 1; j >= 0; j--) {
+                       parent = paths->data[j];
+
+                       if (parent == child)
+                               continue;
+
+                       p2 = parent->pins->data[0];
+                       p3 = parent->pins->data[parent->pins->size - 1];
+
+                       if (p0->lid == p2->lid && p1->lid == p3->lid) {
+
+                               int ret = ses_path_add(parent, child, f);
+                               if (ret < 0)
+                                       return ret;
+
+                               assert(0 == scf_vector_del(paths, child));
+                       }
                }
        }
 
@@ -1439,41 +1521,6 @@ static int __ses_topo_layers(ScfEfunction* f, scf_vector_t* paths)
        return _topo_bridge_piers(f, paths);
 }
 
-int __ses_topo_paths(ScfEfunction* f, scf_vector_t*  paths)
-{
-       if (!f || !paths)
-               return -EINVAL;
-
-       ses_path_t*      path;
-       ScfEcomponent*   B;
-       ScfEline*        el;
-
-       _topo_clear(f);
-
-       scf_vector_clear(paths, ( void (*)(void*) )ses_path_free);
-
-       B  = f->components[0];
-       el = f->elines[B->pins[SCF_EDA_Battery_POS]->lid];
-
-       int ret = _topo_paths(f, el, paths);
-       if (ret < 0)
-               return ret;
-
-       int i;
-       for (i = 0; i < f->n_elines; i++) {
-               el =        f->elines[i];
-
-               if (el->flags & SCF_EDA_PIN_IN) {
-
-                       ret = _topo_paths(f, el, paths);
-                       if (ret < 0)
-                               return ret;
-               }
-       }
-
-       return __ses_topo_layers(f, paths);
-}
-
 static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
 {
        ses_path_t*      path;
@@ -1500,6 +1547,10 @@ static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t*
        if (ret < 0)
                return ret;
 
+       ret = _topo_path_parallel(f, ctx->paths);
+       if (ret < 0)
+               return ret;
+
        int i;
        for (i = 0; i < ctx->paths->size; i++) {
                path      = ctx->paths->data[i];
index cbdfb2c69ed62c1e6ae9dd29266effb0dfc7f1e3..7610a28a46196b0bfa23604286b2279047da8f91 100644 (file)
@@ -122,6 +122,7 @@ static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, int n,
 
                double sr = 0;
                double cv = 0;
+               double lv = 0;
                double dv = 0;
                double da = 0;
                double pr;
@@ -133,14 +134,14 @@ static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, int n,
 
                ses_ur_i(&child->a0, NULL, v, 0, child->pr, 0);
 
-               if (__ses_path_capacitors(f, path, i, k, &cv) > 0)
-                       v += cv;
+               __ses_path_lc(f, path, i, k, &cv, &lv, NULL, NULL, NULL);
+               v += cv + lv;
 
                ses_ur_i(&child->a, 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, n_NPNs: %d), v: %lg, cv: %lg, dv: %lg, a: %lg, pr: %lg, sr: %lg\n",
+               scf_logw("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d, n_NPNs: %d), v: %lg, cv: %lg, lv: %lg, dv: %lg, a: %lg, pr: %lg, sr: %lg\n",
                                child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id,
-                               child->n_diodes, child->n_NPNs, v, cv, dv, *a, pr, sr);
+                               child->n_diodes, child->n_NPNs, v, cv, lv, dv, *a, pr, sr);
 
                *a  -= child->a0;
 
@@ -181,9 +182,9 @@ static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, int n,
                p1->pr  = _pr1;
                p1->sr  = _sr1;
 
-               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, cv: %lg, cda: %lg\n\n",
+               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, cv: %lg, lv: %lg\n\n",
                                child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id,
-                               child->n_diodes + child->n_NPNs, p0->v, v, child->a0, child->a, cv, child->cda);
+                               child->n_diodes + child->n_NPNs, p0->v, v, child->a0, child->a, cv, lv);
 
                n_childs++;
        }
@@ -207,7 +208,7 @@ static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i,
 
        p->v = p0->v - v;
 
-       if (SCF_EDA_Capacitor == c->type && (i & 0x1)) {
+       if ((SCF_EDA_Capacitor == c->type || SCF_EDA_Inductor == c->type) && (i & 0x1)) {
                int sign = !p->id - p->id;
 
                p->v -= c->v * sign;
@@ -216,30 +217,55 @@ static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i,
        scf_logd("c%ldp%ld, c%ldp%ld, a: %lg, r: %lg, v: %lg, p0->v: %lg, p->v: %lg\n", p0->cid, p0->id, p->cid, p->id, a, r, v, p0->v, p->v);
 }
 
-int __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv)
+void __ses_path_lc(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv, double* lv, double* uf, double* uh, double* la)
 {
        ScfEcomponent* c;
        ScfEpin*       p;
 
-       double v = 0;
-       int    k = 0;
-       int    i;
+       int i;
+
+       if (cv)
+               *cv = 0;
+
+       if (lv)
+               *lv = 0;
+
+       if (uf)
+               *uf = 0;
+
+       if (uh)
+               *uh = 0;
+
+       if (la)
+               *la = 0;
 
        for (i = m; i <= n; i++) {
                p  = path->pins->data[i];
 
                c  = f->components[p->cid];
 
-               if (SCF_EDA_Capacitor == c->type && (i & 0x1)) {
+               if (i & 0x1) {
                        int sign = !p->id - p->id;
 
-                       v += c->v * sign;
-                       k++;
+                       if (SCF_EDA_Capacitor == c->type) {
+                               if (cv)
+                                       *cv += c->v * sign;
+
+                               if (uf)
+                                       *uf += c->uf;
+
+                       } else if (SCF_EDA_Inductor == c->type) {
+                               if (la)
+                                       *la = c->a * sign;
+
+                               if (lv)
+                                       *lv += c->v * sign;
+
+                               if (uh)
+                                       *uh += c->uh;
+                       }
                }
        }
-
-       *cv = v;
-       return k;
 }
 
 int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count)
@@ -255,9 +281,6 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double
        if (n - m < 1)
                return 0;
 
-//     if (path->vflag)
-//             return 0;
-
        ScfEcomponent* c;
        ScfEline*      el;
        ScfEpin*       p;
@@ -281,23 +304,23 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double
        }
 
        double cv = 0;
+       double lv = 0;
        double a  = 0;
        double v  = p0->v - p1->v;
 
-       __ses_path_capacitors(f, path, m, n, &cv);
-       v -= cv;
+       __ses_path_lc(f, path, m, n, &cv, &lv, NULL, NULL, NULL);
+       v -= cv + lv;
 
        ses_ur_i(&a, NULL, v, 0, pr, 0);
 
        if (0 == m && path->pins->size - 1 == n)
                path->a = a;
 
-       scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, pr: %lg, path->pr: %lg, a: %lg\n\n",
-                       path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, pr, path->pr, a);
+       scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, lv: %lg, pr: %lg, path->pr: %lg, a: %lg\n\n",
+                       path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, lv, pr, path->pr, a);
 
        double r   = 0;
        double dv  = 0;
-       double dv0 = 0;
        double dvc = 0;
 
        int i0 = m;
@@ -314,7 +337,7 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double
                __ses_path_split_v(f, path, i0, i, a);
 
                p->a  = a;
-               p->v -= dv0 + dvc;
+               p->v -= dvc;
                el->v = p->v;
 
                r += p->r + p->dr;
@@ -326,20 +349,30 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double
 
                        int sign = !p->id - p->id;
 
-                       c->a  = a * sign;
                        p2->a = a;
 
                        if (SCF_EDA_Capacitor == c->type) {
                                cv  = c->v * sign;
                                dv -= cv;
 
-                               c->v += a * sign * ns / 1e3 / c->uf;
-
+                               c->a = a * sign;
                                dvc += cv;
 
-                               scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uf: %lg\n",
+                               scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uF: %lg\n",
                                                c->id, c->v, p->v, p2->v, dv, p->a, c->a, ns, c->uf);
-                       }
+
+                       } else if (SCF_EDA_Inductor == c->type) {
+                               lv  = c->v * sign;
+                               dv -= lv;
+
+                               c->a = a * sign;
+                               dvc += lv;
+
+                               scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uH: %lg\n",
+                                               c->id, c->v, p->v, p2->v, dv, p->a, c->a, ns, c->uh);
+                       } else
+                               c->a = a * sign;
+
                        c->count = count;
 
                        scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, r: %lg, p->a: %lg, a: %lg, p->pr: %lg, e%ld->v: %lg\n\n",
@@ -385,8 +418,8 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double
                        r  = 0;
                } else {
                        dv = p->v;
-                       scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, a: %lg, p->pr: %lg, dv0: %lg, e%ld->v: %lg\n",
-                                       path->index, i, p->cid, p->id, p->v, dv, a, p->pr, dv0, el->id, el->v);
+                       scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, a: %lg, p->pr: %lg, e%ld->v: %lg\n",
+                                       path->index, i, p->cid, p->id, p->v, dv, a, p->pr, el->id, el->v);
                }
        }
        printf("\n");
@@ -429,19 +462,20 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i
        ScfEpin*       cp1;
 
        double cv = 0;
+       double lv = 0;
        double a  = 0;
        double v  = p0->v - p1->v;
 
-       __ses_path_capacitors(f, path, m, n, &cv);
-       v -= cv;
+       __ses_path_lc(f, path, m, n, &cv, &lv, NULL, NULL, NULL);
+       v -= cv + lv;
 
        ses_ur_i(&a, NULL, v, 0, pr, 0);
 
        if (0 == m && path->pins->size - 1 == n)
                path->a = a;
 
-       scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, pr: %lg, path->pr: %lg, a: %lg\n\n",
-                       path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, pr, path->pr, a);
+       scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, lv: %lg, pr: %lg, path->pr: %lg, a: %lg\n\n",
+                       path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, lv, pr, path->pr, a);
 
        double r   = 0;
        double dv  = 0;
@@ -505,6 +539,14 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i
 
                                scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uf: %lg\n",
                                                c->id, c->v, p->v, p2->v, dv, p->a, c->a, ns, c->uf);
+
+                       } else if (SCF_EDA_Inductor == c->type) {
+                               lv  = c->v * sign;
+                               dv -= lv;
+                               ses_ur_i(&p->a, NULL, dv, 0, r, 0);
+
+                               dvc += lv;
+
                        } else if (p->a > a) {
                                p->a = a;
                                c->a = p->a * sign;
index 286b4666aa679befde9f6244c7a7360f1927d803..985a139f055da8b06e5b8a0e3bb421b69a0f164c 100644 (file)
@@ -96,10 +96,11 @@ void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double
                        continue;
 
                double cv = 0;
+               double lv = 0;
 
                if (child->n_capacitors > 0) {
-                       __ses_path_capacitors(f, child, 0, child->pins->size - 1, &cv);
-                       v -= cv;
+                       __ses_path_lc(f, child, 0, child->pins->size - 1, &cv, &lv, NULL, NULL, NULL);
+                       v -= cv + lv;
                        ses_ur_i(&child->a, NULL, v, 0, child->pr, 0);
                } else {
                        ses_ur_i(&child->a, NULL, v, 0, child->pr, 0);
@@ -125,8 +126,8 @@ void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double
                                goto ok;
                }
 
-               scf_logi("k: %d, c%ldp%ld--c%ldp%ld, v: %lg, cv: %lg, child->pr: %lg, r: %lg, child->a: %lg, el->a: %lg\n",
-                               k, cp0->cid, cp0->id, cp1->cid, cp1->id, v, cv, child->pr, r, child->a, la);
+               scf_logi("k: %d, c%ldp%ld--c%ldp%ld, v: %lg, cv: %lg, lv: %lg, child->pr: %lg, r: %lg, child->a: %lg, el->a: %lg\n",
+                               k, cp0->cid, cp0->id, cp1->cid, cp1->id, v, cv, lv, child->pr, r, child->a, la);
 
                cp1->v = p1->v;
                cp0->v = p0->v;
@@ -235,6 +236,7 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path)
        double r;
        double a;
        double cv = 0;
+       double lv = 0;
 
        int i = 0;
        int j;
@@ -252,9 +254,9 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path)
                        || (SCF_EDA_NPN   == c->type && SCF_EDA_NPN_B     == pi->id)
                        || (SCF_EDA_PNP   == c->type && SCF_EDA_PNP_E     == pi->id));
 
-               __ses_path_capacitors(f, path, i, path->pins->size - 1, &cv);
+               __ses_path_lc(f, path, i, path->pins->size - 1, &cv, &lv, NULL, NULL, NULL);
 
-               __ses_path_a_diode(f, path, i, j, cv, &a);
+               __ses_path_a_diode(f, path, i, j, cv + lv, &a);
 
                if (a < 0)
                        break;
@@ -269,15 +271,16 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path)
                ses_ir_u(&v, NULL, a, 0, r, 0);
 
                double cv2 = 0;
-               __ses_path_capacitors(f, path, i, info->i, &cv2);
+               double lv2 = 0;
+               __ses_path_lc(f, path, i, info->i, &cv2, &lv2, NULL, NULL, NULL);
 
-               pi->v = p0->v - v - cv2;
+               pi->v = p0->v - v - cv2 - lv2;
                pj->v = pi->v - info->n_diodes * SCF_EDA_V_Diode_ON
                       - info->n_NPNs   * SCF_EDA_V_NPN_ON
                       - info->n_PNPs   * SCF_EDA_V_PNP_ON;
 
-               scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, cv2: %lg, r: %lg, v: %lg, a: %lg\n",
-                               p0->cid, p0->id, p0->v, pi->cid, pi->id, pi->v, pj->cid, pj->id, pj->v, cv2, r, v, a);
+               scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, cv2: %lg, lv2: %lg, r: %lg, v: %lg, a: %lg\n",
+                               p0->cid, p0->id, p0->v, pi->cid, pi->id, pi->v, pj->cid, pj->id, pj->v, cv2, lv2, r, v, a);
 
                el         = f->elines[pi->lid];
                el->v      = pi->v;
index e450f7b2630dd97d4266351927561d885b247de4..609c3404fe951870ed0ed32e05941ffb8b5b379f 100644 (file)
@@ -62,8 +62,8 @@ static int _va_nodes_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx
                p0 = path->pins->data[0];
                p1 = path->pins->data[path->pins->size - 1];
 
-               if (p0->lid != Bp->lid || p1->lid != Bn->lid)
-                       continue;
+//             if (p0->lid != Bp->lid || p1->lid != Bn->lid)
+//                     continue;
 
                scf_logi("i: %d, path->index: %d\n", i, path->index);
 
index a269c8d7053716643d2e34daff8afd5c4e092706..61c6a3b8ca8fd311c09bb812a511848397d5ea20 100644 (file)
@@ -12,13 +12,11 @@ extern ses_step_t   ses_step_topo;
 
 extern ses_step_t   ses_step_jr;
 extern ses_step_t   ses_step_va_diode;
-extern ses_step_t   ses_step_va_transistor;
 extern ses_step_t   ses_step_va;
 extern ses_step_t   ses_step_status;
 
 extern ses_step_t   ses_step_open;
 extern ses_step_t   ses_step_va_nodes;
-extern ses_step_t   ses_step_va_capacitor;
 
 extern ses_step_t   ses_step_a_stat;
 
@@ -42,17 +40,16 @@ static ses_step_t*  ses_steps_1[] =
 
        &ses_step_topo,
 
-       &ses_step_va_diode,
+//     &ses_step_va_diode,
 
-       &ses_step_va,
-       &ses_step_status,
+//     &ses_step_va,
+//     &ses_step_status,
 };
 
 static ses_step_t*  ses_steps_2[] =
 {
        &ses_step_open,
        &ses_step_va_nodes,
-//     &ses_step_va_capacitor,
 
 //     &ses_step_a_stat,
 
index a9ba53e47454c0e93d265fa9875fcccfa0e41449..fd2a2804eacee8485dd207d67cd54fd916d077f5 100644 (file)
@@ -37,18 +37,12 @@ ses_edge_t* ses_edge_alloc(ses_path_t* path, int first, int last)
        edge->vip_m = first;
        edge->vip_n = last;
 
-       edge->refs = 1;
        return edge;
 }
 
 void ses_edge_free(ses_edge_t* edge)
 {
        if (edge) {
-               if (--edge->refs > 0)
-                       return;
-
-               assert(0 == edge->refs);
-
                free(edge);
        }
 }
@@ -103,68 +97,6 @@ void ses_edge_print(ses_edge_t* edge)
        printf("; ");
 }
 
-ses_mesh_t* ses_mesh_alloc()
-{
-       ses_mesh_t* mesh = calloc(1, sizeof(ses_mesh_t));
-       if (!mesh)
-               return NULL;
-
-       mesh->edges = scf_vector_alloc();
-       if (!mesh->edges) {
-               free(mesh);
-               return NULL;
-       }
-
-       return mesh;
-}
-
-void ses_mesh_free(ses_mesh_t* mesh)
-{
-       if (mesh) {
-               scf_vector_clear(mesh->edges, (void (*)(void*) )ses_edge_free);
-               scf_vector_free(mesh->edges);
-
-               free(mesh);
-       }
-}
-
-void ses_meshs_free(scf_vector_t* meshs)
-{
-       if (meshs) {
-               scf_vector_clear(meshs, (void (*)(void*) )ses_mesh_free);
-               scf_vector_free(meshs);
-       }
-}
-
-void ses_mesh_print(ses_mesh_t* mesh)
-{
-       if (!mesh)
-               return;
-
-       ses_edge_t* edge;
-
-       int i;
-
-       for (i = 0; i < mesh->edges->size; i++) {
-               edge      = mesh->edges->data[i];
-
-               ses_edge_print(edge);
-       }
-       printf("\n");
-}
-
-void ses_meshs_print(scf_vector_t* meshs)
-{
-       if (!meshs)
-               return;
-
-       int i;
-       for (i = 0; i < meshs->size; i++) {
-
-               ses_mesh_print(meshs->data[i]);
-       }
-}
-
 ses_node_t* ses_node_alloc()
 {
        ses_node_t* node = calloc(1, sizeof(ses_node_t));
@@ -183,7 +115,6 @@ ses_node_t* ses_node_alloc()
 void ses_node_free(ses_node_t* node)
 {
        if (node) {
-               scf_vector_clear(node->edges, (void (*)(void*) )ses_edge_free);
                scf_vector_free(node->edges);
 
                free(node);
index a10716ef956bd664bcdab60dd1fe7a86271aab46..5c5ce8c99ea8625cd2c785626d64e9024d6c2d0a 100644 (file)
@@ -1,7 +1,9 @@
 #CFILES += main.c
 #CFILES += test.c
-#CFILES += fft.c
-CFILES += pnp.c
+CFILES += fft.c
+#CFILES += dct.c
+#CFILES += pnp.c
+#CFILES += colpitts.c
 CFILES += ../scf_eda_pack.c
 CFILES += ../pack/scf_pack.c
 
diff --git a/test/colpitts.c b/test/colpitts.c
new file mode 100644 (file)
index 0000000..dc1fe97
--- /dev/null
@@ -0,0 +1,101 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include"ses_core.h"
+
+int main(int argc, char* argv[])
+{
+       ScfEcomponent* B;
+
+       ScfEcomponent* R0;
+       ScfEcomponent* C0;
+       ScfEcomponent* T0;
+
+       ScfEcomponent* R1;
+       ScfEcomponent* R2;
+       ScfEcomponent* R3;
+
+       ScfEcomponent* C1;
+       ScfEcomponent* C2;
+       ScfEcomponent* C3;
+       ScfEcomponent* L0;
+
+       ScfEfunction*  f;
+       ScfEboard*     b;
+
+       b = scf_eboard__alloc();
+       f = scf_efunction__alloc("colpitts_oscillator");
+
+       EDA_INST_ADD_COMPONENT(f, B,  SCF_EDA_Battery);
+
+       B->pins[SCF_EDA_Battery_NEG]->flags = SCF_EDA_PIN_NEG;
+       B->pins[SCF_EDA_Battery_POS]->flags = SCF_EDA_PIN_POS;
+
+       EDA_INST_ADD_COMPONENT(f, R0, SCF_EDA_Resistor);
+       EDA_INST_ADD_COMPONENT(f, C0, SCF_EDA_Capacitor);
+       EDA_INST_ADD_COMPONENT(f, T0, SCF_EDA_NPN);
+
+       EDA_INST_ADD_COMPONENT(f, R1, SCF_EDA_Resistor);
+       EDA_INST_ADD_COMPONENT(f, R2, SCF_EDA_Resistor);
+       EDA_INST_ADD_COMPONENT(f, R3, SCF_EDA_Resistor);
+
+       EDA_INST_ADD_COMPONENT(f, C1, SCF_EDA_Capacitor);
+       EDA_INST_ADD_COMPONENT(f, C2, SCF_EDA_Capacitor);
+       EDA_INST_ADD_COMPONENT(f, C3, SCF_EDA_Capacitor);
+       EDA_INST_ADD_COMPONENT(f, L0, SCF_EDA_Inductor);
+
+       EDA_PIN_ADD_PIN(B,  SCF_EDA_Battery_POS,  R1, 1);
+       EDA_PIN_ADD_PIN(R1, 0,                    T0, SCF_EDA_NPN_C);
+       EDA_PIN_ADD_PIN(T0, SCF_EDA_NPN_E,        R0, 1);
+       EDA_PIN_ADD_PIN(R0, 1,                    C0, 1);
+       EDA_PIN_ADD_PIN(R0, 0,                    C0, 0);
+       EDA_PIN_ADD_PIN(R0, 0,                    B,  SCF_EDA_Battery_NEG);
+
+       EDA_PIN_ADD_PIN(B,  SCF_EDA_Battery_POS,  R2, 1);
+       EDA_PIN_ADD_PIN(R2, 0,                    R3, 1);
+       EDA_PIN_ADD_PIN(R3, 1,                    T0, SCF_EDA_NPN_B);
+       EDA_PIN_ADD_PIN(R3, 0,                    B,  SCF_EDA_Battery_NEG);
+
+       EDA_PIN_ADD_PIN(C1, 1,                    T0, SCF_EDA_NPN_C);
+       EDA_PIN_ADD_PIN(C1, 0,                    B,  SCF_EDA_Battery_NEG);
+       EDA_PIN_ADD_PIN(L0, 1,                    T0, SCF_EDA_NPN_C);
+       EDA_PIN_ADD_PIN(L0, 0,                    C2, 1);
+       EDA_PIN_ADD_PIN(C2, 0,                    B,  SCF_EDA_Battery_NEG);
+       EDA_PIN_ADD_PIN(C3, 1,                    C2, 1);
+       EDA_PIN_ADD_PIN(C3, 0,                    T0, SCF_EDA_NPN_B);
+
+       T0->pins[SCF_EDA_NPN_C]->flags |= SCF_EDA_PIN_OUT;
+       T0->pins[SCF_EDA_NPN_C]->hfe    = 150;
+
+       R0->r  = 1000;
+       R1->r  = 1000;
+       R2->r  = 1000 * 10;
+       R3->r  = 1000 * 10;
+       C0->uf = 10;
+       C1->uf = 0.01;
+       C2->uf = 0.01;
+       C3->uf = 0.01;
+       C1->r  = 1;
+       C2->r  = 1;
+       C3->r  = 1;
+       L0->uh = 1000;
+       L0->r  = 1;
+
+       scf_eboard__add_function(b, f);
+
+       int      len = 0;
+       uint8_t* buf = NULL;
+
+       ScfEboard_pack(b, &buf, &len);
+       ScfEboard_free(b);
+       b = NULL;
+
+       FILE* fp = fopen("./colpitts_oscillator.cpk", "wb");
+       if (!fp)
+               return -EINVAL;
+
+       fwrite(buf, len, 1, fp);
+       fclose(fp);
+
+       return 0;
+}
diff --git a/test/dct.c b/test/dct.c
new file mode 100644 (file)
index 0000000..6d05f9f
--- /dev/null
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <math.h>
+
+#define N 256
+
+void dct(double* dst, double* src, int n)
+{
+       int i;
+       int u;
+
+       for (u = 0; u < n; u++) {
+               dst[u] = 0;
+
+               for (i = 0; i < n; i++)
+                       dst[u] += src[i] * cos((i + 0.5) * 3.1415926 * u / n);
+
+               if (0 == u)
+                       dst[u] *= sqrt(1.0 / n);
+               else
+                       dst[u] *= sqrt(2.0 / n);
+       }
+}
+
+int main()
+{
+       double v;
+
+       int i;
+       int j;
+
+       FILE* fp = fopen("v.txt", "r");
+
+       double src[N];
+       double dst[N];
+
+       for (i = 0; i < N; i++) {
+               fscanf(fp, "%d, %lg", &j, &v);
+               src[i] = v;
+       }
+
+       dct(dst, src, N);
+
+       double Zmax = 0;
+       double sum  = 0;
+       int    imax = 0;
+
+       for (i = 0; i < N; i++) {
+
+               if (i > 0) {
+                       double Z = sqrt(dst[i] * dst[i]);
+
+                       if (Zmax < Z) {
+                               Zmax = Z;
+                               imax = i;
+                       }
+
+                       sum += Z;
+               }
+
+               printf("%d, %lg\n", i, dst[i]);
+       }
+
+       double f = 100 * 1000 * imax / N;
+
+       printf("avg: %lg, Zmax: %lg, imax: %d, f: %lg\n", sum / (N - 1), Zmax, imax, f);
+
+       fclose(fp);
+       return 0;
+}
index f2384dc5260ad4c249b373db7c8b5107cd49f2a5..b7812eef2deb4447a9071f67602c16243e47b896 100644 (file)
@@ -8,7 +8,7 @@
 #define REAL(z,i) ((z)[2*(i)])
 #define IMAG(z,i) ((z)[2*(i)+1])
 
-#define N 1024
+#define N 256
 
 int main()
 {
@@ -32,7 +32,7 @@ int main()
        double sum  = 0;
        int    imax = 0;
 
-       for (i = 0; i < N; i++) {
+       for (i = 0; i < N / 2; i++) {
 
                if (i > 0) {
                        double real = REAL(data, i) / sqrt(N);