support PNP transistor, add pnp_oscillator.cpk
authoryu.dongliang <18588496441@163.com>
Sun, 26 May 2024 06:13:57 +0000 (14:13 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 26 May 2024 06:13:57 +0000 (14:13 +0800)
21 files changed:
Makefile
examples/pnp_oscillator.cpk [new file with mode: 0644]
main.c
scf_eda_pack.h
ses_core.h
ses_layout.c
ses_node_analysis.c
ses_path.c
ses_step_dc_npn.c [moved from ses_step_dc_transistor.c with 92% similarity]
ses_step_dc_pnp.c [new file with mode: 0644]
ses_step_output.c
ses_step_simplify.c
ses_step_status.c
ses_step_topo.c
ses_step_va.c
ses_step_va_diode.c
ses_step_va_transistor.c [deleted file]
ses_steps.c
ses_utils.c
test/Makefile
test/pnp.c [new file with mode: 0644]

index 9b4794d6bcf46f405824938fa99f17f189392f69..9619bf1164711b84af384ee63e5e7b71076ebbad 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,13 +16,13 @@ CFILES += ses_steps.c
 CFILES += ses_step_battery.c
 CFILES += ses_step_dc_input.c
 CFILES += ses_step_dc_diode.c
-CFILES += ses_step_dc_transistor.c
+CFILES += ses_step_dc_npn.c
+CFILES += ses_step_dc_pnp.c
 
 CFILES += ses_step_topo.c
 
 CFILES += ses_step_jr.c
 CFILES += ses_step_va_diode.c
-CFILES += ses_step_va_transistor.c
 CFILES += ses_step_va.c
 CFILES += ses_step_status.c
 
diff --git a/examples/pnp_oscillator.cpk b/examples/pnp_oscillator.cpk
new file mode 100644 (file)
index 0000000..62dc959
Binary files /dev/null and b/examples/pnp_oscillator.cpk differ
diff --git a/main.c b/main.c
index 1d0596dea6c37ba097ad31982b4127cde99afc73..c608d2a58d1d8c028e1c516a94cfb89550c54bf3 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, 60 * 1000 + 10501);
+               ses_steps_analyse(f, 1000, 1);
        }
 #endif
 
index 1f48b4cfd256374096f68a4d9ec0bbb75d1b9387..b955ef50c90e611d2de2741a3fda2a4ccb629044 100644 (file)
@@ -36,6 +36,9 @@ enum {
 #define SCF_EDA_V_NPN_ON    0.70
 #define SCF_EDA_V_NPN_OFF   0.61
 
+#define SCF_EDA_V_PNP_ON    SCF_EDA_V_NPN_ON
+#define SCF_EDA_V_PNP_OFF   SCF_EDA_V_NPN_OFF
+
 enum {
        SCF_EDA_Battery_NEG,
        SCF_EDA_Battery_POS,
@@ -63,10 +66,10 @@ enum {
 };
 
 enum {
-       SCF_EDA_PNP_B,
-       SCF_EDA_PNP_E,
-       SCF_EDA_PNP_C,
-       SCF_EDA_PNP_NB,
+       SCF_EDA_PNP_B  = SCF_EDA_NPN_B,
+       SCF_EDA_PNP_E  = SCF_EDA_NPN_E,
+       SCF_EDA_PNP_C  = SCF_EDA_NPN_C,
+       SCF_EDA_PNP_NB = SCF_EDA_NPN_NB,
 };
 
 typedef struct {
@@ -301,7 +304,7 @@ SCF_PACK_INFO_OBJS(ScfEboard, functions, ScfEfunction),
 SCF_PACK_END(ScfEboard)
 
 
-ScfEconn*   scf_econn__alloc();
+ScfEconn*      scf_econn__alloc();
 int            scf_econn__add_cid(ScfEconn* ec, uint64_t  cid);
 int            scf_econn__del_cid(ScfEconn* ec, uint64_t  cid);
 
index 1eda99c43ad0785d787e2cec72c70a9bae2a58b4..abdbf998544cbb77c69f33962f9d613b9d7324f0 100644 (file)
@@ -54,6 +54,7 @@ struct ses_info_s
        int            j;
        int            n_diodes;
        int            n_NPNs;
+       int            n_PNPs;
        int            n_capacitors;
 };
 
@@ -114,6 +115,7 @@ struct ses_path_s
        int            n_capacitors;
        int            n_diodes;
        int            n_NPNs;
+       int            n_PNPs;
        int            n_transistors;
        int            n_layers;
 
@@ -129,15 +131,11 @@ struct ses_edge_s
        int            vip_m;
        int            vip_n;
 
-       int            n_diodes;
-       int            n_NPNs;
-
        ses_node_t*    node0;
        ses_node_t*    node1;
 
-       ses_edge_t*    npn_b;
-       int            npn_index;
-       double         npn_hfe;
+       ses_edge_t*    edge_b;
+       double         hfe;
 
        double         cv;
        double         r;
@@ -147,6 +145,7 @@ struct ses_edge_s
        double         a0;
 
        uint8_t        vflag:1;
+       uint8_t        bflag:1;
 };
 
 struct ses_node_s
index 0d4212e544f6e3a5dfe3bb3a0155b1b8a2d9c9a7..b4aaeb71b72880f8bd1b0ab89edbf65784b8a96d 100644 (file)
@@ -668,7 +668,7 @@ static int __ses_layout_lines4(ScfEfunction* f)
 
        p = base->pins->data[j - 1];
        n = __ses_find_eline_index(f, p->lid);
-       SCF_XCHG(f->elines[n], f->elines[j / 2 + 1]);
+       SCF_XCHG(f->elines[n], f->elines[j / 2]);
 
        for (i = 0; i < f->n_elines; i++)
                f->elines[i]->vflag = 0;
@@ -1540,13 +1540,17 @@ static void __ses_xchg_ce(ScfEfunction* f, int d)
        ScfEpin*       pe;
        ScfEpin*       pc;
 
-       size_t i;
-       size_t j;
+       int64_t i;
+       int64_t j;
+
+       assert(SCF_EDA_NPN_B == SCF_EDA_PNP_B);
+       assert(SCF_EDA_NPN_C == SCF_EDA_PNP_C);
+       assert(SCF_EDA_NPN_E == SCF_EDA_PNP_E);
 
        for (i = 0; i < f->n_components; i++) {
                c  =        f->components[i];
 
-               if (SCF_EDA_NPN != c->type)
+               if (SCF_EDA_NPN != c->type && SCF_EDA_PNP != c->type)
                        continue;
 
                j = 0;
index 8324cef06c38f405769fdee2ace188d351f8037a..0da595c32f108bec11d1e5e77d686f06a67d3161 100644 (file)
@@ -77,16 +77,16 @@ ses_edge_t* ses_nodes_find_edge_by_pin(scf_vector_t* nodes, ScfEpin* vip)
        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* n_NPNs)
+int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* nodes, int* n_edges)
 {
        ses_path_t*    child;
        ses_path_t*    bridge;
        ses_path_t*    conn;
 
-       ses_edge_t*    edge  = NULL;
-       ses_edge_t*    npn_c = NULL;
-       ses_node_t*    prev  = NULL;
-       ses_node_t*    node  = NULL;
+       ses_edge_t*    edge   = NULL;
+       ses_edge_t*    edge_c = NULL;
+       ses_node_t*    prev   = NULL;
+       ses_node_t*    node   = NULL;
 
        ScfEcomponent* c;
        ScfEpin*       p;
@@ -107,7 +107,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, n_NPNs);
+                       ret = __ses_nodes_path2(f, conn, 0, conn->pins->size - 1, nodes, n_edges);
                        if (ret < 0)
                                return ret;
                }
@@ -120,7 +120,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, n_NPNs);
+                       ret = __ses_nodes_path2(f, child, 0, child->pins->size - 1, nodes, n_edges);
                        if (ret < 0)
                                return ret;
                }
@@ -133,7 +133,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, n_NPNs);
+                       ret = __ses_nodes_path2(f, bridge, 0, bridge->pins->size - 1, nodes, n_edges);
                        if (ret < 0)
                                return ret;
                }
@@ -141,31 +141,38 @@ 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 n = 0;
+       int bflag = 0;
        for (i = vip_n - 1; i > vip_m; i -= 2) {
 
                p = path->pins->data[i];
                c = f->components[p->cid];
 
-               if (SCF_EDA_NPN == c->type) {
+               switch (c->type) {
 
-                       if (SCF_EDA_NPN_B == p->id) {
-                               npn_c = ses_nodes_find_edge_by_pin(nodes, c->pins[SCF_EDA_NPN_C]);
-                               if (!npn_c) {
-                                       scf_loge("\n");
-                                       return -EINVAL;
-                               }
+                       case SCF_EDA_PNP:
+                               p = path->pins->data[i + 1];
+                       case SCF_EDA_NPN:
 
-                               n++;
-                               npn_c->npn_hfe = c->pins[SCF_EDA_NPN_C]->hfe;
-                       }
+                               if (SCF_EDA_NPN_B == p->id) {
+                                       edge_c = ses_nodes_find_edge_by_pin(nodes, c->pins[SCF_EDA_NPN_C]);
+                                       if (!edge_c) {
+                                               scf_loge("\n");
+                                               return -EINVAL;
+                                       }
 
-                       if (!node) {
-                               node = ses_node_alloc();
-                               if (!node)
-                                       return -ENOMEM;
-                       }
-               }
+                                       bflag = 1;
+                                       edge_c->hfe = c->pins[SCF_EDA_NPN_C]->hfe;
+                               }
+
+                               if (!node) {
+                                       node = ses_node_alloc();
+                                       if (!node)
+                                               return -ENOMEM;
+                               }
+                               break;
+                       default:
+                               break;
+               };
 
                if (path->childs) {
                        for (k = 0; k < path->childs->size; k++) {
@@ -248,8 +255,8 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                }
                edge->index = (*n_edges)++;
                edge->node1 = node;
-               edge->n_NPNs= n;
-               n = 0;
+               edge->bflag = bflag;
+               bflag = 0;
 
                if (prev) {
                        ret = ses_node_ref_edge(prev, edge);
@@ -260,10 +267,9 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                        edge->node0 = prev;
                }
 
-               if (npn_c) {
-                       npn_c->npn_b     = edge;
-                       npn_c->npn_index = (*n_NPNs)++;
-                       npn_c = NULL;
+               if (edge_c) {
+                       edge_c->edge_b = edge;
+                       edge_c = NULL;
                }
 
                ret = scf_vector_add(nodes, node);
@@ -300,13 +306,12 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                        return ret;
                edge->index = (*n_edges)++;
                edge->node0 = prev;
-               edge->n_NPNs= n;
-               n = 0;
+               edge->bflag = bflag;
+               bflag = 0;
 
-               if (npn_c) {
-                       npn_c->npn_b     = edge;
-                       npn_c->npn_index = (*n_NPNs)++;
-                       npn_c = NULL;
+               if (edge_c) {
+                       edge_c->edge_b = edge;
+                       edge_c = NULL;
                }
        }
 
@@ -319,21 +324,20 @@ int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, sc
        if (!vec)
                return -ENOMEM;
 
+       ses_node_t* node;
+       ses_edge_t* edge;
+
        int n_edges = 0;
-       int n_NPNs  = 0;
+       int i;
+       int j;
 
-       int ret = __ses_nodes_path2(f, path, vip_m, vip_n, vec, &n_edges, &n_NPNs);
+       int ret = __ses_nodes_path2(f, path, vip_m, vip_n, vec, &n_edges);
        if (ret < 0) {
                scf_vector_clear(vec, (void (*)(void*) )ses_node_free);
                scf_vector_free(vec);
                return ret;
        }
 
-       ses_node_t* node;
-       ses_edge_t* edge;
-       int i;
-       int j;
-
        for (i = 0; i < vec->size; ) {
                node      = vec->data[i];
 
@@ -410,7 +414,7 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
                                m++;
                                edge->vflag = 1;
 
-                               if (edge->npn_b)
+                               if (edge->edge_b)
                                        t++;
                        }
                }
@@ -497,16 +501,9 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
 
                        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->n_NPNs > 0) {
-                               b[n + edge->index] = cv + edge->n_NPNs * SCF_EDA_V_NPN_ON;
-#if 0
-                       } else if (edge->npn_b) {
-                               A[(n + edge->index) * N + n + edge->index]        = 1;
-                               A[(n + edge->index) * N + n + edge->npn_b->index] = -edge->npn_hfe;
-                               b[n + edge->index] = 0;
-                               continue;
-#endif
-                       } else {
+                       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;
                        }
@@ -581,11 +578,11 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
                        for (j = 0; j < node->edges->size; j++) {
                                edge      = node->edges->data[j];
 
-                               if (edge->npn_b) {
+                               if (edge->edge_b) {
                                        double Ic = X[n + edge->index];
-                                       double Ib = X[n + edge->npn_b->index];
+                                       double Ib = X[n + edge->edge_b->index];
 
-                                       double dI = Ib * edge->npn_hfe - Ic;
+                                       double dI = Ib * edge->hfe - Ic;
 
                                        if (dI < -1e-10) {
                                                scf_logi("Ic: %lg, Ib: %lg, dI: %lg\n", Ic, Ib, dI);
@@ -594,9 +591,9 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
                                                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->npn_b->index] = edge->npn_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++;
                                        }
@@ -649,6 +646,14 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
                                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);
+
+                               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;
                        }
 
                        ret = __ses_path_va_branch(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ns, count);
index f2628e6b1bafe1d9c1dfd10a773187ba61dac270..b52dbf38e08ccc3952762a70d93c9b8d09c71b19 100644 (file)
@@ -112,15 +112,15 @@ void ses_path_print(ses_path_t* path)
        if (!path)
                return;
 
-       ses_path_t* path2;
+       ses_path_t* child;
        ScfEpin*    p;
 
        int i;
        int j;
 
        if (!path->parent)
-               printf("\033[31mpath  : %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, \033[0m",
-                               path->index, path->n_diodes, path->n_NPNs, path->n_capacitors, path->infos->size);
+               printf("\033[31mpath  : %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, \033[0m",
+                               path->index, path->n_diodes, path->n_NPNs, path->n_PNPs, path->n_capacitors);
 
        for (i = 0; i < path->pins->size; i++) {
                p  =        path->pins->data[i];
@@ -131,37 +131,37 @@ void ses_path_print(ses_path_t* path)
 
        if (path->connections) {
                for (i = 0; i < path->connections->size; i++) {
-                       path2     = path->connections->data[i];
+                       child     = path->connections->data[i];
 
-                       if (path2->parent == path) {
-                               printf("\033[34mconnection: %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, parent: %d, \033[0m",
-                                               path2->index, path2->n_diodes, path2->n_NPNs, path2->n_capacitors, path2->infos->size, path->index);
+                       if (child->parent == path) {
+                               printf("\033[34mconnection: %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, parent: %d, \033[0m",
+                                               child->index, child->n_diodes, child->n_NPNs, child->n_PNPs, child->n_capacitors, path->index);
 
-                               ses_path_print(path2);
+                               ses_path_print(child);
                        } else
-                               printf("connection: %d\n", path2->index);
+                               printf("\033[34mconnection: %d\033[0m\n", child->index);
                }
        }
 
        if (path->childs) {
                for (i = 0; i < path->childs->size; i++) {
-                       path2     = path->childs->data[i];
+                       child     = path->childs->data[i];
 
-                       printf("\033[32mchild : %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, parent: %d, \033[0m",
-                                       path2->index, path2->n_diodes, path2->n_NPNs, path2->n_capacitors, path2->infos->size, path->index);
+                       printf("\033[32mchild : %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, parent: %d, \033[0m",
+                                       child->index, child->n_diodes, child->n_NPNs, child->n_PNPs, child->n_capacitors, path->index);
 
-                       ses_path_print(path2);
+                       ses_path_print(child);
                }
        }
 
        if (path->bridges) {
                for (i = 0; i < path->bridges->size; i++) {
-                       path2     = path->bridges->data[i];
+                       child     = path->bridges->data[i];
 
-                       printf("\033[33mbridge: %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, parent: %d, \033[0m",
-                                       path2->index, path2->n_diodes, path2->n_NPNs, path2->n_capacitors, path2->infos->size, path->index);
+                       printf("\033[33mbridge: %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, parent: %d, \033[0m",
+                                       child->index, child->n_diodes, child->n_NPNs, child->n_PNPs, child->n_capacitors, path->index);
 
-                       ses_path_print(path2);
+                       ses_path_print(child);
                }
        }
 }
similarity index 92%
rename from ses_step_dc_transistor.c
rename to ses_step_dc_npn.c
index e13c1d0f7556899cc477fcbe6e63ce8501ea9dda..147bf2e264d3fd1753c44326dc8f2eabf1a1afe6 100644 (file)
@@ -1,6 +1,6 @@
 #include"ses_core.h"
 
-static int _dc_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
+static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
 {
        ScfEcomponent*   c;
        ScfEcomponent*   B;
@@ -111,9 +111,9 @@ static int _dc_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, se
        return 0;
 }
 
-ses_step_t   ses_step_dc_transistor =
+ses_step_t   ses_step_dc_npn =
 {
-       .name    = "dc_transistor",
+       .name    = "dc_npn",
 
-       .handler = _dc_transistor_handler,
+       .handler = _dc_npn_handler,
 };
diff --git a/ses_step_dc_pnp.c b/ses_step_dc_pnp.c
new file mode 100644 (file)
index 0000000..bbc7ef8
--- /dev/null
@@ -0,0 +1,119 @@
+#include"ses_core.h"
+
+static int _dc_pnp_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
+{
+       ScfEcomponent*   c;
+       ScfEcomponent*   B;
+       ScfEline*        lb;
+       ScfEline*        le;
+       ScfEpin*         pb;
+       ScfEpin*         pc;
+       ScfEpin*         pe;
+       ScfEpin*         Bp;
+       ScfEpin*         Bn;
+
+       size_t i;
+       size_t j;
+       size_t k;
+
+       B  = f->components[0];
+       Bp = B->pins[SCF_EDA_Battery_POS];
+       Bn = B->pins[SCF_EDA_Battery_NEG];
+
+       for (i = 0; i < f->n_components; i++) {
+               c  =        f->components[i];
+
+               if (SCF_EDA_PNP != c->type)
+                       continue;
+
+               pb = c->pins[SCF_EDA_PNP_B];
+               pc = c->pins[SCF_EDA_PNP_C];
+               pe = c->pins[SCF_EDA_PNP_E];
+
+               lb = f->elines[pb->lid];
+               le = f->elines[pe->lid];
+
+               if (pe->lid == Bp->lid && pb->lid == Bn->lid) {
+                       scf_loge("PNP c%ld, short connected\n", c->id);
+                       return -EINVAL;
+               }
+
+               if (__ses_path_pos(f, lb) && !__ses_path_neg(f, lb)) {
+                       c->status = SCF_EDA_Status_OFF;
+
+                       scf_loge("PNP c%ld, status: %d\n", c->id, c->status);
+                       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_PNP_OFF);
+
+               if (lb->v < SCF_EDA_V_MIN) {
+
+                       if (le->v < SCF_EDA_V_MIN)
+                               continue;
+
+                       pe->v = le->v;
+                       pb->v = le->v - SCF_EDA_V_PNP_ON;
+                       lb->v = pb->v;
+
+                       if (le->v == Bp->v)
+                               lb->vconst = 1;
+
+                       if (pb->v < Bn->v) {
+                               if (!c->lock)
+                                       c->status = SCF_EDA_Status_OFF;
+                       } else
+                               c->status = SCF_EDA_Status_ON;
+
+               } else if (le->v < SCF_EDA_V_MIN) {
+
+                       pb->v = lb->v;
+                       pe->v = lb->v + SCF_EDA_V_PNP_ON;
+                       le->v = pe->v;
+
+                       if (lb->v == Bn->v)
+                               le->vconst = 1;
+
+                       if (pe->v > Bp->v) {
+                               if (!c->lock)
+                                       c->status = SCF_EDA_Status_OFF;
+                       } else
+                               c->status = SCF_EDA_Status_ON;
+
+               } else if (lb->v <= le->v - SCF_EDA_V_PNP_OFF) {
+
+                       if (le->v == Bp->v)
+                               lb->vconst = 1;
+                       else if (lb->v == Bn->v)
+                               le->vconst = 1;
+
+                       lb->v = le->v - SCF_EDA_V_PNP_ON;
+                       pb->v = lb->v;
+                       pe->v = le->v;
+
+                       if (pb->v < Bn->v) {
+                               if (!c->lock)
+                                       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;
+               }
+
+               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);
+       }
+
+       return 0;
+}
+
+ses_step_t   ses_step_dc_pnp =
+{
+       .name    = "dc_pnp",
+
+       .handler = _dc_pnp_handler,
+};
index cd13d0dbd9d426771c746a3a4ac988a82c74177c..f5bb2479d2f0994921242717f8ff40a4fa4bdda2 100644 (file)
@@ -14,7 +14,7 @@ static int _output_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t
        for (i = 0; i < f->n_elines; i++) {
                el =        f->elines[i];
 
-               printf("e%ld->vconst: %d\n", el->id, el->vconst);
+               scf_logd("e%ld->vconst: %d\n", el->id, el->vconst);
 
                if (SCF_EDA_PIN_OUT & el->flags)
                        scf_logw("out el: %ld, V: %lg\n", el->id, el->v);
index 2b1bdd49be189de4df4db3b20af462da0efbf521..471ed979e4adb28c23835bf36991463d33135d47 100644 (file)
@@ -1,7 +1,7 @@
 #include<cairo/cairo.h>
 #include"ses_core.h"
 
-#define SHOW_BITS 1000000.0
+#define SHOW_BITS 10000.0
 
 static void ses_text_a(cairo_t* cr, int x, int y, double a)
 {
@@ -330,6 +330,67 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
                                        cairo_stroke(cr);
                                }
 
+                               cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+                               ses_text_a(cr, c->x, (pb->y + c->y) / 2, pb->a);
+                               ses_text_a(cr, c->x,  c->y,              pc->a);
+                               ses_text_a(cr, c->x, (pe->y + c->y) / 2, pe->a);
+                               cairo_stroke(cr);
+                               break;
+
+                       case SCF_EDA_PNP:
+                               pb = c->pins[SCF_EDA_PNP_B];
+                               pc = c->pins[SCF_EDA_PNP_C];
+                               pe = c->pins[SCF_EDA_PNP_E];
+
+                               vertical(&dx0, &dy0, c->x - pb->x, c->y - pb->y,  8);
+                               forward (&dx3, &dy3, c->x - pb->x, c->y - pb->y,  8);
+
+                               cairo_arc(cr, c->x - dx3 / 2, c->y - dy3 / 2, 12, 0, 2 * M_PI);
+
+                               cairo_move_to    (cr,  pb->x,       pb->y);
+                               cairo_line_to    (cr,  c->x - dx3,  c->y - dy3);
+                               cairo_rel_move_to(cr,  dx0,         dy0);
+                               cairo_rel_line_to(cr, -dx0 * 2,    -dy0 * 2);
+                               cairo_stroke(cr);
+
+                               if ((c->x + dx3 + dx0 > c->x + dx3 - dx0 && pe->x > pc->x)
+                                               || (c->x + dx3 + dx0 < c->x + dx3 - dx0 && pe->x < pc->x)) {
+
+                                       cairo_move_to(cr, c->x - dx3,       c->y - dy3);
+                                       cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0);
+                                       cairo_line_to(cr, pe->x, pe->y);
+
+                                       vertical(&dx1, &dy1, dx3 * 2 + dx0, dy3 * 2 + dy0, 4);
+                                       forward (&dx4, &dy4, dx3 * 2 + dx0, dy3 * 2 + dy0, 12);
+
+                                       cairo_move_to(cr, c->x - dx3 + dx4 + dx1,  c->y - dy3 + dy4 + dy1);
+                                       cairo_line_to(cr, c->x - dx3,              c->y - dy3);
+                                       cairo_line_to(cr, c->x - dx3 + dx4 - dx1,  c->y - dy3 + dy4 - dy1);
+                                       cairo_stroke(cr);
+
+                                       cairo_move_to(cr, c->x - dx3,        c->y - dy3);
+                                       cairo_line_to(cr, c->x + dx3 - dx0,  c->y + dy3 - dy0);
+                                       cairo_line_to(cr, pc->x, pc->y);
+                                       cairo_stroke(cr);
+                               } else {
+                                       cairo_move_to(cr, c->x - dx3,       c->y - dy3);
+                                       cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0);
+                                       cairo_line_to(cr, pc->x, pc->y);
+                                       cairo_stroke(cr);
+
+                                       cairo_move_to(cr, c->x - dx3,        c->y - dy3);
+                                       cairo_line_to(cr, c->x + dx3 - dx0,  c->y + dy3 - dy0);
+                                       cairo_line_to(cr, pe->x, pe->y);
+
+                                       vertical(&dx1, &dy1, dx3 * 2 - dx0, dy3 * 2 - dy0, 4);
+                                       forward (&dx4, &dy4, dx3 * 2 - dx0, dy3 * 2 - dy0, 12);
+
+                                       cairo_move_to(cr, c->x - dx3 + dx4 + dx1,  c->y - dy3 + dy4 + dy1);
+                                       cairo_line_to(cr, c->x - dx3,              c->y - dy3);
+                                       cairo_line_to(cr, c->x - dx3 + dx4 - dx1,  c->y - dy3 + dy4 - dy1);
+                                       cairo_stroke(cr);
+                               }
+
                                cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
                                ses_text_a(cr, c->x, (pb->y + c->y) / 2, pb->a);
                                ses_text_a(cr, c->x,  c->y,              pc->a);
@@ -449,7 +510,7 @@ int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t b
                                        n = snprintf(text, sizeof(text) - 1, "%lgmV", (int64_t)(el->v * 1000.0 * SHOW_BITS) / SHOW_BITS);
                                else
                                        n = snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(el->v * 1000000.0 * SHOW_BITS) / SHOW_BITS);
-
+#if 0
                                // A of line
                                if (el->aout > 1e-1 || el->aout < -1e-1)
                                        n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgA", (int64_t)(el->aout * SHOW_BITS) / SHOW_BITS);
@@ -466,7 +527,7 @@ int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t b
                                        n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgmA", (int64_t)(el->ain * 1000.0 * SHOW_BITS) / SHOW_BITS);
                                else
                                        n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lguA", (int64_t)(el->ain * 1000000.0 * SHOW_BITS) / SHOW_BITS);
-
+#endif
                                int cx = INT_MAX;
                                int cy = l->y0;
 
@@ -528,13 +589,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 1
+#if 0
        if (count < 60 * 1000)
                return 0;
 #endif
 
        if (count % 10 == 0) {
-#if 1
+#if 0
                static FILE* fp = NULL;
                if (!fp)
                        fp = fopen("v.txt", "w");
@@ -542,7 +603,7 @@ static int _simplify_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx
                if (fp)
                        fprintf(fp, "%ld, %lg\n", i, f->elines[4]->v);
 #endif
-//             ses_simplify_draw(f, file, f->x, f->y, f->w, f->h, ns, count);
+               ses_simplify_draw(f, file, f->x, f->y, f->w, f->h, ns, count);
                i++;
        }
 
index 01ee0f917d50c509bdb0df9d71e0a1f832e264fa..213775d37afe1858fb8d30b84a4d9aa0a2d3c4a5 100644 (file)
@@ -32,16 +32,11 @@ int __ses_path_status(ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vec
 
        __ses_path_jr(f, bridge);
 
-       if (bridge->n_diodes + bridge->n_NPNs > 0) {
+       if (bridge->n_diodes + bridge->n_NPNs + bridge->n_PNPs > 0) {
                __ses_path_va_diode(f, bridge);
                __ses_path_jr      (f, bridge);
        }
 
-       if (bridge->n_transistors > 0) {
-               __ses_path_va_transistor(f, bridge);
-               __ses_path_jr           (f, bridge);
-       }
-
        int ret = __ses_path_va(f, bridge, &__changed, ns, count);
        if (ret < 0)
                return ret;
index 9bf978a878a4ad9cdc89c7c36564ceea74a8cb4c..44da2bf9ec72f731bc766e38d6cd783382a3ccda 100644 (file)
@@ -1,16 +1,31 @@
 #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 __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __paths, ses_path_t** ppath)
 {
        ScfEcomponent*   c;
        ScfEline*        el;
        ScfEpin*         np;
        ScfEpin*         p;
-       ScfEpin*         p2;
 
        size_t i;
        size_t j;
-       size_t k;
 
        if (SCF_EDA_Status_OFF == rc->status)
                return SCF_EDA_Status_OFF;
@@ -21,6 +36,9 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
        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)
@@ -30,7 +48,8 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
        if (scf_vector_add((*ppath)->pins, rp) < 0)
                return -ENOMEM;
 
-       if (SCF_EDA_NPN != rc->type || SCF_EDA_NPN_E != rp->id)
+       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);
@@ -45,6 +64,8 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
 
                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%ld_p%ld, l%ld, vflag: %d, pflag: %d\n", np->cid, np->id, np->lid, np->vflag, np->pflag);
 
@@ -63,22 +84,24 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
                                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)
+               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) {
 
-                       if (scf_vector_add(__paths, *ppath) < 0)
-                               return -ENOMEM;
-
-                       for (j = 0; j < (*ppath)->pins->size; j++) {
-                               p2        = (*ppath)->pins->data[j];
-                               p2->pflag = 1;
-                               p2->path  = (uintptr_t)*ppath;
-                       }
+                       ret = __ses_dfs_add_path(__paths, *ppath);
+                       if (ret < 0)
+                               return ret;
 
                        *ppath = NULL;
                        return 0;
@@ -93,17 +116,13 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
 
                        if (p->pflag) {
                                if (p != np && *ppath) {
-                                       scf_logd("branch: c%ld_p%ld, l%ld\n", c->id, p->id, el->id);
+                                       scf_logd("branch: c%ld_p%ld, l%ld\n\n", c->id, p->id, el->id);
 
                                        if ((*ppath)->pins->size > 0) {
-                                               if (scf_vector_add(__paths, *ppath) < 0)
-                                                       return -ENOMEM;
-
-                                               for (k = 0; k < (*ppath)->pins->size; k++) {
-                                                       p2        = (*ppath)->pins->data[k];
-                                                       p2->pflag = 1;
-                                                       p2->path  = (uintptr_t)*ppath;
-                                               }
+
+                                               ret = __ses_dfs_add_path(__paths, *ppath);
+                                               if (ret < 0)
+                                                       return ret;
                                        } else
                                                ses_path_free(*ppath);
 
@@ -117,28 +136,38 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
 
                        if (SCF_EDA_Capacitor == rc->type && SCF_EDA_Capacitor != c->type) {
                                if (*ppath) {
-                                       if (scf_vector_add(__paths, *ppath) < 0)
-                                               return -ENOMEM;
+                                       if ((*ppath)->pins->size > 0) {
 
-                                       for (j = 0; j < (*ppath)->pins->size; j++) {
-                                               p2        = (*ppath)->pins->data[j];
-                                               p2->pflag = 1;
-                                               p2->path  = (uintptr_t)*ppath;
-                                       }
+                                               ret = __ses_dfs_add_path(__paths, *ppath);
+                                               if (ret < 0)
+                                                       return ret;
+                                       } else
+                                               ses_path_free(*ppath);
 
                                        *ppath = NULL;
                                }
                        }
 
-                       if (SCF_EDA_NPN != c->type || SCF_EDA_NPN_E != p->id)
+                       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;
 
+                       ses_path_t* tmp = NULL;
+
+                       if (SCF_EDA_Capacitor != rc->type && SCF_EDA_Capacitor == c->type) {
+                               tmp    = *ppath;
+                               *ppath = NULL;
+                       }
+
                        ret = __ses_dfs_path(f, c, p, __paths, ppath);
                        if (ret < 0)
                                return ret;
 
                        if (SCF_EDA_Path_OFF == ret)
                                p->vflag = 0;
+
+                       if (tmp)
+                               *ppath = tmp;
                }
 
                if (*ppath) {
@@ -159,10 +188,10 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
                if (SCF_EDA_Path_OFF == ret) {
                        rp->vflag = 0;
 
-                       scf_logd("off: c%ld_p%ld, l%ld\n", rp->cid, rp->id, rp->lid);
+                       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", rp->cid, rp->id, rp->lid);
+                       scf_logd("off: c%ld_p%ld, l%ld\n\n", rp->cid, rp->id, rp->lid);
        }
 
        return ret;
@@ -187,6 +216,25 @@ static int ses_pin_to_npn(const ScfEfunction* f, const ScfEpin* vip, int pid)
        return 0;
 }
 
+static int ses_pin_to_pnp(const ScfEfunction* f, const ScfEpin* vip, int pid)
+{
+       const ScfEcomponent* c;
+       const ScfEline*      el = f->elines[vip->lid];
+       const ScfEpin*       p;
+
+       int i;
+       for (i = 0; i < el->n_pins; i += 2) {
+
+               c  = f->components[el->pins[i]];
+               p  = c->pins      [el->pins[i + 1]];
+
+               if (p != vip && SCF_EDA_PNP == c->type && pid == p->id)
+                       return 1;
+       }
+
+       return 0;
+}
+
 static int ses_path_to_npn(const ScfEfunction* f, const ses_path_t* path, int pid)
 {
        const ScfEpin* p0 = path->pins->data[0];
@@ -195,7 +243,6 @@ 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_child_cmp(const void* v0, const void* v1)
 {
        const ses_path_t* p0 = *(const ses_path_t**)v0;
@@ -279,28 +326,32 @@ static int __topo_path_bridges(ScfEfunction* f, ses_path_t* path)
                        c0 = f->components[p0->cid];
                        c1 = f->components[p1->cid];
 
-                       if (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_C == p0->id)
+                       if ((SCF_EDA_NPN == c0->type && SCF_EDA_NPN_C == p0->id)
+                        || (SCF_EDA_PNP == c0->type && SCF_EDA_PNP_C == p0->id))
                                goto bridge_sp1;
 
-                       if (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_C == p1->id)
+                       if ((SCF_EDA_NPN == c1->type && SCF_EDA_NPN_C == p1->id)
+                        || (SCF_EDA_PNP == c1->type && SCF_EDA_PNP_C == p1->id))
                                goto bridge_sp0;
 
                        if ((SCF_EDA_Diode == c0->type && SCF_EDA_Diode_POS == p0->id)
-                        || (SCF_EDA_NPN   == c0->type && SCF_EDA_NPN_B     == p0->id))
+                        || (SCF_EDA_NPN   == c0->type && SCF_EDA_NPN_B     == p0->id)
+                        || (SCF_EDA_PNP   == c0->type && SCF_EDA_PNP_B     == p0->id))
                                goto bridge_sp1;
 
                        if ((SCF_EDA_Diode == c1->type && SCF_EDA_Diode_POS == p1->id)
-                        || (SCF_EDA_NPN   == c1->type && SCF_EDA_NPN_B     == p1->id))
+                        || (SCF_EDA_NPN   == c1->type && SCF_EDA_NPN_B     == p1->id)
+                        || (SCF_EDA_PNP   == c1->type && SCF_EDA_PNP_B     == p1->id))
                                goto bridge_sp0;
 
-                       if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_B))
+                       if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_B) || ses_pin_to_pnp(f, p0, SCF_EDA_PNP_B))
                                goto bridge_sp1;
-                       if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_B))
+                       if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_B) || ses_pin_to_pnp(f, p1, SCF_EDA_PNP_B))
                                goto bridge_sp0;
 
-                       if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_C))
+                       if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_C) || ses_pin_to_pnp(f, p0, SCF_EDA_PNP_C))
                                goto bridge_sp1;
-                       if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_C))
+                       if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_C) || ses_pin_to_pnp(f, p1, SCF_EDA_PNP_C))
                                goto bridge_sp0;
 
                        // negative pin of path
@@ -313,25 +364,27 @@ static int __topo_path_bridges(ScfEfunction* f, ses_path_t* path)
                        if (SCF_EDA_PIN_IN & p1->flags)
                                goto bridge_sp0;
 
-                       if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_B))
+                       if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_B) || ses_pin_to_pnp(f, p0, SCF_EDA_PNP_B))
                                goto bridge_sp1;
-                       if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_B))
+                       if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_B) || ses_pin_to_pnp(f, p1, SCF_EDA_PNP_B))
                                goto bridge_sp0;
 
-                       if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_C))
+                       if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_C) || ses_pin_to_pnp(f, p0, SCF_EDA_PNP_C))
                                goto bridge_sp1;
-                       if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_C))
+                       if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_C) || ses_pin_to_pnp(f, p1, SCF_EDA_PNP_C))
                                goto bridge_sp0;
 
                        c0 = f->components[p0->cid];
                        c1 = f->components[p1->cid];
 
                        if ((SCF_EDA_Diode == c0->type && SCF_EDA_Diode_NEG == p0->id)
-                        || (SCF_EDA_NPN   == c0->type && SCF_EDA_NPN_E     == p0->id))
+                        || (SCF_EDA_NPN   == c0->type && SCF_EDA_NPN_E     == p0->id)
+                        || (SCF_EDA_PNP   == c0->type && SCF_EDA_PNP_E     == p0->id))
                                goto bridge_sp1;
 
                        if ((SCF_EDA_Diode == c1->type && SCF_EDA_Diode_NEG == p1->id)
-                        || (SCF_EDA_NPN   == c1->type && SCF_EDA_NPN_E     == p1->id))
+                        || (SCF_EDA_NPN   == c1->type && SCF_EDA_NPN_E     == p1->id)
+                        || (SCF_EDA_PNP   == c1->type && SCF_EDA_PNP_E     == p1->id))
                                goto bridge_sp0;
 
 bridge_sp1:
@@ -767,6 +820,7 @@ static int __topo_path_key_infos(ScfEfunction* f, ses_path_t* path)
        scf_vector_clear(path->infos, ( void (*)(void*) )free);
        path->n_diodes = 0;
        path->n_NPNs   = 0;
+       path->n_PNPs   = 0;
 
        for (i = 0; i < path->pins->size; i++) {
                p  =        path->pins->data[i];
@@ -820,6 +874,39 @@ static int __topo_path_key_infos(ScfEfunction* f, ses_path_t* path)
                        }
                }
 
+               if (SCF_EDA_PNP == c->type) {
+
+                       if (SCF_EDA_PNP_B == p->id) {
+                               if (!info) {
+                                       info = calloc(1, sizeof(ses_info_t));
+                                       if (!info)
+                                               return -ENOMEM;
+
+                                       info->i = i - 1;
+                               }
+
+                               info->n_PNPs++;
+                               path->n_PNPs++;
+
+                               if (__ses_branch_exist(path, i)) {
+                                       j = i;
+                                       goto _add;
+                               }
+
+                       } else if (SCF_EDA_PNP_C == p->id) {
+                               if (info) {
+                                       if (info->n_diodes + info->n_NPNs + info->n_PNPs > 0) {
+                                               j = i - 2;
+                                               goto _add;
+                                       }
+
+                                       free(info);
+                                       info = NULL;
+                               }
+                       }
+                       continue;
+               }
+
                j = i - 1;
 _add:
                if (info) {
@@ -996,6 +1083,7 @@ static void _topo_key_components(ScfEfunction* f, ses_path_t* path)
        int i;
 
        path->n_NPNs   = 0;
+       path->n_PNPs   = 0;
        path->n_diodes = 0;
        path->n_capacitors = 0;
 
@@ -1017,6 +1105,14 @@ static void _topo_key_components(ScfEfunction* f, ses_path_t* path)
                        else if (SCF_EDA_NPN_C == p->id)
                                path->n_transistors++;
 
+               } else if (SCF_EDA_PNP == c->type) {
+
+                       if (SCF_EDA_PNP_B == p->id)
+                               path->n_PNPs++;
+
+                       else if (SCF_EDA_PNP_C == p->id)
+                               path->n_transistors++;
+
                } else if (SCF_EDA_Capacitor == c->type) {
 
                        if (0 == p->id)
@@ -1403,21 +1499,7 @@ static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t*
        ret = _topo_bridge_connections(f, ctx->paths);
        if (ret < 0)
                return ret;
-#if 1
-//     if (count > 30000) {
-               R = f->components[10];
-
-               double w0 = 2 * 3.1415926 * 100;
-               double w1 = 2 * 3.1415926 * 1000;
-               double w2 = 2 * 3.1415926 * 5000;
-               double r0 = sin(w0 * ns * (count - 30000) / 1e9);
-               double r1 = sin(w1 * ns * (count - 30000) / 1e9);
-               double r2 = sin(w2 * ns * (count - 30000) / 1e9);
-               R->dr = 10.0 * (r0 + r1 + r2);
-
-               scf_logi("### c%ld->r: %lg, r: %lg\n", R->id, R->r, R->dr);
-//     }
-#endif
+
        int i;
        for (i = 0; i < ctx->paths->size; i++) {
                path      = ctx->paths->data[i];
index 1f20b3a8247273bd80195eeec705b97c25c9d478..cbdfb2c69ed62c1e6ae9dd29266effb0dfc7f1e3 100644 (file)
@@ -1,5 +1,88 @@
 #include"ses_core.h"
 
+int __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe, int vinit)
+{
+       ScfEcomponent* c2;
+       ScfEline*      el;
+       ScfEpin*       p2;
+
+       ScfEcomponent* B  = f->components[0];
+       ScfEpin*       Bp = B->pins[SCF_EDA_Battery_POS];
+       ScfEpin*       Bn = B->pins[SCF_EDA_Battery_NEG];
+
+       size_t i;
+       double Voff = SCF_EDA_Diode == c->type ? SCF_EDA_V_Diode_OFF : SCF_EDA_V_NPN_OFF;
+       double Von  = SCF_EDA_Diode == c->type ? SCF_EDA_V_Diode_ON  : SCF_EDA_V_NPN_ON;
+
+       pb->v = f->elines[pb->lid]->v;
+       pe->v = f->elines[pe->lid]->v;
+
+       if (pb->v < SCF_EDA_V_MIN) {
+
+               if (pe->v < SCF_EDA_V_MIN)
+                       return 0;
+
+               pb->v = pe->v + Von;
+
+               if (pb->v > Bp->v) {
+                       pb->v = Bp->v;
+                       if (!c->lock)
+                               c->status = SCF_EDA_Status_OFF;
+               } else
+                       c->status = SCF_EDA_Status_ON;
+               goto _changed;
+
+       } else if (pe->v < SCF_EDA_V_MIN) {
+               pe->v = pb->v - Von;
+
+               if (pe->v < Bn->v) {
+                       pe->v = Bn->v;
+                       if (!c->lock)
+                               c->status = SCF_EDA_Status_OFF;
+               } else
+                       c->status = SCF_EDA_Status_ON;
+               goto _changed;
+
+       } else if (pb->v - pe->v < Voff) {
+
+               if (c->status != SCF_EDA_Status_OFF) {
+                       if (!c->lock)
+                               c->status  = SCF_EDA_Status_OFF;
+                       goto _changed;
+               }
+       } else if (SCF_EDA_Status_ON != c->status) {
+               c->status  = SCF_EDA_Status_ON;
+               goto _changed;
+       }
+
+       return 0;
+
+_changed:
+       if (SCF_EDA_NPN == c->type || SCF_EDA_PNP == c->type) {
+
+               p2 = c->pins  [SCF_EDA_NPN_C];
+               el = f->elines[p2->lid];
+               el->vinit = vinit;
+
+               for (i = 0; i + 1 < el->n_pins; i += 2) {
+
+                       c2 = f->components[el->pins[i]];
+                       p2 = c->pins      [el->pins[i + 1]];
+
+                       if ((SCF_EDA_NPN == c2->type || SCF_EDA_PNP == c2->type) && SCF_EDA_NPN_B == p2->id) {
+                               c2->status  = SCF_EDA_Status_ON;
+                               c2->lock    = 1;
+
+                               scf_loge("\033[35mc%ld, status: %d\033[0m\n", c2->id, c2->status);
+                       }
+               }
+       }
+
+       scf_loge("\033[34mc%ld, status: %d, pb->v: %lg, pe->v: %lg, diff: %lg, Von: %lg, Voff: %lg\033[0m\n",
+                       c->id, c->status, pb->v, pe->v, pb->v - pe->v, Von, Voff);
+       return 1;
+}
+
 static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, int n,
                double* a, int* changed, int64_t ns, int64_t count)
 {
@@ -262,17 +345,18 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double
                        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",
                                        path->index, i, p->cid, p->id, p->v, dv, r, p->a, a, p->pr, el->id, el->v);
 
-                       if (SCF_EDA_Diode == c->type) {
+                       switch (c->type) {
+                               case SCF_EDA_Diode:
 
-                               if (SCF_EDA_Diode_NEG == p->id) {
+                                       assert(SCF_EDA_Diode_NEG == p->id);
                                        p2 = path->pins->data[i - 1];
 
                                        *changed += __ses_status_check(f, c, p2, p, 1);
-                               }
+                                       break;
 
-                       } else if (SCF_EDA_NPN == c->type) {
+                               case SCF_EDA_NPN:
 
-                               if (SCF_EDA_NPN_E == p->id) {
+                                       assert(SCF_EDA_PNP_E == p->id);
                                        p2 = path->pins->data[i - 1];
 
                                        if (SCF_EDA_NPN_B == p2->id) {
@@ -280,8 +364,23 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double
 
                                                c->pins[SCF_EDA_NPN_C]->aconst = 1;
                                        }
-                               }
-                       }
+                                       break;
+
+                               case SCF_EDA_PNP:
+
+                                       if (SCF_EDA_PNP_B == p->id) {
+                                               p2 = path->pins->data[i - 1];
+
+                                               assert(SCF_EDA_PNP_E == p2->id);
+
+                                               *changed += __ses_status_check(f, c, p2, p, 1);
+
+                                               c->pins[SCF_EDA_PNP_C]->aconst = 1;
+                                       }
+                                       break;
+                               default:
+                                       break;
+                       };
 
                        r  = 0;
                } else {
@@ -449,17 +548,18 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i
                        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",
                                        path->index, i, p->cid, p->id, p->v, dv, r, p->a, a, p->pr, el->id, el->v);
 
-                       if (SCF_EDA_Diode == c->type) {
+                       switch (c->type) {
+                               case SCF_EDA_Diode:
 
-                               if (SCF_EDA_Diode_NEG == p->id) {
+                                       assert(SCF_EDA_Diode_NEG == p->id);
                                        p2 = path->pins->data[i - 1];
 
                                        *changed += __ses_status_check(f, c, p2, p, 1);
-                               }
+                                       break;
 
-                       } else if (SCF_EDA_NPN == c->type) {
+                               case SCF_EDA_NPN:
 
-                               if (SCF_EDA_NPN_E == p->id) {
+                                       assert(SCF_EDA_PNP_E == p->id);
                                        p2 = path->pins->data[i - 1];
 
                                        if (SCF_EDA_NPN_B == p2->id) {
@@ -467,8 +567,23 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i
 
                                                c->pins[SCF_EDA_NPN_C]->aconst = 1;
                                        }
-                               }
-                       }
+                                       break;
+
+                               case SCF_EDA_PNP:
+
+                                       if (SCF_EDA_PNP_B == p->id) {
+                                               p2 = path->pins->data[i - 1];
+
+                                               assert(SCF_EDA_PNP_E == p2->id);
+
+                                               *changed += __ses_status_check(f, c, p2, p, 1);
+
+                                               c->pins[SCF_EDA_PNP_C]->aconst = 1;
+                                       }
+                                       break;
+                               default:
+                                       break;
+                       };
 
                        r  = 0;
                } else {
index be5f8f934ce7219e17ec16c73a3fb459d3ca7e3f..286b4666aa679befde9f6244c7a7360f1927d803 100644 (file)
@@ -44,6 +44,25 @@ void __ses_path_dr_forward(ScfEfunction* f, ses_path_t* path, int i, int j, doub
                        p1->a = (1 + p1->hfe) * a;
                        p1->aconst = 1;
 
+                       a = p1->a;
+
+               } else if (SCF_EDA_PNP == c->type && SCF_EDA_PNP_B == p->id) {
+
+                       ses_ui_r(&p->dr, NULL, SCF_EDA_V_PNP_ON, 0, a, 0);
+
+                       p->dr -= p->r;
+
+                       p1    = c->pins[SCF_EDA_PNP_C];
+                       p1->a = p1->hfe * a;
+                       p1->aconst = 1;
+
+                       scf_logw("c%ldp%ld, v: %lg, r: %lg, a: %lg, dr: %lg, c%ldp%ld->a: %lg\n",
+                                       p->cid, p->id, SCF_EDA_V_PNP_ON, p->r, a, p->dr, p1->cid, p1->id, p1->a);
+
+                       p1    = c->pins[SCF_EDA_PNP_E];
+                       p1->a = (1 + p1->hfe) * a;
+                       p1->aconst = 1;
+
                        a = p1->a;
                }
        }
@@ -97,7 +116,7 @@ void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double
                cp1->sr = child->sr;
                cp1->pr = child->pr;
 
-               if (child->n_diodes + child->n_NPNs > 0) {
+               if (child->n_diodes + child->n_NPNs + child->n_PNPs > 0) {
 
                        int ret = __ses_path_va_diode(f, child);
                        if (ret < 0)
@@ -119,7 +138,7 @@ void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double
 
                cp0->a = ca;
 
-               if (child->n_diodes + child->n_NPNs > 0)
+               if (child->n_diodes + child->n_NPNs + child->n_PNPs > 0)
                        __ses_path_dr_forward(f, child, 0, child->pins->size - 1, ca);
 
 ok:
@@ -131,54 +150,6 @@ ok:
        }
 }
 
-void __ses_path_dr_reverse(ScfEfunction* f, ses_path_t* path, int i, int j, double a)
-{
-       ScfEpin* p  = path->pins->data[i];
-       ScfEpin* p1 = path->pins->data[j];
-
-       double   r;
-
-       int k;
-       for (k = j; k >= i; k--) {
-
-               ScfEcomponent* c;
-
-               p  = path->pins->data[k];
-               c  = f->components[p->cid];
-
-               if (SCF_EDA_Diode == c->type && SCF_EDA_Diode_NEG == p->id) {
-
-                       ses_ui_r(&p->dr, NULL, SCF_EDA_V_Diode_ON, 0, a, 0);
-
-                       p->dr -= p->r;
-
-                       scf_logw("c%ldp%ld, v: %lg, r: %lg, a: %lg, dr: %lg\n", p->cid, p->id, SCF_EDA_V_Diode_ON, p->r, a, p->dr);
-
-                       p1    = c->pins[SCF_EDA_Diode_POS];
-                       p1->a = a;
-
-               } else if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_B == p->id) {
-
-                       p1    = c->pins[SCF_EDA_NPN_E];
-                       p1->a = a;
-                       p1->aconst = 1;
-
-                       p1  = c->pins[SCF_EDA_NPN_C];
-
-                       a  /= (1 + p1->hfe);
-
-                       p1->a = p1->hfe * a;
-                       p1->aconst = 1;
-
-                       ses_ui_r(&p->dr, NULL, SCF_EDA_V_NPN_ON, 0, a, 0);
-
-                       p->dr -= p->r;
-
-                       scf_logw("c%ldp%ld, v: %lg, r: %lg, a: %lg, dr: %lg\n", p->cid, p->id, SCF_EDA_V_NPN_ON, p->r, a, p->dr);
-               }
-       }
-}
-
 static void __ses_path_a_diode(ScfEfunction* f, ses_path_t* path, int i, int k, double cv, double* a)
 {
        ses_info_t* info;
@@ -201,7 +172,9 @@ static void __ses_path_a_diode(ScfEfunction* f, ses_path_t* path, int i, int k,
                pi        = path->pins->data[i];
                pj        = path->pins->data[info->i];
 
-               v -= info->n_diodes * SCF_EDA_V_Diode_ON + info->n_NPNs * SCF_EDA_V_NPN_ON;
+               v -= info->n_diodes * SCF_EDA_V_Diode_ON;
+               v -= info->n_NPNs   * SCF_EDA_V_NPN_ON;
+               v -= info->n_PNPs   * SCF_EDA_V_PNP_ON;
 
                __ses_path_pr(f, path, i, info->i, NULL, &_r);
 
@@ -241,12 +214,12 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path)
        ScfEpin*       pi;
        ScfEpin*       pj;
 
-       if ((path->n_diodes + path->n_NPNs) * 2 >= path->pins->size) {
+       if ((path->n_diodes + path->n_NPNs + path->n_PNPs) * 2 >= path->pins->size) {
                scf_loge("all components are diodes\n\n");
                return -1;
        }
 
-       if (path->n_diodes + path->n_NPNs <= 0)
+       if (path->n_diodes + path->n_NPNs + path->n_PNPs <= 0)
                return 0;
 
        p0 = path->pins->data[0];
@@ -276,7 +249,8 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path)
                pi->v = el->v;
 
                assert((SCF_EDA_Diode == c->type && SCF_EDA_Diode_POS == pi->id)
-                       || (SCF_EDA_NPN   == c->type && SCF_EDA_NPN_B     == pi->id));
+                       || (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);
 
@@ -298,7 +272,9 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path)
                __ses_path_capacitors(f, path, i, info->i, &cv2);
 
                pi->v = p0->v - v - cv2;
-               pj->v = pi->v - info->n_diodes * SCF_EDA_V_Diode_ON - info->n_NPNs * SCF_EDA_V_NPN_ON;
+               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);
diff --git a/ses_step_va_transistor.c b/ses_step_va_transistor.c
deleted file mode 100644 (file)
index 482e3df..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-#include"ses_core.h"
-
-void __ses_path_dr_transistor(ScfEfunction* f, ses_path_t* path, int i, int j)
-{
-       ScfEpin* p  = path->pins->data[i];
-       ScfEpin* p1 = path->pins->data[j];
-
-       double v = p->v - p1->v;
-       double r;
-       double dr;
-
-       __ses_path_sr(f, path, i, j, &r);
-
-       ses_ui_r(&dr, NULL, v, 0, p->a, 0);
-
-       p->dr  = dr - r;
-
-       scf_logi("c%ldp%ld--c%ldp%ld, v: %lg, r: %lg, dr: %lg, p->sr: %lg, p->a: %lg, p->dr: %lg\n",
-                       p->cid, p->id, p1->cid, p1->id, v, r, dr, p->sr, p->a, p->dr);
-}
-
-int __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe, int vinit)
-{
-       ScfEcomponent* c2;
-       ScfEline*      el;
-       ScfEpin*       p2;
-
-       ScfEcomponent* B  = f->components[0];
-       ScfEpin*       Bp = B->pins[SCF_EDA_Battery_POS];
-       ScfEpin*       Bn = B->pins[SCF_EDA_Battery_NEG];
-
-       size_t i;
-       double Voff = SCF_EDA_Diode == c->type ? SCF_EDA_V_Diode_OFF : SCF_EDA_V_NPN_OFF;
-       double Von  = SCF_EDA_Diode == c->type ? SCF_EDA_V_Diode_ON  : SCF_EDA_V_NPN_ON;
-
-       pb->v = f->elines[pb->lid]->v;
-       pe->v = f->elines[pe->lid]->v;
-
-       if (pb->v < SCF_EDA_V_MIN) {
-
-               if (pe->v < SCF_EDA_V_MIN)
-                       return 0;
-
-               pb->v = pe->v + Von;
-
-               if (pb->v > Bp->v) {
-                       pb->v = Bp->v;
-                       if (!c->lock)
-                               c->status = SCF_EDA_Status_OFF;
-               } else
-                       c->status = SCF_EDA_Status_ON;
-               goto _changed;
-
-       } else if (pe->v < SCF_EDA_V_MIN) {
-               pe->v = pb->v - Von;
-
-               if (pe->v < Bn->v) {
-                       pe->v = Bn->v;
-                       if (!c->lock)
-                               c->status = SCF_EDA_Status_OFF;
-               } else
-                       c->status = SCF_EDA_Status_ON;
-               goto _changed;
-
-       } else if (pb->v - pe->v < Voff) {
-
-               if (c->status != SCF_EDA_Status_OFF) {
-                       if (!c->lock)
-                               c->status  = SCF_EDA_Status_OFF;
-                       goto _changed;
-               }
-       } else if (SCF_EDA_Status_ON != c->status) {
-               c->status  = SCF_EDA_Status_ON;
-               goto _changed;
-       }
-
-       return 0;
-
-_changed:
-       if (SCF_EDA_NPN == c->type) {
-
-               p2 = c->pins  [SCF_EDA_NPN_C];
-               el = f->elines[p2->lid];
-               el->vinit = vinit;
-
-               for (i = 0; i + 1 < el->n_pins; i += 2) {
-
-                       c2 = f->components[el->pins[i]];
-                       p2 = c->pins      [el->pins[i + 1]];
-
-                       if (SCF_EDA_NPN == c2->type && SCF_EDA_NPN_B == p2->id) {
-                               c2->status  = SCF_EDA_Status_ON;
-                               c2->lock    = 1;
-
-                               scf_loge("\033[35mc%ld, status: %d\033[0m\n", c2->id, c2->status);
-                       }
-               }
-       }
-
-       scf_loge("\033[34mc%ld, status: %d, pb->v: %lg, pe->v: %lg, diff: %lg, Von: %lg, Voff: %lg\033[0m\n",
-                       c->id, c->status, pb->v, pe->v, pb->v - pe->v, Von, Voff);
-       return 1;
-}
-
-int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
-{
-       ScfEcomponent* c;
-       ScfEline*      el;
-       ScfEpin*       p0;
-       ScfEpin*       pj;
-
-       ScfEpin*       p;
-       ScfEpin*       pc;
-       ScfEpin*       pb;
-
-       int i;
-       int j = path->pins->size - 1;
-
-       p0 = path->pins->data[0];
-       pj = path->pins->data[j];
-
-       el    = f->elines[p0->lid];
-       p0->v = el->v;
-
-       el    = f->elines[pj->lid];
-       pj->v = el->v;
-
-       for (i = path->pins->size - 1; i >= 0; i--) {
-               pc = path->pins->data[i];
-               pj = path->pins->data[j];
-
-               double v;
-               double a;
-               double pr;
-               double _pr;
-
-               c = f->components[pc->cid];
-
-               scf_logd("i: %d, c%ldp%ld--c%ldp%ld, pc->v: %lg, pc->a: %lg\n", i, p0->cid, p0->id, pc->cid, pc->id, pc->v, pc->a);
-
-               if (SCF_EDA_NPN != c->type || SCF_EDA_NPN_C != pc->id) {
-
-                       if (j < path->pins->size - 1) {
-                               pc->a = pj->a;
-
-                               if (pc->lid != pj->lid) {
-                                       __ses_path_pr(f, path, i, j, NULL, &pr);
-
-                                       ses_ir_u(&v, NULL, pj->a, 0, pr, 0);
-
-                                       pc->v = p0->v - v;
-
-                                       if (path->childs)
-                                               __ses_path_split_i(f, path, i, j, pj->a, &pc->a);
-
-                               } else
-                                       pc->v = pj->v;
-
-                               j = i;
-                       }
-                       continue;
-               }
-
-               if (!pc->aconst)
-                       break;
-
-               pb    = c->pins[SCF_EDA_NPN_B];
-               pc->a = pc->hfe * pb->a;
-
-               __ses_path_pr(f, path, 0, i, NULL, &pr);
-
-               ses_ir_u(&v, NULL, pc->a, 0, pr, 0);
-
-               pc->v = p0->v - v;
-
-               scf_logi("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, pc->pr: %lg, pb c%ldp%ld->a: %lg, pj: c%ldp%ld->v: %lg\n",
-                               i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, pc->pr, pb->cid, pb->id, pb->a, pj->cid, pj->id, pj->v);
-
-               if (pc->v < pj->v) {
-                       v     = p0->v - pj->v;
-
-                       __ses_path_pr(f, path, 0, j, NULL, &_pr);
-
-                       ses_ur_i(&a, NULL, v, 0, _pr, 0);
-
-                       if (path->childs)
-                               __ses_path_split_i(f, path, 0, j, a, &a);
-
-                       ses_ir_u(&v, NULL, a, 0, pr, 0);
-
-                       pc->v = p0->v - v;
-                       pc->a = a;
-
-                       scf_logi("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, _pr: %lg pc->pr: %lg\n",
-                                       i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, _pr, pc->pr);
-               }
-
-               el    = f->elines[pc->lid];
-               el->v = pc->v;
-
-               scf_logw("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, pc->dr: %lg\n",
-                               i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, pc->dr);
-
-               a = pc->a;
-
-               if (path->childs) {
-                       __ses_path_split_i(f, path, i, j, a, &pc->a);
-
-                       if (i > 0) {
-                               p     = path->pins->data[i - 1];
-                               p->a  = a;
-                               p->v  = el->v;
-
-                               __ses_path_split_i(f, path, 0, i - 1, a, &p->a);
-                       }
-               } else
-                       p0->a = a;
-
-               __ses_path_dr_transistor(f, path, i, j);
-
-               scf_loge("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, pc->dr: %lg\n\n",
-                               i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, pc->dr);
-
-               j = i;
-       }
-
-       return 0;
-}
-
-static int ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
-{
-       ses_path_t*    child;
-       ScfEcomponent* B;
-       ScfEpin*       p0;
-       ScfEpin*       p1;
-       ScfEpin*       Bp;
-       ScfEpin*       Bn;
-
-       size_t i;
-       size_t j;
-       size_t k;
-
-       if (!path || path->pins->size < 2)
-               return -EINVAL;
-
-       if (2 == path->pins->size)
-               return 0;
-
-       B  = f->components[0];
-       Bp = B->pins[SCF_EDA_Battery_POS];
-       Bn = B->pins[SCF_EDA_Battery_NEG];
-
-       p0 = path->pins->data[0];
-       p1 = path->pins->data[path->pins->size - 1];
-
-       __ses_path_jr(f, path);
-
-       int ret = __ses_path_va_transistor(f, path);
-       if (ret < 0)
-               return ret;
-
-       if (path->childs) {
-               for (j = 0; j < path->childs->size; j++) {
-                       child     = path->childs->data[j];
-
-                       ret = ses_path_va_transistor(f, child);
-                       if (ret < 0)
-                               return ret;
-               }
-       }
-
-       return 0;
-}
-
-static int _va_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
-{
-       ses_path_t* path;
-
-       int i;
-
-       for (i = 0; i < ctx->paths->size; i++) {
-               path      = ctx->paths->data[i];
-
-               scf_logi("i: %d, path->index: %d\n", i, path->index);
-
-               int ret = ses_path_va_transistor(f, path);
-               if (ret < 0)
-                       return ret;
-
-               printf("\n");
-       }
-
-       return 0;
-}
-
-ses_step_t  ses_step_va_transistor =
-{
-       .name    = "va_transistor",
-
-       .handler = _va_transistor_handler,
-};
index 161450f3850cbf66d471451304b8735ae76ef5a8..a269c8d7053716643d2e34daff8afd5c4e092706 100644 (file)
@@ -3,13 +3,10 @@
 extern ses_step_t   ses_step_battery;
 
 extern ses_step_t   ses_step_dc_input;
-//extern ses_step_t   ses_step_ac_start;
 
 extern ses_step_t   ses_step_dc_diode;
-extern ses_step_t   ses_step_dc_transistor;
-
-//extern ses_step_t   ses_step_ac_transistor;
-//extern ses_step_t   ses_step_ac_diode;
+extern ses_step_t   ses_step_dc_npn;
+extern ses_step_t   ses_step_dc_pnp;
 
 extern ses_step_t   ses_step_topo;
 
@@ -24,7 +21,6 @@ extern ses_step_t   ses_step_va_nodes;
 extern ses_step_t   ses_step_va_capacitor;
 
 extern ses_step_t   ses_step_a_stat;
-extern ses_step_t   ses_step_a_balance;
 
 extern ses_step_t   ses_step_output;
 extern ses_step_t   ses_step_simplify;
@@ -41,16 +37,13 @@ static ses_step_t*  ses_steps_0[] =
 static ses_step_t*  ses_steps_1[] =
 {
        &ses_step_dc_diode,
-       &ses_step_dc_transistor,
+       &ses_step_dc_npn,
+       &ses_step_dc_pnp,
 
        &ses_step_topo,
 
-//     &ses_step_jr,
-
        &ses_step_va_diode,
-       &ses_step_va_transistor,
 
-//     &ses_step_jr,
        &ses_step_va,
        &ses_step_status,
 };
@@ -58,9 +51,8 @@ static ses_step_t*  ses_steps_1[] =
 static ses_step_t*  ses_steps_2[] =
 {
        &ses_step_open,
-//     &ses_step_simplify2,
        &ses_step_va_nodes,
-       &ses_step_va_capacitor,
+//     &ses_step_va_capacitor,
 
 //     &ses_step_a_stat,
 
index a9231e9ca9755ab3f9801a789272cf2f39fb4b3e..a9ba53e47454c0e93d265fa9875fcccfa0e41449 100644 (file)
@@ -98,8 +98,8 @@ void ses_edge_print(ses_edge_t* edge)
                printf(" ");
        printf(")");
 
-       if (edge->npn_b)
-               printf(" b[%d]", edge->npn_b->index);
+       if (edge->edge_b)
+               printf(" b[%d]", edge->edge_b->index);
        printf("; ");
 }
 
index 34d479ec0a46c331261f604a1c6b5706416bb498..a10716ef956bd664bcdab60dd1fe7a86271aab46 100644 (file)
@@ -1,6 +1,7 @@
 #CFILES += main.c
 #CFILES += test.c
-CFILES += fft.c
+#CFILES += fft.c
+CFILES += pnp.c
 CFILES += ../scf_eda_pack.c
 CFILES += ../pack/scf_pack.c
 
diff --git a/test/pnp.c b/test/pnp.c
new file mode 100644 (file)
index 0000000..8954480
--- /dev/null
@@ -0,0 +1,105 @@
+#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* R4;
+       ScfEcomponent* R5;
+
+       ScfEfunction*  f;
+       ScfEboard*     b;
+
+       b = scf_eboard__alloc();
+       f = scf_efunction__alloc("sin_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_PNP);
+
+       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, R4, SCF_EDA_Resistor);
+       EDA_INST_ADD_COMPONENT(f, R5, SCF_EDA_Resistor);
+
+       EDA_PIN_ADD_PIN(B,  SCF_EDA_Battery_POS,  R0, 1);
+       EDA_PIN_ADD_PIN(R0, 1,                    C0, 1);
+       EDA_PIN_ADD_PIN(R0, 0,                    C0, 0);
+       EDA_PIN_ADD_PIN(R0, 0,                    T0, SCF_EDA_NPN_E);
+       EDA_PIN_ADD_PIN(T0, SCF_EDA_NPN_C,        R5, 1);
+       EDA_PIN_ADD_PIN(R5, 0,                    B,  SCF_EDA_Battery_NEG);
+
+       EDA_PIN_ADD_PIN(B,  SCF_EDA_Battery_POS,  R4, 1);
+       EDA_PIN_ADD_PIN(R4, 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,                    C2, 1);
+       EDA_PIN_ADD_PIN(C2, 0,                    C3, 1);
+       EDA_PIN_ADD_PIN(C3, 0,                    T0, SCF_EDA_NPN_B);
+
+       EDA_PIN_ADD_PIN(C1, 0,                    R1, 1);
+       EDA_PIN_ADD_PIN(C2, 0,                    R2, 1);
+       EDA_PIN_ADD_PIN(R1, 0,                    B,  SCF_EDA_Battery_NEG);
+       EDA_PIN_ADD_PIN(R2, 0,                    B,  SCF_EDA_Battery_NEG);
+
+       T0->pins[SCF_EDA_NPN_C]->flags |= SCF_EDA_PIN_OUT;
+       T0->pins[SCF_EDA_NPN_C]->hfe    = 150;
+
+       R1->r  = 1000 * 10;
+       R2->r  = 1000 * 10;
+       R3->r  = 1000 * 10;
+       R4->r  = 1000 * 10;
+       R5->r  = 1000;
+       R0->r  = 1000;
+       C0->uf = 10;
+       C1->uf = 0.01;
+       C2->uf = 0.01;
+       C3->uf = 0.01;
+       C1->r  = 1;
+       C2->r  = 1;
+       C3->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("./pnp_oscillator.cpk", "wb");
+       if (!fp)
+               return -EINVAL;
+
+       fwrite(buf, len, 1, fp);
+       fclose(fp);
+
+       return 0;
+}