From: yu.dongliang <18588496441@163.com> Date: Sat, 11 May 2024 12:25:35 +0000 (+0800) Subject: 1. add mesh analysis, 2. add bridge_algorithm.c, 3. delete some code for capacity... X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=b4ecf2aff383bb823beb64f7b5ffb71be48e4777;p=ses.git 1. add mesh analysis, 2. add bridge_algorithm.c, 3. delete some code for capacity 'va', etc.. --- diff --git a/Makefile b/Makefile index 3c1bf18..12181bc 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,15 @@ CFILES += main.c + CFILES += scf_eda_pack.c CFILES += pack/scf_pack.c + CFILES += ses_layout.c CFILES += ses_graph.c + CFILES += ses_utils.c +CFILES += ses_path.c +CFILES += ses_flow.c +CFILES += ses_mesh_analysis.c CFILES += ses_steps.c CFILES += ses_step_battery.c @@ -13,18 +19,22 @@ CFILES += ses_step_dc_transistor.c CFILES += ses_step_topo.c -CFILES += ses_step_jr.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_va_bridge.c +CFILES += ses_step_va.c +CFILES += ses_step_status.c + CFILES += ses_step_va_line.c CFILES += ses_step_open.c CFILES += ses_step_va_capacitor.c +CFILES += ses_step_a_stat.c + CFILES += ses_step_output.c CFILES += ses_step_simplify.c +CFILES += ses_step_simplify2.c CFLAGS += -g -D_GNU_SOURCE CFLAGS += -I./ @@ -32,6 +42,7 @@ CFLAGS += -I./pack LDFLAGS += -lm LDFLAGS += -lcairo +LDFLAGS += -lgsl -lgslcblas all: gcc $(CFLAGS) $(CFILES) $(LDFLAGS) diff --git a/examples/add.cpk b/examples/add.cpk new file mode 100644 index 0000000..ed6037b Binary files /dev/null and b/examples/add.cpk differ diff --git a/examples/add.pack b/examples/add.pack deleted file mode 100644 index 846a755..0000000 Binary files a/examples/add.pack and /dev/null differ diff --git a/examples/add2.cpk b/examples/add2.cpk new file mode 100644 index 0000000..5c7bdc3 Binary files /dev/null and b/examples/add2.cpk differ diff --git a/examples/add2.pack b/examples/add2.pack deleted file mode 100644 index 955d1a5..0000000 Binary files a/examples/add2.pack and /dev/null differ diff --git a/examples/and.cpk b/examples/and.cpk new file mode 100644 index 0000000..0907c7d Binary files /dev/null and b/examples/and.cpk differ diff --git a/examples/and.pack b/examples/and.pack deleted file mode 100644 index 2dca83e..0000000 Binary files a/examples/and.pack and /dev/null differ diff --git a/examples/or.cpk b/examples/or.cpk new file mode 100644 index 0000000..888bc0b Binary files /dev/null and b/examples/or.cpk differ diff --git a/examples/or.pack b/examples/or.pack deleted file mode 100644 index fd4867b..0000000 Binary files a/examples/or.pack and /dev/null differ diff --git a/examples/oscillator.pack b/examples/oscillator.pack deleted file mode 100644 index 6346f89..0000000 Binary files a/examples/oscillator.pack and /dev/null differ diff --git a/examples/sin_oscillator.cpk b/examples/sin_oscillator.cpk new file mode 100644 index 0000000..b6dd5c5 Binary files /dev/null and b/examples/sin_oscillator.cpk differ diff --git a/main.c b/main.c index 58aeeba..869dd09 100644 --- 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, 300, 1); + ses_steps_analyse(f, 100, 1); } #endif diff --git a/scf_eda_pack.c b/scf_eda_pack.c index 8d3988b..c837e73 100644 --- a/scf_eda_pack.c +++ b/scf_eda_pack.c @@ -1,5 +1,4 @@ #include "scf_eda_pack.h" -//#include "scf_def.h" static int component_pins[SCF_EDA_Components_NB] = { @@ -18,7 +17,7 @@ static int component_pins[SCF_EDA_Components_NB] = static scf_edata_t component_datas[] = { {SCF_EDA_None, 0, 0, 0, 0, 0, 0, 0, 0}, - {SCF_EDA_Battery, 0, SCF_EDA_Battery_POS, 0, 0, 0, 0, 0, 0}, + {SCF_EDA_Battery, 0, SCF_EDA_Battery_POS, 0, 0, 1e-9, 1e9, 0, 0}, {SCF_EDA_Resistor, 0, 0, 0, 0, 1e4, 0, 0, 0}, {SCF_EDA_Capacitor, 0, 0, 0, 0, 10, 0.1, 0, 0}, diff --git a/scf_eda_pack.h b/scf_eda_pack.h index 2cf8303..1f48b4c 100644 --- a/scf_eda_pack.h +++ b/scf_eda_pack.h @@ -119,15 +119,11 @@ struct scf_epin_s SCF_PACK_DEF_VAR(double, uh); SCF_PACK_DEF_VAR(double, hfe); - SCF_PACK_DEF_VAR(double, jdr); SCF_PACK_DEF_VAR(double, dr); SCF_PACK_DEF_VAR(double, sr); SCF_PACK_DEF_VAR(double, pr); - SCF_PACK_DEF_VAR(double, jsr); - SCF_PACK_DEF_VAR(double, jpr); - SCF_PACK_DEF_VAR(uint64_t, path); SCF_PACK_DEF_VAR(int, x); @@ -158,13 +154,9 @@ SCF_PACK_INFO_VAR(ScfEpin, uf), SCF_PACK_INFO_VAR(ScfEpin, uh), SCF_PACK_INFO_VAR(ScfEpin, hfe), -SCF_PACK_INFO_VAR(ScfEpin, jdr), SCF_PACK_INFO_VAR(ScfEpin, dr), - SCF_PACK_INFO_VAR(ScfEpin, sr), SCF_PACK_INFO_VAR(ScfEpin, pr), -SCF_PACK_INFO_VAR(ScfEpin, jsr), -SCF_PACK_INFO_VAR(ScfEpin, jpr), SCF_PACK_INFO_VAR(ScfEpin, path), SCF_PACK_INFO_VAR(ScfEpin, x), @@ -199,7 +191,8 @@ typedef struct { SCF_PACK_DEF_OBJS(ScfLine, lines); SCF_PACK_DEF_VAR(double, v); - SCF_PACK_DEF_VAR(double, a); + SCF_PACK_DEF_VAR(double, ain); + SCF_PACK_DEF_VAR(double, aout); SCF_PACK_DEF_VAR(uint8_t, vconst); SCF_PACK_DEF_VAR(uint8_t, aconst); SCF_PACK_DEF_VAR(uint8_t, vflag); @@ -217,7 +210,8 @@ SCF_PACK_INFO_OBJS(ScfEline, conns, ScfEconn), SCF_PACK_INFO_OBJS(ScfEline, lines, ScfLine), SCF_PACK_INFO_VAR(ScfEline, v), -SCF_PACK_INFO_VAR(ScfEline, a), +SCF_PACK_INFO_VAR(ScfEline, ain), +SCF_PACK_INFO_VAR(ScfEline, aout), SCF_PACK_INFO_VAR(ScfEline, vconst), SCF_PACK_INFO_VAR(ScfEline, aconst), SCF_PACK_INFO_VAR(ScfEline, vflag), @@ -234,7 +228,6 @@ struct scf_ecomponent_s SCF_PACK_DEF_VAR(double, a); SCF_PACK_DEF_VAR(double, dr); - SCF_PACK_DEF_VAR(double, jdr); SCF_PACK_DEF_VAR(double, r); SCF_PACK_DEF_VAR(double, uf); @@ -261,7 +254,6 @@ SCF_PACK_INFO_VAR(ScfEcomponent, v), SCF_PACK_INFO_VAR(ScfEcomponent, a), SCF_PACK_INFO_VAR(ScfEcomponent, dr), -SCF_PACK_INFO_VAR(ScfEcomponent, jdr), SCF_PACK_INFO_VAR(ScfEcomponent, r), SCF_PACK_INFO_VAR(ScfEcomponent, uf), diff --git a/scf_vector.h b/scf_vector.h index d4249ca..c0a88eb 100644 --- a/scf_vector.h +++ b/scf_vector.h @@ -157,6 +157,15 @@ static inline int scf_vector_qsort(const scf_vector_t* v, int (*cmp)(const void* return 0; } +static inline void scf_vector_mov_first(scf_vector_t* v, int i, void* d) +{ + int j; + for (j = i - 1; j >= 0; j--) + v->data[j + 1] = v->data[j]; + + v->data[0] = d; +} + static inline void scf_vector_clear(scf_vector_t* v, void (*type_free)(void*)) { if (!v || !v->data) @@ -195,4 +204,3 @@ static inline void scf_vector_free(scf_vector_t* v) } #endif - diff --git a/ses_core.h b/ses_core.h index eb50c7d..3b92650 100644 --- a/ses_core.h +++ b/ses_core.h @@ -5,9 +5,14 @@ #include"scf_eda_pack.h" typedef struct ses_step_s ses_step_t; + 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_mesh_s ses_mesh_t; + typedef struct ses_info_s ses_info_t; +typedef struct ses_data_s ses_data_t; typedef struct ses_ctx_s ses_ctx_t; struct ses_flow_s @@ -15,7 +20,9 @@ struct ses_flow_s scf_vector_t* paths; ScfEpin* vip; - ScfEpin* vip_n; + int vip_i; + int vip_m; + int vip_n; int pos_pins; int neg_pins; @@ -29,6 +36,9 @@ struct ses_flow_s double pos_r; double neg_r; + double pos_cv; + double neg_cv; + double v; double a; }; @@ -46,8 +56,32 @@ struct ses_info_s int n_capacitors; }; +typedef struct __ses_data_s +{ + uint64_t id; + + double dr; + double v; + double a; + int n_pins; +} __ses_data_t; + +struct ses_data_s +{ + uint64_t id; + + double dr; + double v; + double a; + + int n_pins; + __ses_data_t pins[0]; +}; + struct ses_path_s { + int refs; + scf_vector_t* pins; scf_vector_t* infos; @@ -60,31 +94,61 @@ struct ses_path_s int parent_p1; double parent_pr; - double parent_jpr; double sr; double pr; - double jsr; - double jpr; - double v; double a; double a0; - double da; + double cda; int type; int index; int n_capacitors; int n_diodes; + int n_NPNs; int n_transistors; int n_layers; uint8_t vflag:1; }; +struct ses_edge_s +{ + int refs; + + ses_path_t* path; + int vip_m; + int vip_n; + + int n_diodes; + int n_NPNs; + + double cv; + double r; + + double v; + double a; + double a0; +}; + +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; @@ -101,16 +165,35 @@ struct ses_step_s void* priv; }; +void ses_data_free(scf_vector_t* vec); + ses_path_t* ses_path_alloc(); void ses_path_free (ses_path_t* path); void ses_path_print(ses_path_t* path); +ses_path_t* ses_path_ref (ses_path_t* src); int ses_path_add (ses_path_t* path, ses_path_t* child, ScfEfunction* f); int ses_path_xchg (ses_path_t* path0, int k0, ses_path_t* path1, int k1); -ses_path_t* ses_path_save (ses_path_t* src); -int ses_path_load (ses_path_t* dst, ses_path_t* src); +int ses_path_save (ScfEfunction* f, ses_path_t* path, scf_vector_t** data); +int ses_path_load (ScfEfunction* f, ses_path_t* path, scf_vector_t* data); +int ses_path_is_child(ses_path_t* parent, ses_path_t* child); ses_path_t* ses_path_find_child(ses_path_t* path, int m, int n); +ses_path_t* ses_path_find_bridge(ses_path_t* path, int m, int n); +void ses_path_sort_childs(ses_path_t* path); + +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_flow_t* ses_flow_alloc(); void ses_flow_free (ses_flow_t* flow); @@ -123,11 +206,13 @@ void ses_flow_jr (ses_flow_t* flow, ScfEfunction* f); ses_ctx_t* ses_ctx_alloc(); void ses_ctx_free (ses_ctx_t* ctx); +void ses_components_print(ScfEfunction* f); +void ses_elines_print (ScfEfunction* f); int ses_layout_board (ScfEboard* b); int ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count); -int ses_flows_make_path(ses_path_t** ppath, ses_flow_t* pos, ses_flow_t* neg, ses_path_t* bridge, int reverse); +int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh); int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, ses_path_t* bridge); int ses_flow_find_pos (ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f); @@ -145,17 +230,25 @@ 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_path2 (ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int vip_i, 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_path_jr (ScfEfunction* f, ses_path_t* path); void __ses_path_pr (ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* child, double* r); void __ses_path_jpr(ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* child, double* jr); void __ses_path_sr (ScfEfunction* f, ses_path_t* path, int i, int j, double* r); void __ses_path_jsr(ScfEfunction* f, ses_path_t* path, int i, int j, double* jr); -int __ses_path_va (ScfEfunction* f, ses_path_t* path, int m, int n, int *changed, int64_t ns, int64_t count); + +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); +int __ses_path_va (ScfEfunction* f, ses_path_t* path, int *changed, int64_t ns, int64_t count); +int __ses_flow_va (ScfEfunction* f, ses_flow_t* flow, double* rp, double* rn, int* changed, int64_t ns, int64_t count); + int __ses_path_pos(ScfEfunction* f, ScfEline* el); int __ses_path_neg(ScfEfunction* f, ScfEline* el); -void __ses_npn_epr (ScfEfunction* f, ScfEpin* pe, double* r); -void __ses_npn_dr (ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe); -void __ses_pn_dr (ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe); static inline void vertical(int* px, int* py, int dx, int dy, int d) @@ -264,4 +357,109 @@ static inline void ses_merge_r(double* tr, double* jtr, double r0, double jr0, d *jtr = jr0 / -R; } +static inline void ses_va_PNN(double U0, double U1, double U2, + double R0, double R1, double R2, + double* pi0, double* pi1, double* pi2, double* pVb0) +{ + double i1 = (R0 * (U2 - U1) + R2 * (U0 - U1)) / (R0 * R1 + R1 * R2 + R0 * R2); + double i0 = (U0 - U1 - i1 * R1) / R0; + double i2 = i0 - i1; + + double V0 = i0 * R0; + double V1 = i1 * R1; + double V2 = i2 * R2; + + scf_logi("U0: %lg, U1: %lg, U2: %lg, R0: %lg, R1: %lg, R2: %lg, i0: %lg, i1: %lg, i2: %lg, V0: %lg, V1: %lg, V2: %lg\n", + U0, U1, U2, R0, R1, R2, i0, i1, i2, V0, V1, V2); + + if (pi0) + *pi0 = i0; + + if (pi1) + *pi1 = i1; + + if (pi2) + *pi2 = i2; + + if (*pVb0) + *pVb0 = U0 - V0; +} + +static inline void ses_va_PPN(double U0, double U1, double U2, + double R0, double R1, double R2, + double* pi0, double* pi1, double* pi2, double* pVb1) +{ + double i1 = (R0 * (U2 - U1) + R2 * (U0 - U1)) / (R0 * R1 + R1 * R2 + R0 * R2); + double i0 = (U0 - U1 - i1 * R1) / R0; + double i2 = i1 - i0; + + double V0 = i0 * R0; + double V1 = i1 * R1; + double V2 = i2 * R2; + + scf_logi("U0: %lg, U1: %lg, U2: %lg, R0: %lg, R1: %lg, R2: %lg, i0: %lg, i1: %lg, i2: %lg, V0: %lg, V1: %lg, V2: %lg\n", + U0, U1, U2, R0, R1, R2, i0, i1, i2, V0, V1, V2); + + if (pi0) + *pi0 = i0; + + if (pi1) + *pi1 = i1; + + if (pi2) + *pi2 = i2; + + if (*pVb1) + *pVb1 = U1 + V1; +} + +static inline void ses_va_bridge( + double U0, double U1, double U2, double U3, double Vbc, + double R0, double R1, double R2, double R3, double Rb, + double* pi0, double* pi1, double* pi2, double* pi3, double* pib, + double* pVb0, double* pVb1) +{ + scf_logw("R0: %lg, R1: %lg, R2: %lg, R3: %lg, Vbc: %lg, U0: %lg, U1: %lg, U2: %lg, U3: %lg\n", R0, R1, R2, R3, Vbc, U0, U1, U2, U3); + + double i1 = (R0 * R3 * (U2 - U1 + Vbc) - R0 * R2 * (U1 - U3 - Vbc) + (R2 * R3 + R3 * Rb + R2 * Rb) * (U0 - U1)) + / ((R2 + R3) * (R0 * R1 + Rb * (R0 + R1)) + R2 * R3 * (R0 + R1)); + + double ib = (U0 - U1 - i1 * (R0 + R1)) / R0; + double i0 = i1 + ib; + double i3 = (R0 * (U1 - U3 - Vbc) - Rb * (U0 - U1) + i1 * (R0 * R1 + Rb * (R0 + R1))) / R0 / R3; + double i2 = i3 - ib; + + double V0 = i0 * R0; + double V1 = i1 * R1; + double V2 = i2 * R2; + double V3 = i3 * R3; + double Vb = ib * Rb; + + scf_logi("i0: %lg, i1: %lg, i2: %lg, i3: %lg, ib: %lg\n", i0, i1, i2, i3, ib); + + double Vb0 = U1 + V1; + double Vb1 = U3 + V3; + + if (pi0) + *pi0 = i0; + + if (pi1) + *pi1 = i1; + + if (pi2) + *pi2 = i2; + + if (pi3) + *pi3 = i3; + + if (pib) + *pib = ib; + + if (pVb0) + *pVb0 = Vb0; + + if (pVb1) + *pVb1 = Vb1; +} + #endif diff --git a/ses_flow.c b/ses_flow.c new file mode 100644 index 0000000..fc559a7 --- /dev/null +++ b/ses_flow.c @@ -0,0 +1,414 @@ +#include"ses_core.h" + +ses_flow_t* ses_flow_alloc() +{ + ses_flow_t* flow = calloc(1, sizeof(ses_flow_t)); + if (!flow) + return NULL; + + flow->paths = scf_vector_alloc(); + if (!flow->paths) { + ses_flow_free(flow); + return NULL; + } + + return flow; +} + +void ses_flow_free(ses_flow_t* flow) +{ + if (flow) { + if (flow->paths) + scf_vector_free(flow->paths); + + free(flow); + } +} + +int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, ses_path_t* bridge) +{ + ses_path_t* path; + ScfEpin* p; + + int i; + int j; + + for (i = 0; i < paths->size; i++) { + path = paths->data[i]; + + if (path == bridge) + continue; + + for (j = 0; j < path->pins->size; j++) { + p = path->pins->data[j]; + + if (vip->lid == p->lid) { + + if (j + 1 >= path->pins->size) + break; + + if (scf_vector_add(flow->paths, path) < 0) + return -1; + + flow->vip = p; + flow->vip_i = j; + flow->vip_m = 0; + flow->vip_n = path->pins->size - 1; + return 1; + } + } + + if (path->childs) { + int ret = ses_paths_find_flow(flow, path->childs, vip, bridge); + if (ret < 0) + return ret; + + if (1 == ret) { + if (scf_vector_add(flow->paths, path) < 0) + return -ENOMEM; + return 1; + } + } + + if (path->bridges) { + int ret = ses_paths_find_flow(flow, path->bridges, vip, bridge); + if (ret < 0) + return ret; + + if (1 == ret) { + if (scf_vector_add(flow->paths, path) < 0) + return -ENOMEM; + return 1; + } + } + } + + return 0; +} + +int ses_flow_find_neg(ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f) +{ + if (flow->paths->size <= 0) + return 0; + + ses_path_t* path = flow->paths->data[flow->paths->size - 1]; + ScfEpin* vp = flow->vip; + ScfEpin* p = path->pins->data[path->pins->size - 1]; + + ScfEcomponent* B = f->components[0]; + ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; + + while (p->lid != Bn->lid) { + int ret = ses_paths_find_flow(flow, paths, p, path); + if (ret < 0) + return ret; + + path = flow->paths->data[flow->paths->size - 1]; + p = path->pins ->data[path->pins->size - 1]; + } + + flow->vip = vp; + return 0; +} + +int ses_flow_find_pos(ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f) +{ + if (flow->paths->size <= 0) + return 0; + + ses_path_t* path = flow->paths->data[flow->paths->size - 1]; + ScfEpin* vp = flow->vip; + ScfEpin* p = path->pins->data[0]; + + ScfEcomponent* B = f->components[0]; + ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; + + while (p->lid != Bp->lid) { + int ret = ses_paths_find_flow(flow, paths, p, path); + if (ret < 0) + return ret; + + path = flow->paths->data[flow->paths->size - 1]; + p = path->pins ->data[0]; + } + + flow->vip = vp; + return 0; +} + +void ses_flow_jr(ses_flow_t* flow, ScfEfunction* f) +{ + if (!flow) + return; + + flow->pos_pins = 0; + flow->neg_pins = 0; + + flow->pos_r = 0; + flow->neg_r = 0; + + flow->pos_cv = 0; + flow->neg_cv = 0; + + if (!flow->paths || !flow->vip) + return; + + ses_path_t* path; + ses_path_t* child; + ScfEcomponent* c; + ScfEpin* p; + ScfEpin* p0; + ScfEpin* vip = flow->vip; + + int i; + int j; + int m; + int n; + + for (i = 0; i < flow->paths->size; i++) { + path = flow->paths->data[i]; + + if (0 == i) { + m = flow->vip_m; + n = flow->vip_n; + } else { + m = 0; + n = path->pins->size - 1; + } + + for (j = m; j <= n; j++) { + p = path->pins->data[j]; + + ++flow->pos_pins; + + c = f->components[p->cid]; + + if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_B == p->id) + flow->pos_NPNs++; + else if (SCF_EDA_Diode == c->type && SCF_EDA_Diode_POS == p->id) + flow->pos_diodes++; + + else if (SCF_EDA_Capacitor == c->type && (j & 0x1)) { + int sign = !p->id - p->id; + + flow->pos_cv += c->v * sign; + } + + if (p->lid == vip->lid) { + vip = path->pins->data[0]; + + child = ses_path_find_child(path, 0, j); + if (!child) + child = ses_path_find_bridge(path, 0, j); + + if (child) { + flow->pos_r += child->parent_pr; + + } else if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id) { + p = path->pins->data[j - 1]; + + flow->pos_r += p->pr + p->r + p->dr; + } else + flow->pos_r += p->pr; + + scf_logd("flow->pos_r: %lg, c%ldp%ld->pr: %lg, vip c%ldp%ld->pr: %lg\n", + flow->pos_r, p->cid, p->id, p->pr, vip->cid, vip->id, vip->pr); + break; + } + } + } + + vip = flow->vip; + + for (i = 0; i < flow->paths->size; i++) { + path = flow->paths->data[i]; + + if (0 == i) { + m = flow->vip_m; + n = flow->vip_n; + } else { + m = 0; + n = path->pins->size - 1; + } + + int parallel = 0; + int j0; + + p0 = NULL; + for (j = m; j <= n; j++) { + p = path->pins->data[j]; + + if (!p0) { + if (!(j & 0x1) && p->lid == vip->lid) { + p0 = p; + j0 = j; + + child = ses_path_find_child(path, j0, n); + if (child) + parallel = 1; + } else + continue; + } + + ++flow->neg_pins; + + c = f->components[p->cid]; + + if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_B == p->id) + flow->neg_NPNs++; + else if (SCF_EDA_Diode == c->type && SCF_EDA_Diode_POS == p->id) + flow->neg_diodes++; + + else if (SCF_EDA_Capacitor == c->type && (j & 0x1)) { + int sign = !p->id - p->id; + + flow->neg_cv += c->v * sign; + } + + if (parallel) + continue; + + if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id) { + p = path->pins->data[j - 1]; + + if (p->lid == p0->lid) + flow->neg_r += p->r + p->dr; + else + flow->neg_r += p->pr - p0->pr; + + scf_logd("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n", + flow->neg_r, p->cid, p->id, p->sr, p0->cid, p0->id, p0->pr); + + if (j + 1 <= n) { + p0 = path->pins->data[j + 1]; + j0 = j + 1; + } else { + p0 = path->pins->data[j]; + j0 = j; + } + + } else if (p->sr != p->pr) { + + child = ses_path_find_child(path, j0, j); + if (!child) + child = ses_path_find_bridge(path, j0, j); + + if (child) + flow->neg_r += child->parent_pr - p0->pr; + else + flow->neg_r += p->sr - p0->pr; + + scf_logd("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p->pr: %lg, p0 c%ldp%ld->pr: %lg\n", + flow->neg_r, p->cid, p->id, p->sr, p->pr, p0->cid, p0->id, p0->pr); + + p0 = p; + j0 = j; + } + } + + if (p0) { + vip = path->pins->data[j - 1]; + c = f->components[vip->cid]; + + if (vip != p0) { + child = ses_path_find_child(path, j0, j - 1); + if (child) + flow->neg_r += child->parent_pr - p0->pr; + else + flow->neg_r += vip->sr - p0->pr; + } + + scf_logd("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n", + flow->neg_r, vip->cid, vip->id, vip->sr, p0->cid, p0->id, p0->pr); + + if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == vip->id) + vip->pr = path->parent_pr; + } + + scf_logd("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg\n", flow->neg_r, vip->cid, vip->id, vip->sr); + } + + scf_loge("flow pos_r: %lg, neg_r: %lg, pos_cv: %lg, neg_cv: %lg, vip: c%ldp%ld, pos_diodes: %d, pos_NPNs: %d, neg_diodes: %d, neg_NPNs: %d\n", + flow->pos_r, flow->neg_r, flow->pos_cv, flow->neg_cv, flow->vip->cid, flow->vip->id, flow->pos_diodes, flow->pos_NPNs, flow->neg_diodes, flow->neg_NPNs); +} + +void ses_flow_print(ses_flow_t* flow) +{ + if (!flow || !flow->paths || !flow->vip) + return; + + ses_path_t* path; + ScfEpin* p; + ScfEpin* vip = flow->vip; + + int i; + int j; + int m; + int n; + + for (i = flow->paths->size - 1; i >= 0; i--) { + + if (i > 0) { + path = flow->paths->data[i - 1]; + + vip = path->pins->data[0]; + m = 0; + n = path->pins->size - 1; + } else { + vip = flow->vip; + m = flow->vip_m; + n = flow->vip_n; + } + + path = flow->paths->data[i]; + + for (j = m; j <= n; j++) { + p = path->pins->data[j]; + + printf("c%ldp%ld ", p->cid, p->id); + + if (p->lid == vip->lid) + break; + } + + if (i > 0) + printf(", "); + } + + printf(";\n"); + + vip = flow->vip; + + for (i = 0; i < flow->paths->size; i++) { + path = flow->paths->data[i]; + + if (i > 0) { + m = 0; + n = path->pins->size - 1; + } else { + m = flow->vip_m; + n = flow->vip_n; + } + + int flag = 0; + + for (j = m; j <= n; j++) { + p = path->pins->data[j]; + + if (!flag) { + if (p->lid == vip->lid) + flag = 1; + continue; + } + + printf("c%ldp%ld ", p->cid, p->id); + } + + if (flag) + printf(", "); + + vip = path->pins->data[j - 1]; + } + + printf(".\n"); +} diff --git a/ses_layout.c b/ses_layout.c index 6906dc4..0d4212e 100644 --- a/ses_layout.c +++ b/ses_layout.c @@ -1793,7 +1793,7 @@ int ses_layout_board(ScfEboard* b) ses_lines_same_components(f); - int ret = ses_layout_function(f, 60); + int ret = ses_layout_function(f, 90); if (ret < 0) { scf_loge("\n"); return ret; diff --git a/ses_mesh_analysis.c b/ses_mesh_analysis.c new file mode 100644 index 0000000..ae44d9e --- /dev/null +++ b/ses_mesh_analysis.c @@ -0,0 +1,448 @@ +#include"ses_core.h" +#include + +int ses_mesh_ref_edge(ses_mesh_t* mesh, ses_edge_t* edge) +{ + int ret = scf_vector_add(mesh->edges, edge); + if (ret < 0) + return ret; + + edge->refs++; + return 0; +} + +int ses_mesh_add_edge(ses_mesh_t* mesh, 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(mesh->edges, edge); + if (ret < 0) { + ses_edge_free(edge); + return ret; + } + + if (pp) + *pp = edge; + return 0; +} + +int __ses_meshs_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int vip_i, scf_vector_t** meshs) +{ + scf_vector_t* vec; + ses_path_t* child; + + ses_edge_t* edge = NULL; + ses_edge_t* prev = NULL; + ses_mesh_t* mesh; + ses_mesh_t* right = NULL; + + int ret = -1; + + vec = scf_vector_alloc(); + if (!vec) + return -ENOMEM; + + right = ses_mesh_alloc(); + if (!right) { + ret = -ENOMEM; + goto error; + } + + int i; + int j = vip_i; + int k; + + for (i = vip_i - 1; i >= vip_m; i -= 2) { + + ScfEpin* p = path->pins->data[i]; + + if (!path->childs) + continue; + + for (k = 0; k < path->childs->size; k++) { + child = path->childs->data[k]; + + if (child->parent_p0 == i && child->parent_p1 == vip_n) + break; + } + + if (k >= path->childs->size) + continue; + scf_logd("c%ldp%ld\n", p->cid, p->id); + + mesh = ses_mesh_alloc(); + if (!mesh) { + ret = -ENOMEM; + goto error; + } + + ret = scf_vector_add(vec, mesh); + if (ret < 0) { + ses_mesh_free(mesh); + goto error; + } + + if (prev) { + ret = ses_mesh_add_edge(mesh, prev->path, prev->vip_n, prev->vip_m, NULL); + if (ret < 0) + goto error; + } + + ret = ses_mesh_add_edge(mesh, path, j, i, &edge); + if (ret < 0) + goto error; + ret = ses_mesh_ref_edge(right, edge); + if (ret < 0) + goto error; + + ret = ses_mesh_add_edge(mesh, child, 0, child->pins->size - 1, &prev); + if (ret < 0) + goto error; + + j = i - 1; + } + + if (j > vip_m) { + ret = ses_mesh_add_edge(right, path, j, vip_m, NULL); + if (ret < 0) + goto error; + } + + ret = scf_vector_add(vec, right); + if (ret < 0) + goto error; + + *meshs = vec; + return 0; + +error: + if (right) + ses_mesh_free(right); + + scf_vector_clear(vec, (void (*)(void*) )ses_mesh_free); + scf_vector_free(vec); + return ret; +} + +int __ses_meshs_path(ScfEfunction* f, ses_path_t* path, scf_vector_t** meshs) +{ + int n = path->pins->size - 1; + + return __ses_meshs_path2(f, path, 0, n, n, meshs); +} + +/* + a[vip_n, 0] = Iright + I[0] + a[0, 1] = Iright + I[1] + a[1, 2] = Iright + I[2] + ... + a[n - 2, n - 1] = Iright + I[n - 1] + a[n - 1, vip_m] = Iright + + a[0] = I[0] - I[1] + a[1] = I[1] - I[2] + ... + a[n - 1] = I[n - 1] + +----------------------------- + v[0] - a[0] * R[0] = C[0] + Vn + v[1] - a[1] * R[1] = C[1] + Vn +... + v[n - 1] - a[n - 1] * R[n - 1] = C[n - 1] + Vn + + + v[vip_n] - v[0] - a[vip_n, 0] * R[vip_n, 0] = C[vip_n, 0] + v[0] - v[1] - a[0, 1] * R[0, 1] = C[0, 1] +... + v[n - 2] - v[n - 1] - a[n - 2, n - 1] * R[n - 2, n - 1] = C[n - 2, n - 1] + v[n - 1] - a[n - 1, m] * R[n - 1, m] = C[n - 1, m] + Vm + +----------------------------- + v[0] - (I[0] - I[1]) * R[0] = C[0] + Vn + v[1] - (I[1] - I[2]) * R[1] = C[1] + Vn +... + v[n - 2] - (I[n -2] - I[n-1]) * R[n - 2] = C[n - 2] + Vn + v[n - 1] - I[n -1] * R[n - 1] = C[n - 1] + Vn + + - v[0] - (Iright + I[0]) * R[vip_n, 0] = C[vip_n, 0] - Vn + v[0] - v[1] - (Iright + I[1]) * R[0, 1] = C[0, 1] +... + v[n - 2] - v[n - 1] - (Iright + I[n-1]) * R[n - 2, n - 1] = C[n - 2, n - 1] + v[n - 1] - Iright * R[n - 1, m] = C[n - 1, m] + Vm + +----------------------------- + 0: v[0] + 1: v[1] + ... +n - 1: v[n - 1] + +n : I[0] +n + 1: I[1] + ... +2n -1: I[n - 1] +2n : Iright +*/ + +int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* meshs, int* changed, int64_t ns, int64_t count) +{ + ses_mesh_t* mesh; + ses_edge_t* edge; + + ScfEline* el; + ScfEpin* pm = path->pins->data[vip_m]; + ScfEpin* pn = path->pins->data[vip_n]; + ScfEpin* p0; + ScfEpin* p1; + + int ret = 0; + + int n = meshs->size - 1; + int N = 2 * n + 1; + int i; + + scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, n_childs: %d, N: %d\n", pm->cid, pm->id, pm->v, pn->cid, pn->id, pn->v, n, N); + + double* A = calloc(N * N + N + N, sizeof(double)); + if (!A) + return -ENOMEM; + + double* b = A + N * N; + double* X = b + N; + double cv; + double pr; + + __ses_path_jr(f, path); + + for (i = 0; i < meshs->size - 1; i++) { + mesh = meshs->data[i]; + + edge = mesh->edges->data[mesh->edges->size - 1]; + + __ses_path_capacitors(f, edge->path, edge->vip_m, edge->vip_n, &cv); + b[i] = cv + pn->v; + + __ses_path_pr(f, edge->path, edge->vip_m, edge->vip_n, NULL, &pr); + + edge->r = pr; + + p0 = edge->path->pins->data[edge->vip_m]; + p1 = edge->path->pins->data[edge->vip_n]; + scf_logi("c%ldp%ld-c%ldp%ld, pr: %lg, cv: %lg\n", p0->cid, p0->id, p1->cid, p1->id, pr, cv); + + A[i * N + i] = 1; + A[i * N + n + i] = -pr; + + if (i < n - 1) + A[i * N + n + i + 1] = pr; + } + + mesh = meshs->data[meshs->size - 1]; + + for (i = 0; i < mesh->edges->size; i++) { + edge = mesh->edges->data[i]; + + if (edge->vip_m > edge->vip_n) { + + if (0 == edge->vip_n && edge->vip_m == edge->path->pins->size - 1) + pr = edge->path->pr; + else + __ses_path_pr(f, edge->path, edge->vip_n, edge->vip_m, NULL, &pr); + + __ses_path_capacitors(f, edge->path, edge->vip_n, edge->vip_m, &cv); + b[n + i] = -cv; + } else { + __ses_path_capacitors(f, edge->path, edge->vip_m, edge->vip_n, &cv); + b[n + i] = cv; + + if (0 == edge->vip_m && edge->vip_n == edge->path->pins->size - 1) + pr = edge->path->pr; + else + __ses_path_pr(f, edge->path, edge->vip_m, edge->vip_n, NULL, &pr); + } + + if (i > 0) + A[(n + i) * N + i - 1] = 1; + else + b[n + i] -= pn->v; + + if (i < n) { + A[(n + i) * N + i] = -1; + A[(n + i) * N + n + i] = -pr; + } else + b[n + i] += pm->v; + + A[(n + i) * N + 2 * n] = -pr; + + p0 = edge->path->pins->data[edge->vip_m]; + p1 = edge->path->pins->data[edge->vip_n]; + + edge->r = pr; + + scf_logi("c%ldp%ld-c%ldp%ld, pr: %lg, cv: %lg, vip_m: %d, vip_n: %d\n", p0->cid, p0->id, p1->cid, p1->id, pr, cv, edge->vip_m, edge->vip_n); + } + + gsl_matrix_view _A = gsl_matrix_view_array(A, N, N); + gsl_vector_view _b = gsl_vector_view_array(b, N); + gsl_vector_view _X = gsl_vector_view_array(X, N); + + int s; + gsl_permutation* _P = gsl_permutation_alloc(N); + if (!_P) { + ret = -ENOMEM; + goto P_failed; + } + + gsl_linalg_LU_decomp(&_A.matrix, _P, &s); + gsl_linalg_LU_solve (&_A.matrix, _P, &_b.vector, &_X.vector); + + scf_logi("X:\n"); + gsl_vector_fprintf(stdout, &_X.vector, "%lg"); +#if 1 + for (i = 0; i < meshs->size - 1; i++) { + mesh = meshs->data[i]; + + edge = mesh->edges->data[mesh->edges->size - 1]; + + p0 = edge->path->pins->data[edge->vip_m]; + p1 = edge->path->pins->data[edge->vip_n]; + + el = f->elines[p0->lid]; + el->v = X[i]; + + ret = __ses_path_va2(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ns, count); + if (ret < 0) + goto error; + } + + mesh = meshs->data[meshs->size - 1]; + + for (i = 0; i < mesh->edges->size; i++) { + edge = mesh->edges->data[i]; + + p0 = edge->path->pins->data[edge->vip_m]; + p1 = edge->path->pins->data[edge->vip_n]; + + ret = __ses_path_va2(f, edge->path, edge->vip_n, edge->vip_m, edge->r, changed, ns, count); + if (ret < 0) + goto error; + } +#endif +error: + gsl_permutation_free(_P); +P_failed: + free(A); + return ret; +} + +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) +{ + scf_vector_t* meshs = NULL; + ses_mesh_t* mesh; + ses_edge_t* edge; + + ScfEline* el; + ScfEpin* pm = path->pins->data[vip_m]; + ScfEpin* pn = path->pins->data[vip_n]; + ScfEpin* p0; + ScfEpin* p1; + + int ret = __ses_meshs_path2(f, path, vip_m, vip_n, vip_n, &meshs); + if (ret < 0) + return ret; + + ses_meshs_print(meshs); + + ret = __ses_meshs_path_solve2(f, path, vip_m, vip_n, meshs, changed, ns, count); + + scf_vector_clear(meshs, (void (*)(void*) )ses_mesh_free); + scf_vector_free(meshs); + + return ret; +} + +int __ses_meshs_PPN(ScfEfunction* f, ses_flow_t* flow, ses_path_t* bridge, scf_vector_t** meshs) +{ + scf_vector_t* vec = NULL; + ses_path_t* path = flow->paths->data[0]; + + ses_edge_t* edge0 = NULL; + ses_edge_t* edge1 = NULL; + ses_mesh_t* mesh; + ses_mesh_t* left; + ses_mesh_t* right; + + int ret = __ses_meshs_path2(f, path, flow->vip_m, flow->vip_n, flow->vip_i, &vec); + if (ret < 0) + return ret; + + mesh = vec->data[0]; + right = vec->data[vec->size - 1]; + + left = ses_mesh_alloc(); + if (!left) { + ret = -ENOMEM; + goto error; + } + + ret = scf_vector_add(vec, left); + if (ret < 0) { + ses_mesh_free(left); + goto error; + } + scf_vector_mov_first(vec, vec->size - 1, left); + + ret = ses_mesh_add_edge(left, bridge, 0, bridge->pins->size - 1, &edge0); + if (ret < 0) + goto error; + + ret = ses_mesh_ref_edge(right, edge0); + if (ret < 0) + goto error; + + ret = ses_mesh_add_edge(left, path, flow->vip_i + 1, flow->vip_n, NULL); + if (ret < 0) + goto error; + + ret = ses_mesh_add_edge(mesh, path, flow->vip_n, flow->vip_i + 1, &edge1); + if (ret < 0) + goto error; + + scf_vector_mov_first(right->edges, right->edges->size - 1, edge0); + scf_vector_mov_first(mesh ->edges, mesh ->edges->size - 1, edge1); + + *meshs = vec; + return 0; + +error: + scf_vector_clear(vec, (void (*)(void*) )ses_mesh_free); + scf_vector_free(vec); + return ret; +} + +int __ses_meshs_PPN_solve(ScfEfunction* f, ses_flow_t* flow, ses_path_t* bridge, int* changed, int64_t ns, int64_t count) +{ + scf_vector_t* meshs = NULL; + ses_path_t* path = flow->paths->data[0]; + ses_mesh_t* mesh; + ses_edge_t* edge; + + ScfEline* el; + ScfEpin* pm = path->pins->data[flow->vip_m]; + ScfEpin* pn = path->pins->data[flow->vip_n]; + ScfEpin* p0; + ScfEpin* p1; + + int ret = __ses_meshs_PPN(f, flow, bridge, &meshs); + if (ret < 0) + return ret; + + ses_meshs_print(meshs); + + ret = __ses_meshs_path_solve2(f, path, flow->vip_m, flow->vip_n, meshs, changed, ns, count); + + scf_vector_clear(meshs, (void (*)(void*) )ses_mesh_free); + scf_vector_free(meshs); + return ret; +} diff --git a/ses_path.c b/ses_path.c new file mode 100644 index 0000000..7061ec5 --- /dev/null +++ b/ses_path.c @@ -0,0 +1,712 @@ +#include"ses_core.h" + +ses_path_t* ses_path_alloc() +{ + ses_path_t* path = calloc(1, sizeof(ses_path_t)); + if (!path) + return NULL; + + path->pins = scf_vector_alloc(); + if (!path->pins) { + free(path); + return NULL; + } + + path->infos = scf_vector_alloc(); + if (!path->infos) { + scf_vector_free(path->pins); + free(path); + return NULL; + } + + path->refs = 1; + return path; +} + +void ses_path_free(ses_path_t* path) +{ + if (path) { + if (--path->refs > 0) + return; + + assert(0 == path->refs); + + if (path->pins) + scf_vector_free(path->pins); + + if (path->infos) { + scf_vector_clear(path->infos, ( void (*)(void*) )free); + scf_vector_free (path->infos); + } + + if (path->childs) { + scf_vector_clear(path->childs, ( void (*)(void*) )ses_path_free); + scf_vector_free (path->childs); + } + + if (path->bridges) { + scf_vector_clear(path->bridges, ( void (*)(void*) )ses_path_free); + scf_vector_free (path->bridges); + } + + scf_logd("path: %d\n", path->index); + + free(path); + } +} + +ses_path_t* ses_path_ref(ses_path_t* src) +{ + if (!src) + return NULL; + + ses_path_t* dst = ses_path_alloc(); + if (!dst) + return NULL; + + dst->pins = scf_vector_clone(src->pins); + if (!dst->pins) { + ses_path_free(dst); + return NULL; + } + + if (src->childs) { + dst->childs = scf_vector_clone(src->childs); + + if (!dst->childs) { + ses_path_free(dst); + return NULL; + } + + ses_path_t* child; + int i; + + for (i = 0; i < dst->childs->size; i++) { + child = dst->childs->data[i]; + child->refs++; + } + } + + dst->index = src->index; + return dst; +} + +void ses_path_print(ses_path_t* path) +{ + if (!path) + return; + + ses_path_t* path2; + ScfEpin* p; + + int i; + + 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); + + for (i = 0; i < path->pins->size; i++) { + p = path->pins->data[i]; + + printf("c%ldp%ld ", p->cid, p->id); + } + printf("\n"); + + if (path->childs) { + for (i = 0; i < path->childs->size; i++) { + path2 = 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); + + ses_path_print(path2); + } + } + + if (path->bridges) { + for (i = 0; i < path->bridges->size; i++) { + path2 = 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); + + ses_path_print(path2); + } + } +} + +int ses_path_is_child(ses_path_t* parent, ses_path_t* child) +{ + ScfEpin* cp0 = child->pins->data[0]; + ScfEpin* cp1 = child->pins->data[child->pins->size - 1]; + ScfEpin* p; + + int i; + int j = -1; + + for (i = 0; i < parent->pins->size; i++) { + p = parent->pins->data[i]; + + if (p->lid == cp0->lid) { + j = i; + continue; + } + + if (p->lid == cp1->lid) { + if (j >= 0) + return 1; + return 0; + } + } + + return 0; +} + +static int _ses_child_cmp(const void* v0, const void* v1) +{ + const ses_path_t* p0 = *(const ses_path_t**)v0; + const ses_path_t* p1 = *(const ses_path_t**)v1; + + if (p0->parent_p0 <= p1->parent_p0 && p0->parent_p1 >= p1->parent_p1) + return -1; + + if (p0->parent_p0 >= p1->parent_p0 && p0->parent_p1 <= p1->parent_p1) + return 1; + return 0; +} + +void ses_path_child_index(ses_path_t* path, ses_path_t* child) +{ + ScfEpin* cp0; + ScfEpin* cp1; + ScfEpin* p; + + child->parent_p0 = -1; + child->parent_p1 = -1; + + cp0 = child->pins->data[0]; + cp1 = child->pins->data[child->pins->size - 1]; + + int j; + for (j = 0; j < path->pins->size; j++) { + p = path->pins->data[j]; + + if (p->lid == cp0->lid) + child->parent_p0 = j; + + else if (p->lid == cp1->lid) { + child->parent_p1 = j; + break; + } + } + + assert(child->parent_p0 >= 0); + assert(child->parent_p1 >= 0); +} + +void ses_path_sort_childs(ses_path_t* path) +{ + ses_path_t* child; + + if (path && path->childs) { + int i; + for (i = 0; i < path->childs->size; i++) { + child = path->childs->data[i]; + + ses_path_child_index(path, child); + } + + scf_vector_qsort(path->childs, _ses_child_cmp); + } +} + +ses_path_t* ses_path_find_child(ses_path_t* path, int m, int n) +{ + ses_path_t* child; + ScfEpin* cp0; + ScfEpin* cp1; + + if (path->childs) { + ScfEpin* p0 = path->pins->data[m]; + ScfEpin* p1 = path->pins->data[n]; + + scf_logd("c%ldp%ld-c%ldp%ld\n", p0->cid, p0->id, p1->cid, p1->id); + int i; + int j; + + for (i = 0; i < path->childs->size; i++) { + child = path->childs->data[i]; + + cp0 = child->pins->data[0]; + cp1 = child->pins->data[child->pins->size - 1]; + + if (cp1->lid != p1->lid) + continue; + + for (j = m; j <= n; j++) { + p0 = path->pins->data[j]; + + if (cp0->lid == p0->lid) + return child; + } + } + } + return NULL; +} + +ses_path_t* ses_path_find_bridge(ses_path_t* path, int m, int n) +{ + ses_path_t* child; + ScfEpin* cp0; + ScfEpin* cp1; + + if (path->bridges) { + ScfEpin* p0 = path->pins->data[m]; + ScfEpin* p1 = path->pins->data[n]; + + scf_logd("c%ldp%ld-c%ldp%ld\n", p0->cid, p0->id, p1->cid, p1->id); + int i; + int j; + + for (i = 0; i < path->bridges->size; i++) { + child = path->bridges->data[i]; + + cp0 = child->pins->data[0]; + cp1 = child->pins->data[child->pins->size - 1]; + + if (cp1->lid != p1->lid) + continue; + + for (j = m; j <= n; j++) { + p0 = path->pins->data[j]; + + if (cp0->lid == p0->lid) + return child; + } + } + } + return NULL; +} + +int ses_path_xchg(ses_path_t* path0, int k0, ses_path_t* path1, int k1) +{ + ScfEpin* p; + + int i; + + for (i = 0; i + k0 < path0->pins->size && i + k1 < path1->pins->size; i++) + SCF_XCHG(path0->pins->data[i + k0], path1->pins->data[i + k1]); + + scf_logd("path0: %d, k0: %d ... path1: %d, k1: %d, i: %d\n", path0->pins->size, k0, path1->pins->size, k1, i); + + if (i + k0 < path0->pins->size) { + + while (i + k0 < path0->pins->size) { + p = path0->pins->data[i + k0]; + + assert(0 == scf_vector_del(path0->pins, p)); + + if (scf_vector_add(path1->pins, p) < 0) + return -ENOMEM; + } + + } else if (i + k1 < path1->pins->size) { + + while (i + k1 < path1->pins->size) { + p = path1->pins->data[i + k1]; + + assert(0 == scf_vector_del(path1->pins, p)); + + if (scf_vector_add(path0->pins, p) < 0) + return -ENOMEM; + } + } + + return 0; +} + +int ses_path_add(ses_path_t* parent, ses_path_t* child, ScfEfunction* f) +{ + if (!parent || !child) + return -EINVAL; + + if (!parent->childs) { + parent->childs = scf_vector_alloc(); + if (!parent->childs) + return -ENOMEM; + } + + ses_path_t* path; + ScfEpin* p0; + ScfEpin* p1; + ScfEpin* cp0 = child->pins->data[0]; + ScfEpin* cp1 = child->pins->data[child->pins->size - 1]; + + 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; + + for (j = 0; j < parent->pins->size; j++) { + p0 = parent->pins->data[j]; + + if (p0->lid == cp0->lid) { + child->parent_p0 = (j + 1) & ~0x1; + break; + } + } + assert(j < parent->pins->size); + + int n_transistors = 0; + int n_capacitors = 0; + int n_diodes = 0; + int n_NPNs = 0; + + for ( ; j < parent->pins->size; j++) { + p0 = parent->pins->data[j]; + + if (!(j & 0x1)) { + ScfEcomponent* c = f->components[p0->cid]; + + if (SCF_EDA_Capacitor == c->type) + n_capacitors++; + + else if (SCF_EDA_Diode == c->type) + n_diodes++; + + else if (SCF_EDA_NPN == c->type) { + if (SCF_EDA_NPN_B == p0->id) + n_NPNs++; + else if (SCF_EDA_NPN_C == p0->id) + n_transistors++; + } + } + + if (p0->lid == cp1->lid) { + child->parent_p1 = j; + break; + } + } + assert(j < parent->pins->size); + + p0 = parent->pins->data[0]; + p1 = parent->pins->data[parent->pins->size - 1]; + + scf_logd("parent: %d, c%ldp%ld-c%ldp%ld, child: %d, c%ldp%ld-c%ldp%ld\n", + parent->index, p0->cid, p0->id, p1->cid, p1->id, + child->index, cp0->cid, cp0->id, cp1->cid, cp1->id); + + if (0 == n_transistors + && (n_diodes + n_NPNs < child->n_diodes + child->n_NPNs + || (n_diodes + n_NPNs == child->n_diodes + child->n_NPNs && n_capacitors < child->n_capacitors))) { + + int ret = ses_path_xchg(parent, child->parent_p0, child, 0); + if (ret < 0) + return ret; + + int old_parent_p1 = child->parent_p1; + j = child->parent_p1 - child->parent_p0 + 1; + child->parent_p1 = parent->pins->size - 1; + + while (j < child->pins->size) { + p0 = child->pins->data[j]; + + assert(0 == scf_vector_del(child->pins, p0)); + + ret = scf_vector_add(parent->pins, p0); + if (ret < 0) + return ret; + } + + parent->n_NPNs += child->n_NPNs - n_NPNs; + child ->n_NPNs = n_NPNs; + + parent->n_diodes += child->n_diodes - n_diodes; + child ->n_diodes = n_diodes; + + parent->n_capacitors += child->n_capacitors - n_capacitors; + child ->n_capacitors = n_capacitors; + + for (j = 0; j < parent->childs->size; ) { + path = parent->childs->data[j]; + + if (path == child) { + j++; + continue; + } + + if (path->parent_p1 <= child->parent_p0) { + j++; + continue; + } + + if (path->parent_p0 >= child->parent_p1) { + path->parent_p0 += child->parent_p1 - old_parent_p1; + path->parent_p1 += child->parent_p1 - old_parent_p1; + j++; + continue; + } + + if (path->parent_p0 == child->parent_p0 && path->parent_p1 == old_parent_p1) { + + assert(0 == scf_vector_del(parent->childs, path)); + + ret = ses_path_add(child, path, f); + if (ret < 0) + return ret; + continue; + } + + cp0 = path->pins->data[0]; + cp1 = path->pins->data[path->pins->size - 1]; + + path->parent_p0 = -1; + path->parent_p1 = -1; + + int k; + for (k = 0; k < parent->pins->size; k++) { + p0 = parent->pins->data[k]; + + if (p0->lid == cp0->lid) { + path->parent_p0 = k; + continue; + } + + if (p0->lid == cp1->lid) { + path->parent_p1 = k; + break; + } + } + + if (-1 == path->parent_p0 || -1 == path->parent_p1) { + assert(0 == scf_vector_del(parent->childs, path)); + + if (!parent->bridges) { + parent->bridges = scf_vector_alloc(); + if (!parent->bridges) + return -ENOMEM; + } + + ret = scf_vector_add(parent->bridges, path); + if (ret < 0) + return ret; + } else + j++; + } + + if (child->childs) { + for (j = 0; j < child->childs->size; ) { + path = child->childs->data[j]; + + cp0 = path->pins->data[0]; + cp1 = path->pins->data[path->pins->size - 1]; + + path->parent_p0 = -1; + path->parent_p1 = -1; + + int k; + for (k = 0; k < child->pins->size; k++) { + p0 = child->pins->data[k]; + + if (p0->lid == cp0->lid) { + path->parent_p0 = k; + continue; + } + + if (p0->lid == cp1->lid) { + path->parent_p1 = k; + break; + } + } + + if (-1 == path->parent_p0 || -1 == path->parent_p1) { + assert(0 == scf_vector_del(child->childs, path)); + + ret = ses_path_add(parent, path, f); + if (ret < 0) + return ret; + } else + j++; + } + } + } + + child->parent = parent; + child->type = SES_PATH_BRANCH; + return 0; +} + +static int __ses_path_save(ScfEfunction* f, ses_path_t* path, scf_vector_t* vec) +{ + ses_path_t* child; + ses_data_t* d; + + ScfEcomponent* c; + ScfEpin* p; + + int i; + int j; + + for (i = 0; i < path->pins->size; i += 2) { + p = path->pins->data[i]; + + c = f->components[p->cid]; + d = NULL; + + if (SCF_EDA_NPN == c->type) { + for (j = vec->size - 1; j >= 0; j--) { + d = vec->data[j]; + + if (d->id == c->id) + goto save_pins; + } + } + + d = malloc(sizeof(ses_data_t) * (1 + c->n_pins)); + if (!d) + return -ENOMEM; + + int ret = scf_vector_add(vec, d); + if (ret < 0) { + free(d); + return ret; + } + + d->id = c->id; + d->dr = c->dr; + d->v = c->v; + d->a = c->a; + d->n_pins = c->n_pins; + +save_pins: + for (j = 0; j < c->n_pins; j++) { + p = c->pins[j]; + + d->pins[j].id = p->id; + d->pins[j].dr = p->dr; + d->pins[j].v = p->v; + d->pins[j].a = p->a; + d->pins[j].n_pins = 0; + } + } + + if (path->childs) { + for (i = 0; i < path->childs->size; i++) { + child = path->childs->data[i]; + + int ret = __ses_path_save(f, child, vec); + if (ret < 0) + return ret; + } + } + + return 0; +} + +int ses_path_save(ScfEfunction* f, ses_path_t* path, scf_vector_t** data) +{ + if (!f || !path || !data) + return -EINVAL; + + scf_vector_t* vec = scf_vector_alloc(); + if (!vec) + return -ENOMEM; + + int ret = __ses_path_save(f, path, vec); + if (ret < 0) { + scf_vector_clear(vec, (void (*)(void*) )free); + scf_vector_free(vec); + return ret; + } + + *data = vec; + return 0; +} + +void ses_data_free(scf_vector_t* vec) +{ + if (vec) { + scf_vector_clear(vec, (void (*)(void*) )free); + scf_vector_free(vec); + } +} + +void ses_data_print(scf_vector_t* vec) +{ + __ses_data_t* p; + ses_data_t* c; + int i; + int j; + + if (vec) { + for (i = 0; i < vec->size; i++) { + c = vec->data[i]; + + printf("c%ld->v: %lg, a: %lg, dr: %lg\n", c->id, c->v, c->a, c->dr); + + for (j = 0; j < c->n_pins; j++) { + p = &c->pins[j]; + + printf("c%ldp%ld->v: %lg, a: %lg, dr: %lg\n", c->id, p->id, p->v, p->a, p->dr); + } + printf("\n"); + } + } +} + +int ses_path_load(ScfEfunction* f, ses_path_t* path, scf_vector_t* data) +{ + if (!f || !path || !data) + return -EINVAL; + + ses_data_t* d; + ScfEcomponent* c; + ScfEpin* p; + + int i; + int j; + + for (i = 0; i < data->size; i++) { + d = data->data[i]; + + c = f->components[d->id]; + c->v = d->v; + c->a = d->a; + c->dr = d->dr; + + assert(d->n_pins == c->n_pins); + + for (j = 0; j < c->n_pins; j++) { + p = c->pins[j]; + + p->v = d->pins[j].v; + p->a = d->pins[j].a; + p->dr = d->pins[j].dr; + } + } + + return 0; +} diff --git a/ses_step_a_stat.c b/ses_step_a_stat.c new file mode 100644 index 0000000..5064415 --- /dev/null +++ b/ses_step_a_stat.c @@ -0,0 +1,60 @@ +#include"ses_core.h" + +static int _a_stat_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) +{ + ses_path_t* path; + + ScfEcomponent* B = f->components[0]; + ScfEcomponent* c; + ScfEline* el; + ScfEpin* p; + ScfEpin* p0; + ScfEpin* p1; + ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; + ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; + + int i; + for (i = 1; i < f->n_components; i++) { + c = f->components[i]; + + if (SCF_EDA_NPN == c->type) { + + p = c->pins[SCF_EDA_NPN_B]; + el = f->elines[p->lid]; + el->aout += p->a; + + p = c->pins[SCF_EDA_NPN_C]; + el = f->elines[p->lid]; + el->aout += p->a; + + p = c->pins[SCF_EDA_NPN_E]; + p->a = c->pins[SCF_EDA_NPN_B]->a + c->pins[SCF_EDA_NPN_C]->a; + el = f->elines[p->lid]; + el->ain += p->a; + continue; + } + + if (c->a > 0) { + el = f->elines[c->pins[0]->lid]; + el->ain += c->a; + + el = f->elines[c->pins[1]->lid]; + el->aout += c->a; + } else { + el = f->elines[c->pins[0]->lid]; + el->aout -= c->a; + + el = f->elines[c->pins[1]->lid]; + el->ain -= c->a; + } + } + + return 0; +} + +ses_step_t ses_step_a_stat = +{ + .name = "a_stat", + + .handler = _a_stat_handler, +}; diff --git a/ses_step_dc_transistor.c b/ses_step_dc_transistor.c index 4ada12b..e13c1d0 100644 --- a/ses_step_dc_transistor.c +++ b/ses_step_dc_transistor.c @@ -45,7 +45,7 @@ static int _dc_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, se continue; } - scf_logi("c%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n", + 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 (lb->v < SCF_EDA_V_MIN) { diff --git a/ses_step_jr.c b/ses_step_jr.c index ea709a9..9086dd4 100644 --- a/ses_step_jr.c +++ b/ses_step_jr.c @@ -25,46 +25,24 @@ void __ses_path_pr(ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* ScfEpin* p0 = path->pins->data[i]; ScfEpin* p1 = path->pins->data[j]; - if (!child) { - *r = p1->pr - p0->pr; - - scf_logd("c%ldp%ld-c%ldp%ld, r: %lg, p0->pr: %lg, p1->pr: %lg\n", - p0->cid, p0->id, p1->cid, p1->id, *r, p0->pr, p1->pr); - } else { + if (child) { *r = child->parent_pr - p0->pr; scf_logd("c%ldp%ld-c%ldp%ld, r: %lg, p0->pr: %lg, p1->pr: %lg, child->parent_pr: %lg\n", p0->cid, p0->id, p1->cid, p1->id, *r, p0->pr, p1->pr, child->parent_pr); + return; } -} - -void __ses_path_jsr(ScfEfunction* f, ses_path_t* path, int i, int j, double* jr) -{ - ScfEpin* p0 = path->pins->data[i]; - ScfEpin* p1 = path->pins->data[j]; - - *jr = p1->jsr - p0->jpr; - - scf_logd("c%ldp%ld-c%ldp%ld, jr: %lg, p0->jsr: %lg, p0->jpr: %lg, p1->jsr: %lg, p1->jpr: %lg\n", - p0->cid, p0->id, p1->cid, p1->id, *jr, p0->jsr, p0->jpr, p1->jsr, p1->jpr); -} - -void __ses_path_jpr(ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* child, double* jr) -{ - ScfEpin* p0 = path->pins->data[i]; - ScfEpin* p1 = path->pins->data[j]; - if (!child) { - *jr = p1->jpr - p0->jpr; + child = ses_path_find_child(path, i, j); + if (child) { + *r = child->parent_pr - p0->pr; + return; + } - scf_logd("c%ldp%ld-c%ldp%ld, jr: %lg, p0->jpr: %lg, p1->jpr: %lg\n", - p0->cid, p0->id, p1->cid, p1->id, *jr, p0->jpr, p1->jpr); - } else { - *jr = child->parent_jpr - p0->jpr; + *r = p1->sr - p0->pr; - scf_logd("c%ldp%ld-c%ldp%ld, jr: %lg, p0->jpr: %lg, p1->jpr: %lg, child->parent_jpr: %lg\n", - p0->cid, p0->id, p1->cid, p1->id, *jr, p0->jpr, p1->jpr, child->parent_jpr); - } + scf_logd("c%ldp%ld-c%ldp%ld, r: %lg, p0->pr: %lg, p1->sr: %lg\n", + p0->cid, p0->id, p1->cid, p1->id, *r, p0->pr, p1->sr); } int __ses_path_jr(ScfEfunction* f, ses_path_t* path) @@ -88,9 +66,6 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) double r; double r2; - double jr; - double jr2; - int i; int j; @@ -105,36 +80,27 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) } r = 0; - jr = 0; for (i = 0; i < path->pins->size; i++) { p = path->pins->data[i]; c = f->components[p->cid]; r2 = r; - r += p->r + p->dr + p->jdr; - - jr2 = jr; - jr += p->r + p->dr; + r += p->r + p->dr; if (i & 0x1) { - r += c->r + c->dr + c->jdr; - jr += c->r + c->dr; + r += c->r + c->dr; } - if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E != p->id) { + if (SCF_EDA_NPN == c->type && !(i & 0x1)) { p->sr = r2; p->pr = r2; - p->jsr = jr2; - p->jpr = jr2; } else { p->sr = r; p->pr = r; - p->jsr = jr; - p->jpr = jr; } - scf_loge("path: %d, i: %d, c%ldp%ld, sr: %lg, jsr: %lg\n", path->index, i, p->cid, p->id, p->sr, p->jsr); + scf_loge("path: %d, i: %d, c%ldp%ld, sr: %lg\n", path->index, i, p->cid, p->id, p->sr); } if (path->childs) { @@ -176,40 +142,28 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) if (!p1) return -EINVAL; - double pr; - double jpr; - - __ses_path_pr (f, path, k, j, NULL, &pr); - __ses_path_jpr(f, path, k, j, NULL, &jpr); + double pr = p1->pr - p0->pr; - ses_merge_r(&r, NULL, pr, 0, child->pr, 0); - ses_merge_r(&jr, NULL, jpr, 0, child->jpr, 0); + ses_merge_r(&r, NULL, pr, 0, child->pr, 0); - double dr = pr - r; - double jdr = jpr - jr; + double dr = pr - r; - p1->pr -= dr; - p1->jpr -= jdr; + p1->pr -= dr; - child->parent_pr = p1->pr; - child->parent_jpr = p1->jpr; + child->parent_pr = p1->pr; - scf_logi("j: %d, c%ldp%ld, p->pr: %lg, p->sr: %lg, pr: %lg, dr: %lg\n", j, p1->cid, p1->id, p1->pr, p1->sr, pr, dr); - scf_logi("j: %d, c%ldp%ld, p->jpr: %lg, p->jsr: %lg, jpr: %lg, jdr: %lg\n", j, p1->cid, p1->id, p1->jpr, p1->jsr, jpr, jdr); + scf_logi("j: %d, c%ldp%ld, p->pr: %lg, p->sr: %lg, pr: %lg, dr: %lg\n", j, p1->cid, p1->id, p1->pr, p1->sr, pr, dr); for (++j; j < path->pins->size; j++) { p = path->pins->data[j]; - p->pr -= dr; - p->sr -= dr; - p->jpr -= jdr; - p->jsr -= jdr; + p->pr -= dr; + p->sr -= dr; - scf_logd("j: %d, c%ldp%ld, p->pr: %lg, p->sr: %lg\n", j, p->cid, p->id, p->pr, p->sr); - scf_logd("j: %d, c%ldp%ld, p->jpr: %lg, p->jsr: %lg\n", j, p->cid, p->id, p->jpr, p->jsr); + scf_logi("j: %d, c%ldp%ld, p->pr: %lg, p->sr: %lg\n", j, p->cid, p->id, p->pr, p->sr); } - scf_logw("child: %d, pr: %lg, dr: %lg, jpr: %lg, jdr: %lg\n", child->index, child->pr, dr, child->jpr, jdr); + scf_logw("child: %d, pr: %lg, dr: %lg\n", child->index, child->pr, dr); } } @@ -224,20 +178,17 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) if (p->lid == cp1->lid) { child->parent_pr = p->pr; - child->parent_jpr = p->jpr; break; } } } } - p = path->pins->data[path->pins->size - 1]; - path->pr = p->pr; - path->sr = p->sr; - path->jpr = p->jpr; - path->jsr = p->jsr; + p = path->pins->data[path->pins->size - 1]; + path->pr = p->pr; + path->sr = p->sr; - scf_loge("path: %d, pr: %lg, sr: %lg, jpr: %lg, jsr: %lg\n\n", path->index, path->pr, path->sr, path->jpr, path->jsr); + scf_loge("path: %d, pr: %lg, sr: %lg\n\n", path->index, path->pr, path->sr); return 0; } diff --git a/ses_step_open.c b/ses_step_open.c index d0e611e..a0a9ae4 100644 --- a/ses_step_open.c +++ b/ses_step_open.c @@ -167,20 +167,18 @@ static int _open_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* if (el->flags & (SCF_EDA_PIN_IN | SCF_EDA_PIN_POS | SCF_EDA_PIN_NEG)) continue; - if (el->v > SCF_EDA_V_MIN) - continue; - if (__ses_path_pos(f, el)) { - if (!__ses_path_neg(f, el)) + if (!__ses_path_neg(f, el)) { el->v = Bp->v; - } else if (__ses_path_neg(f, el)) + scf_logw("e%ld->v: %lg\n", el->id, el->v); + } + } else if (__ses_path_neg(f, el)) { el->v = Bn->v; - else - return -EINVAL; - scf_logw("e%ld->v: %lg\n", el->id, el->v); + scf_logw("e%ld->v: %lg\n", el->id, el->v); + } } printf("\n"); diff --git a/ses_step_simplify.c b/ses_step_simplify.c index a9be82d..0352d1c 100644 --- a/ses_step_simplify.c +++ b/ses_step_simplify.c @@ -1,6 +1,90 @@ #include #include"ses_core.h" +static void ses_text_cda(cairo_t* cr, int x, int y, double a) +{ + char text[64]; + + cairo_set_source_rgb(cr, 0.0, 0.7, 0.0); + + if (a > 1e-1 || a < -1e-1) { + snprintf(text, sizeof(text) - 1, "%lgA", (int)(a * 1000) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + + } else if (a > 1e-5 || a < -1e-5) { + snprintf(text, sizeof(text) - 1, "%lgmA", (int)(a * 1000000) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + + } else { + snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000000LL) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + } +} + +static void ses_text_a(cairo_t* cr, int x, int y, double a) +{ + char text[64]; + + if (a > 0) + cairo_set_source_rgb(cr, 0.7, 0.0, 0.0); + else + cairo_set_source_rgb(cr, 0.0, 0.0, 0.7); + + if (a > 1e-1 || a < -1e-1) { + snprintf(text, sizeof(text) - 1, "%lgA", (int)(a * 1000) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + + } else if (a > 1e-5 || a < -1e-5) { + snprintf(text, sizeof(text) - 1, "%lgmA", (int)(a * 1000000) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + + } else if (a > 1e-9 || a < -1e-9) { + snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000000LL) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + } +} + +static void ses_text_v(cairo_t* cr, int x, int y, double v) +{ + char text[64]; + + if (v > 0) + cairo_set_source_rgb(cr, 0.7, 0.0, 0.0); + else + cairo_set_source_rgb(cr, 0.0, 0.0, 0.7); + + if (v > 1e-1 || v < -1e-1) { + snprintf(text, sizeof(text) - 1, "%lgv", (int)(v * 1000) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + + } else if (v > 1e-5 || v < -1e-5) { + snprintf(text, sizeof(text) - 1, "%lgmV", (int)(v * 1000000) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + + } else if (v > 1e-9 || v < -1e-9) { + snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(v * 1000000000LL) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + } +} + void __ses_function_draw(ScfEfunction* f, cairo_t* cr) { ScfEcomponent* c; @@ -132,24 +216,10 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) cairo_line_to(cr, p->x, p->y); cairo_stroke(cr); - if (c->v > 0) - cairo_set_source_rgb(cr, 0.7, 0.0, 0.0); - else - cairo_set_source_rgb(cr, 0.0, 0.0, 0.7); cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - if (c->v > 1e-3 || c->v < -1e-3) { - snprintf(text, sizeof(text) - 1, "%lgv", (int)(c->v * 1000) / 1000.0); - - cairo_move_to (cr, c->x + 10, c->y + 10); - cairo_show_text(cr, text); - - } else if (c->v > 1e-6 || c->v < -1e-6) { - snprintf(text, sizeof(text) - 1, "%lgmV", (int)(c->v * 1000000) / 1000.0); - - cairo_move_to (cr, c->x + 10, c->y + 10); - cairo_show_text(cr, text); - } + 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); @@ -163,14 +233,22 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) case SCF_EDA_Resistor: p = c->pins[0]; - vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 3); - forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 6); + vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 6); + forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 12); - cairo_move_to (cr, p->x, p->y); - cairo_line_to (cr, c->x - dx1, c->y - dy1); + cairo_move_to(cr, p->x, p->y); + cairo_line_to(cr, c->x - dx1, c->y - dy1); + cairo_stroke(cr); - cairo_rel_move_to(cr, dx0, dy0); + cairo_set_source_rgb(cr, 0.0, 0.0, 0.8); + + cairo_move_to (cr, c->x - dx1 + dx0, c->y - dy1 + dy0); cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); + cairo_stroke(cr); + + cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); + + cairo_move_to (cr, c->x - dx1 - dx0, c->y - dy1 - dy0); cairo_rel_line_to(cr, dx1 * 2, dy1 * 2); cairo_rel_line_to(cr, dx0 * 2, dy0 * 2); cairo_rel_line_to(cr, -dx1 * 2, -dy1 * 2); @@ -180,14 +258,16 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) cairo_line_to (cr, c->x + dx1, c->y + dy1); cairo_stroke(cr); + cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + + 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->r > 1e6) snprintf(text, sizeof(text) - 1, "%dM", (int)(c->r / 1000000.0)); else snprintf(text, sizeof(text) - 1, "%dk", (int)(c->r / 1000.0)); - cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); - cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - cairo_move_to (cr, c->x + 4, c->y - 5); cairo_show_text(cr, text); cairo_stroke(cr); @@ -214,6 +294,7 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) cairo_rel_move_to(cr, dx0, dy0); cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); + ses_text_a(cr, c->x + 10, c->y + 25, c->a); cairo_stroke(cr); break; @@ -270,6 +351,12 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) 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); + ses_text_a(cr, c->x, (pe->y + c->y) / 2, pe->a); + cairo_stroke(cr); break; default: break; @@ -277,7 +364,7 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) } } -static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh, int64_t count) +int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh) { ScfEcomponent* B; ScfEcomponent* c; @@ -330,8 +417,6 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw else cairo_set_source_rgb(cr, 1, 0.5, 0.1); - cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - uint8_t text[64]; ScfLine* prev = NULL; @@ -342,25 +427,49 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw continue; if (!prev) { + if (el->vconst) + cairo_select_font_face(cr, "Calibri", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + else + cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + cairo_set_font_size(cr, 28); + int n = snprintf(text, sizeof(text) - 1, "%ld", el->id); cairo_move_to (cr, l->x0 - 10 - n * 12, l->y0 + 10); cairo_show_text(cr, text); cairo_stroke(cr); + // V of line if (el->v < SCF_EDA_V_MIN) - snprintf(text, sizeof(text) - 1, "0v"); + n = snprintf(text, sizeof(text) - 1, "0v"); else if (el->v > SCF_EDA_V_MAX) - snprintf(text, sizeof(text) - 1, "%lgv", B->pins[SCF_EDA_Battery_POS]->v); + n = snprintf(text, sizeof(text) - 1, "%lgv", B->pins[SCF_EDA_Battery_POS]->v); + + else if (el->v > 1e-2 || el->v < -1e-2) + n = snprintf(text, sizeof(text) - 1, "%lgv", (int)(el->v * 1000) / 1000.0); + + else if (el->v > 1e-5 || el->v < -1e-5) + n = snprintf(text, sizeof(text) - 1, "%lgmV", (int)(el->v * 1000000) / 1000.0); + else + n = snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(el->v * 1000000000LL) / 1000.0); + + // A of line + if (el->aout > 1e-1 || el->aout < -1e-1) + n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgA", (int)(el->aout * 1000) / 1000.0); - else if (el->v > 1e-3 || el->v < -1e-3) - snprintf(text, sizeof(text) - 1, "%lgv", (int)(el->v * 1000) / 1000.0); + else if (el->aout > 1e-5 || el->aout < -1e-5) + n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgmA", (int)(el->aout * 1000000) / 1000.0); + else + n += snprintf(text + n, sizeof(text) - 1 - n, ", %lguA", (int64_t)(el->aout * 1000000000LL) / 1000.0); + + if (el->ain > 1e-1 || el->ain < -1e-1) + n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgA", (int)(el->ain * 1000) / 1000.0); - else if (el->v > 1e-6 || el->v < -1e-6) - snprintf(text, sizeof(text) - 1, "%lgmV", (int)(el->v * 1000000) / 1000.0); + else if (el->ain > 1e-5 || el->ain < -1e-5) + n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgmA", (int)(el->ain * 1000000) / 1000.0); else - snprintf(text, sizeof(text) - 1, "%lguV", (int)(el->v * 1000000) / 1000000.0); + n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lguA", (int64_t)(el->ain * 1000000000LL) / 1000.0); int cx = INT_MAX; int cy = l->y0; @@ -374,14 +483,17 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw } } + if (INT_MAX == cx) + cx = l->x0; + cairo_set_font_size(cr, 20); if (cy > l->y0) { - cairo_move_to (cr, cx - 20, l->y0 - 8); + cairo_move_to (cr, cx - 40, l->y0 - 8); cairo_show_text(cr, text); cairo_stroke(cr); } else { - cairo_move_to (cr, cx - 20, l->y0 + 24); + cairo_move_to (cr, cx - 40, l->y0 + 24); cairo_show_text(cr, text); cairo_stroke(cr); } @@ -407,9 +519,6 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw __ses_function_draw(f, cr); - char file[128]; - snprintf(file, sizeof(file) - 1, "./simplify_%ld.png", count); - cairo_surface_write_to_png(surface, file); cairo_destroy(cr); @@ -419,7 +528,27 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw static int _simplify_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) { - _simplify_draw(f, f->x, f->y, f->w, f->h, count); + ScfEline* el; + + int i; +#if 0 + for (i = 0; i < f->n_elines; i++) { + el = f->elines[i]; + + if (el->flags & SCF_EDA_PIN_OUT) { + if (el->v < 1) + return 0; + else + break; + } + } +#endif + + char file[128]; + snprintf(file, sizeof(file) - 1, "./simplify_%ld.png", count); + + if (count % 100 < 5) + ses_simplify_draw(f, file, f->x, f->y, f->w, f->h); return 0; } diff --git a/ses_step_simplify2.c b/ses_step_simplify2.c new file mode 100644 index 0000000..afdc666 --- /dev/null +++ b/ses_step_simplify2.c @@ -0,0 +1,551 @@ +#include +#include"ses_core.h" + +static void ses_text_cda(cairo_t* cr, int x, int y, double a) +{ + char text[64]; + + cairo_set_source_rgb(cr, 0.0, 0.7, 0.0); + + if (a > 1e-1 || a < -1e-1) { + snprintf(text, sizeof(text) - 1, "%lgA", (int)(a * 1000) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + + } else if (a > 1e-5 || a < -1e-5) { + snprintf(text, sizeof(text) - 1, "%lgmA", (int)(a * 1000000) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + + } else { + snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000000LL) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + } +} + +static void ses_text_a(cairo_t* cr, int x, int y, double a) +{ + char text[64]; + + if (a > 0) + cairo_set_source_rgb(cr, 0.7, 0.0, 0.0); + else + cairo_set_source_rgb(cr, 0.0, 0.0, 0.7); + + if (a > 1e-1 || a < -1e-1) { + snprintf(text, sizeof(text) - 1, "%lgA", (int)(a * 1000) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + + } else if (a > 1e-5 || a < -1e-5) { + snprintf(text, sizeof(text) - 1, "%lgmA", (int)(a * 1000000) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + + } else if (a > 1e-9 || a < -1e-9) { + snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000000LL) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + } +} + +static void ses_text_v(cairo_t* cr, int x, int y, double v) +{ + char text[64]; + + if (v > 0) + cairo_set_source_rgb(cr, 0.7, 0.0, 0.0); + else + cairo_set_source_rgb(cr, 0.0, 0.0, 0.7); + + if (v > 1e-1 || v < -1e-1) { + snprintf(text, sizeof(text) - 1, "%lgv", (int)(v * 1000) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + + } else if (v > 1e-5 || v < -1e-5) { + snprintf(text, sizeof(text) - 1, "%lgmV", (int)(v * 1000000) / 1000.0); + + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + } +} + +static void __ses_function_draw(ScfEfunction* f, cairo_t* cr) +{ + ScfEcomponent* c; + ScfEpin* p; + ScfEpin* pb; + ScfEpin* pc; + ScfEpin* pe; + + size_t j; + size_t k; + + for (j = 0; j < f->n_components; j++) { + c = f->components[j]; + + cairo_set_line_width(cr, 2.5); + + uint8_t text[64]; + int n = snprintf(text, sizeof(text) - 1, "%ld", c->id); + + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_select_font_face(cr, "Calibri", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + cairo_set_font_size (cr, 20); + cairo_move_to (cr, c->x - 10 - n * 10, c->y - 5); + cairo_show_text (cr, text); + cairo_stroke(cr); + + if ((SCF_EDA_Diode == c->type || SCF_EDA_NPN == c->type) && SCF_EDA_Status_OFF == c->status) + cairo_set_source_rgb(cr, 0.0, 0.6, 0.6); + else + cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); + + for (k = 0; k < c->n_pins; k++) { + p = c->pins[k]; + + cairo_arc (cr, p->x, p->y, 4, 0, 2 * M_PI); + cairo_fill(cr); + } + cairo_stroke(cr); + + int dx0; + int dy0; + + int dx1; + int dy1; + int dx2; + int dy2; + + int dx3; + int dy3; + int dx4; + int dy4; + + switch (c->type) { + + case SCF_EDA_Battery: + p = c->pins[SCF_EDA_Battery_POS]; + + if (p->y < c->y) { + cairo_move_to(cr, c->x - 12, c->y - 5); + cairo_line_to(cr, c->x + 12, c->y - 5); + + cairo_move_to(cr, c->x, c->y - 5); + cairo_line_to(cr, p->x, p->y); + + cairo_move_to(cr, c->x - 8, c->y + 5); + cairo_line_to(cr, c->x + 8, c->y + 5); + + p = c->pins[SCF_EDA_Battery_NEG]; + cairo_move_to(cr, c->x, c->y + 5); + cairo_line_to(cr, p->x, p->y); + + } else { + cairo_move_to(cr, c->x - 12, c->y + 5); + cairo_line_to(cr, c->x + 12, c->y + 5); + + cairo_move_to(cr, c->x, c->y + 5); + cairo_line_to(cr, p->x, p->y); + + cairo_move_to(cr, c->x - 8, c->y - 5); + cairo_line_to(cr, c->x + 8, c->y - 5); + + p = c->pins[SCF_EDA_Battery_NEG]; + cairo_move_to(cr, c->x, c->y - 5); + cairo_line_to(cr, p->x, p->y); + } + + cairo_stroke(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); + cairo_line_to(cr, c->x + 8, c->y - 5); + cairo_stroke(cr); + + cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); + cairo_move_to(cr, c->x, c->y - 5); + } else { + cairo_move_to(cr, c->x - 8, c->y + 5); + cairo_line_to(cr, c->x + 8, c->y + 5); + cairo_stroke(cr); + + cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); + cairo_move_to(cr, c->x, c->y + 5); + } + cairo_line_to(cr, p->x, p->y); + cairo_stroke(cr); + + cairo_set_source_rgb(cr, 0.0, 0.0, 0.8); + p = c->pins[SCF_EDA_Battery_NEG]; + if (p->y < c->y) { + cairo_move_to(cr, c->x - 8, c->y - 5); + cairo_line_to(cr, c->x + 8, c->y - 5); + cairo_stroke(cr); + + cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); + cairo_move_to(cr, c->x, c->y - 5); + } else { + cairo_move_to(cr, c->x - 8, c->y + 5); + cairo_line_to(cr, c->x + 8, c->y + 5); + cairo_stroke(cr); + + cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); + cairo_move_to(cr, c->x, c->y + 5); + } + cairo_line_to(cr, p->x, p->y); + 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); + + 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_Resistor: + p = c->pins[0]; + + vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 6); + forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 12); + + cairo_move_to(cr, p->x, p->y); + cairo_line_to(cr, c->x - dx1, c->y - dy1); + cairo_stroke(cr); + + cairo_set_source_rgb(cr, 0.0, 0.0, 0.8); + + cairo_move_to (cr, c->x - dx1 + dx0, c->y - dy1 + dy0); + cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); + cairo_stroke(cr); + + cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); + + cairo_move_to (cr, c->x - dx1 - dx0, c->y - dy1 - dy0); + cairo_rel_line_to(cr, dx1 * 2, dy1 * 2); + cairo_rel_line_to(cr, dx0 * 2, dy0 * 2); + cairo_rel_line_to(cr, -dx1 * 2, -dy1 * 2); + + p = c->pins[1]; + cairo_move_to (cr, p->x, p->y); + cairo_line_to (cr, c->x + dx1, c->y + dy1); + cairo_stroke(cr); + + cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + + 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->r > 1e6) + snprintf(text, sizeof(text) - 1, "%dM", (int)(c->r / 1000000.0)); + else + snprintf(text, sizeof(text) - 1, "%dk", (int)(c->r / 1000.0)); + + cairo_move_to (cr, c->x + 4, c->y - 5); + cairo_show_text(cr, text); + cairo_stroke(cr); + break; + + case SCF_EDA_Diode: + p = c->pins[SCF_EDA_Diode_POS]; + + vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 6); + forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 6); + + cairo_move_to(cr, p->x, p->y); + cairo_line_to(cr, c->x - dx1, c->y - dy1); + + cairo_rel_move_to(cr, dx0, dy0); + cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); + cairo_line_to (cr, c->x + dx1, c->y + dy1); + cairo_line_to (cr, c->x + dx0 - dx1, c->y + dy0 - dy1); + + p = c->pins[SCF_EDA_Diode_NEG]; + + cairo_move_to (cr, p->x, p->y); + cairo_line_to (cr, c->x + dx1, c->y + dy1); + cairo_rel_move_to(cr, dx0, dy0); + cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); + + ses_text_a(cr, c->x + 10, c->y + 25, c->a); + cairo_stroke(cr); + break; + + case SCF_EDA_NPN: + pb = c->pins[SCF_EDA_NPN_B]; + pc = c->pins[SCF_EDA_NPN_C]; + pe = c->pins[SCF_EDA_NPN_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, 3); + forward (&dx4, &dy4, dx3 * 2 + dx0, dy3 * 2 + dy0, 8); + + cairo_move_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1); + cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); + 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, 3); + forward (&dx4, &dy4, dx3 * 2 - dx0, dy3 * 2 - dy0, 8); + + cairo_move_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1); + cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); + 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); + ses_text_a(cr, c->x, (pe->y + c->y) / 2, pe->a); + cairo_stroke(cr); + break; + default: + break; + }; + } +} + +static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh, int64_t count) +{ + ScfEcomponent* B; + ScfEcomponent* c; + ScfEline* el; + ScfLine* l; + + cairo_surface_t* surface; + cairo_t* cr; + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, bx + bw, by + bh); + cr = cairo_create (surface); + + cairo_set_line_width(cr, 2); + cairo_set_source_rgb(cr, 1, 1, 1); + cairo_rectangle (cr, 0, 0, bx + bw, by + bh); + cairo_fill(cr); + cairo_stroke(cr); + + long i; + long j; + long k; + + B = f->components[0]; + + for (j = 0; j < f->n_elines; j++) { + el = f->elines[j]; + + cairo_set_line_width(cr, 2); + + if (SCF_EDA_PIN_POS & el->flags) + cairo_set_source_rgb(cr, 1, 0, 0); + + else if (SCF_EDA_PIN_NEG & el->flags) + cairo_set_source_rgb(cr, 0, 0, 1); + + else if (SCF_EDA_PIN_OUT & el->flags) + cairo_set_source_rgb(cr, 1, 0, 1); + + else if (el->v == B->pins[SCF_EDA_Battery_POS]->v) + cairo_set_source_rgb(cr, 0.8, 0, 0); + + else if (el->v == B->pins[SCF_EDA_Battery_NEG]->v) + cairo_set_source_rgb(cr, 0, 0, 0.8); + + else if (SCF_EDA_PIN_IN & el->flags) + cairo_set_source_rgb(cr, 0, 1, 0); + + else if (SCF_EDA_PIN_CF & el->flags) + cairo_set_source_rgb(cr, 0.8, 0, 1.0); + else + cairo_set_source_rgb(cr, 1, 0.5, 0.1); + + uint8_t text[64]; + ScfLine* prev = NULL; + + for (k = 0; k < el->n_lines; k++) { + l = el->lines[k]; + + if (l->x0 > l->x1) + continue; + + if (!prev) { + if (el->vconst) + cairo_select_font_face(cr, "Calibri", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + else + cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + + cairo_set_font_size(cr, 28); + + int n = snprintf(text, sizeof(text) - 1, "%ld", el->id); + + cairo_move_to (cr, l->x0 - 10 - n * 12, l->y0 + 10); + cairo_show_text(cr, text); + cairo_stroke(cr); + + // V of line + if (el->v < SCF_EDA_V_MIN) + n = snprintf(text, sizeof(text) - 1, "0v"); + else if (el->v > SCF_EDA_V_MAX) + n = snprintf(text, sizeof(text) - 1, "%lgv", B->pins[SCF_EDA_Battery_POS]->v); + + else if (el->v > 1e-2 || el->v < -1e-2) + n = snprintf(text, sizeof(text) - 1, "%lgv", (int)(el->v * 1000) / 1000.0); + + else if (el->v > 1e-5 || el->v < -1e-5) + n = snprintf(text, sizeof(text) - 1, "%lgmV", (int)(el->v * 1000000) / 1000.0); + else + n = snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(el->v * 1000000000LL) / 1000.0); + + // A of line + if (el->aout > 1e-1 || el->aout < -1e-1) + n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgA", (int)(el->aout * 1000) / 1000.0); + + else if (el->aout > 1e-5 || el->aout < -1e-5) + n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgmA", (int)(el->aout * 1000000) / 1000.0); + else + n += snprintf(text + n, sizeof(text) - 1 - n, ", %lguA", (int64_t)(el->aout * 1000000000LL) / 1000.0); + + if (el->ain > 1e-1 || el->ain < -1e-1) + n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgA", (int)(el->ain * 1000) / 1000.0); + + else if (el->ain > 1e-5 || el->ain < -1e-5) + n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgmA", (int)(el->ain * 1000000) / 1000.0); + else + n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lguA", (int64_t)(el->ain * 1000000000LL) / 1000.0); + + int cx = INT_MAX; + int cy = l->y0; + + for (i = 0; i < el->n_pins; i += 2) { + c = f->components[el->pins[i]]; + + if (c->x > l->x0 && c->x < cx) { + cx = c->x; + cy = c->y; + } + } + + cairo_set_font_size(cr, 20); + + if (cy > l->y0) { + cairo_move_to (cr, cx - 40, l->y0 - 8); + cairo_show_text(cr, text); + cairo_stroke(cr); + } else { + cairo_move_to (cr, cx - 40, l->y0 + 24); + cairo_show_text(cr, text); + cairo_stroke(cr); + } + } + + cairo_set_line_width(cr, 4); + cairo_move_to(cr, l->x0, l->y0); + cairo_line_to(cr, l->x1, l->y1); + cairo_stroke(cr); + + if (prev) { + if (!(el->flags & SCF_EDA_PIN_BORDER)) + cairo_set_line_width(cr, 1); + + cairo_move_to(cr, prev->x0, prev->y0); + cairo_line_to(cr, l->x0, l->y0); + cairo_stroke(cr); + } + + prev = l; + } + } + + __ses_function_draw(f, cr); + + char file[128]; + snprintf(file, sizeof(file) - 1, "./simplify2_%ld.png", count); + + cairo_surface_write_to_png(surface, file); + + cairo_destroy(cr); + cairo_surface_destroy(surface); + return 0; +} + +static int _simplify_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) +{ + ScfEline* el; + + int i; +#if 0 + for (i = 0; i < f->n_elines; i++) { + el = f->elines[i]; + + if (el->flags & SCF_EDA_PIN_OUT) { + if (el->v < 1) + return 0; + else + break; + } + } +#endif + +// if (count % 5000 == 0) + _simplify_draw(f, f->x, f->y, f->w, f->h, count); + return 0; +} + +ses_step_t ses_step_simplify2 = +{ + .name = "simplify2", + + .handler = _simplify_handler, +}; diff --git a/ses_step_status.c b/ses_step_status.c new file mode 100644 index 0000000..01ee0f9 --- /dev/null +++ b/ses_step_status.c @@ -0,0 +1,129 @@ +#include"ses_core.h" + +int __ses_path_status(ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns, int64_t count) +{ + ScfEcomponent* B; + ScfEline* el; + ScfEpin* Bp; + ScfEpin* Bn; + ScfEpin* p0; + ScfEpin* p1; + + B = f->components[0]; + Bp = B->pins[SCF_EDA_Battery_POS]; + Bn = B->pins[SCF_EDA_Battery_NEG]; + + p0 = bridge->pins->data[0]; + p1 = bridge->pins->data[bridge->pins->size - 1]; + + if (p0->lid == Bp->lid && p1->lid == Bn->lid) + return 0; + + el = f->elines[p0->lid]; + p0->v = el->v; + + el = f->elines[p1->lid]; + p1->v = el->v; + + if (p0->v < SCF_EDA_V_MIN || p1->v < SCF_EDA_V_MIN) + return 0; + + int __changed = 0; + + __ses_path_jr(f, bridge); + + if (bridge->n_diodes + bridge->n_NPNs > 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; + + *changed += __changed; + + scf_loge("bridge: %d, c%ldp%ld--c%ldp%ld, __changed: %d, p0->v: %lg, p1->v: %lg, n_diodes: %d, n_NPNs: %d, p0->a: %lg, p1->a: %lg\n\n", + bridge->index, p0->cid, p0->id, p1->cid, p1->id, __changed, p0->v, p1->v, bridge->n_diodes, bridge->n_NPNs, p0->a, p1->a); + + bridge->vflag = 0; + return 0; +} + +static int ses_path_status(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths, int64_t ns, int64_t count) +{ + ses_path_t* child; + + int ret; + int j; + + if (!path) + return -EINVAL; + + if (0 == path->n_capacitors) { + + ret = __ses_path_status(f, path, changed, paths, ns, count); + if (ret < 0) + return ret; + } + + if (path->bridges) { + scf_vector_t* vec = scf_vector_alloc(); + if (!vec) + return -ENOMEM; + + ret = scf_vector_add(vec, path); + if (ret < 0) { + scf_vector_free(vec); + return ret; + } + + for (j = 0; j < path->bridges->size; j++) { + child = path->bridges->data[j]; + + ret = ses_path_status(f, child, changed, vec, ns, count); + if (ret < 0) { + scf_vector_free(vec); + return ret; + } + } + + scf_vector_free(vec); + vec = NULL; + } + + return 0; +} + +static int _status_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) +{ + ses_path_t* path; + + int changed = 0; + 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_status(f, path, &changed, ctx->paths, ns, count); + if (ret < 0) + return ret; + } + + ctx->changed += changed; + return 0; +} + +ses_step_t ses_step_status = +{ + .name = "status", + + .handler = _status_handler, +}; diff --git a/ses_step_topo.c b/ses_step_topo.c index ca44eab..c4faecc 100644 --- a/ses_step_topo.c +++ b/ses_step_topo.c @@ -1,11 +1,12 @@ #include"ses_core.h" -int __dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __paths, ses_path_t** ppath) +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; @@ -68,21 +69,19 @@ int __dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __ if (SCF_EDA_NPN != rc->type || SCF_EDA_NPN_E != np->id) np->vflag = 1; - if ((SCF_EDA_PIN_NEG & el->flags) || SCF_EDA_Capacitor == rc->type) { + if (SCF_EDA_PIN_NEG & el->flags) { if (scf_vector_add(__paths, *ppath) < 0) return -ENOMEM; for (j = 0; j < (*ppath)->pins->size; j++) { - p = (*ppath)->pins->data[j]; - p->pflag = 1; - p->path = (uintptr_t)*ppath; + p2 = (*ppath)->pins->data[j]; + p2->pflag = 1; + p2->path = (uintptr_t)*ppath; } *ppath = NULL; - - if (SCF_EDA_PIN_NEG & el->flags) - return 0; + return 0; } ret = 0; @@ -101,9 +100,9 @@ int __dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __ return -ENOMEM; for (k = 0; k < (*ppath)->pins->size; k++) { - p = (*ppath)->pins->data[k]; - p->pflag = 1; - p->path = (uintptr_t)*ppath; + p2 = (*ppath)->pins->data[k]; + p2->pflag = 1; + p2->path = (uintptr_t)*ppath; } } else ses_path_free(*ppath); @@ -116,10 +115,25 @@ int __dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __ if (p->vflag) continue; + if (SCF_EDA_Capacitor == rc->type && SCF_EDA_Capacitor != c->type) { + if (*ppath) { + 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; + } + + *ppath = NULL; + } + } + if (SCF_EDA_NPN != c->type || SCF_EDA_NPN_E != p->id) p->vflag = 1; - ret = __dfs_path(f, c, p, __paths, ppath); + ret = __ses_dfs_path(f, c, p, __paths, ppath); if (ret < 0) return ret; @@ -154,6 +168,34 @@ int __dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __ return ret; } +static int ses_pin_to_npn(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_NPN == 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]; + const ScfEpin* p1 = path->pins->data[path->pins->size - 1]; + + 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; @@ -224,6 +266,7 @@ static int __topo_path_bridges(ScfEfunction* f, ses_path_t* path) continue; } + // positive pin of path p0 = sp0->pins->data[0]; p1 = sp1->pins->data[0]; @@ -250,6 +293,47 @@ static int __topo_path_bridges(ScfEfunction* f, ses_path_t* path) || (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_B == p1->id)) goto bridge_sp0; + if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_B)) + goto bridge_sp1; + if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_B)) + goto bridge_sp0; + + if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_C)) + goto bridge_sp1; + if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_C)) + goto bridge_sp0; + + // negative pin of path + p0 = sp0->pins->data[sp0->pins->size - 1]; + p1 = sp1->pins->data[sp1->pins->size - 1]; + + if (SCF_EDA_PIN_IN & p0->flags) + goto bridge_sp1; + + if (SCF_EDA_PIN_IN & p1->flags) + goto bridge_sp0; + + if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_B)) + goto bridge_sp1; + if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_B)) + goto bridge_sp0; + + if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_C)) + goto bridge_sp1; + if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_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)) + 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)) + goto bridge_sp0; + bridge_sp1: scf_vector_del(path->childs, sp1); if (scf_vector_add(path->bridges, sp1) < 0) @@ -298,33 +382,6 @@ static int _topo_path_bridges(ScfEfunction* f, ses_path_t* path) return __topo_path_bridges(f, path); } -static int ses_pin_to_npn(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_NPN == 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]; - const ScfEpin* p1 = path->pins->data[path->pins->size - 1]; - - return ses_pin_to_npn(f, p0, pid) || ses_pin_to_npn(f, p1, pid); -} - static int _ses_connect_cmp(const void* v0, const void* v1, void* arg) { const ScfEfunction* f = arg; @@ -332,9 +389,21 @@ static int _ses_connect_cmp(const void* v0, const void* v1, void* arg) const ses_path_t* p0 = *(const ses_path_t**)v0; const ses_path_t* p1 = *(const ses_path_t**)v1; - if (0 == p0->n_capacitors) + if (0 == p0->n_capacitors) { + if (0 == p1->n_capacitors) { + + if (ses_path_to_npn(f, p0, SCF_EDA_NPN_B)) + return -1; + if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B)) + return 1; + + if (ses_path_to_npn(f, p0, SCF_EDA_NPN_C)) + return -1; + if (ses_path_to_npn(f, p1, SCF_EDA_NPN_C)) + return 1; + } return -1; - if (0 == p1->n_capacitors) + } else if (0 == p1->n_capacitors) return 1; if (ses_path_to_npn(f, p0, SCF_EDA_NPN_C)) @@ -343,13 +412,13 @@ static int _ses_connect_cmp(const void* v0, const void* v1, void* arg) return 1; if (ses_path_to_npn(f, p0, SCF_EDA_NPN_B)) - return -1; - if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B)) return 1; - - if (p0->n_capacitors < p1->n_capacitors) + if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B)) return -1; + if (p0->n_capacitors > p1->n_capacitors) + return -1; + if (p0->n_capacitors < p1->n_capacitors) return 1; return 0; } @@ -418,7 +487,7 @@ static int _topo_path_connect(ScfEfunction* f, scf_vector_t* paths) } else if (p3->lid == p1->lid) { - if (path0->n_diodes > 0 || path0->n_transistors > 0) + if (path0->n_diodes + path0->n_NPNs > 0 || path0->n_transistors > 0) continue; for (k = path0->pins->size - 1; k >= 0; k--) { @@ -442,7 +511,7 @@ static int _topo_path_connect(ScfEfunction* f, scf_vector_t* paths) } else if (p2->lid == p0->lid) { - if (path0->n_diodes > 0 || path0->n_transistors > 0) + if (path0->n_diodes + path0->n_NPNs > 0 || path0->n_transistors > 0) continue; m = path0->pins->size - 1; @@ -485,6 +554,51 @@ error: return -ENOMEM; } +static int _topo_fix_complete(scf_vector_t* paths, ses_path_t* parent) +{ + ses_path_t* child; + + int i; + + if (parent->childs) { + + for (i = 0; i < parent->childs->size; ) { + child = parent->childs->data[i]; + + if (ses_path_is_child(parent, child)) + i++; + else { + int ret = scf_vector_add(paths, child); + if (ret < 0) + return ret; + + assert(0 == scf_vector_del(parent->childs, child)); + child->parent = NULL; + } + } + } + + if (parent->bridges) { + + for (i = 0; i < parent->bridges->size; ) { + child = parent->bridges->data[i]; + + if (ses_path_is_child(parent, child)) + i++; + else { + int ret = scf_vector_add(paths, child); + if (ret < 0) + return ret; + + assert(0 == scf_vector_del(parent->bridges, child)); + child->parent = NULL; + } + } + } + + return 0; +} + static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths) { if (!f || !paths) @@ -555,6 +669,14 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths) if (ret < 0) return ret; + ret = _topo_fix_complete(paths, path1); + if (ret < 0) + return ret; + + ret = _topo_fix_complete(paths, path0); + if (ret < 0) + return ret; + if (path0->pins->size <= 0) { if (scf_vector_del(paths, path0) < 0) return -1; @@ -581,6 +703,14 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths) if (ret < 0) return ret; + ret = _topo_fix_complete(paths, path1); + if (ret < 0) + return ret; + + ret = _topo_fix_complete(paths, path0); + if (ret < 0) + return ret; + if (path0->pins->size <= 0) { if (scf_vector_del(paths, path0) < 0) return -1; @@ -636,6 +766,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; for (i = 0; i < path->pins->size; i++) { p = path->pins->data[i]; @@ -676,7 +807,7 @@ static int __topo_path_key_infos(ScfEfunction* f, ses_path_t* path) } info->n_NPNs++; - path->n_diodes++; + path->n_NPNs++; continue; } else if (SCF_EDA_NPN_E == p->id) { @@ -850,9 +981,9 @@ static int topo_epin_cmp(const void* v0, const void* v1, void* arg) return 1; if (SCF_EDA_Capacitor == c0->type) - return 1; - if (SCF_EDA_Capacitor == c1->type) return -1; + if (SCF_EDA_Capacitor == c1->type) + return 1; return 0; } @@ -864,7 +995,8 @@ static void _topo_key_components(ScfEfunction* f, ses_path_t* path) int i; - path->n_diodes = 0; + path->n_NPNs = 0; + path->n_diodes = 0; path->n_capacitors = 0; for (i = 0; i < path->pins->size; i++) { @@ -880,7 +1012,7 @@ static void _topo_key_components(ScfEfunction* f, ses_path_t* path) } else if (SCF_EDA_NPN == c->type) { if (SCF_EDA_NPN_B == p->id) - path->n_diodes++; + path->n_NPNs++; else if (SCF_EDA_NPN_C == p->id) path->n_transistors++; @@ -921,6 +1053,8 @@ static void _topo_clear(ScfEfunction* f) for (i = 0; i < f->n_elines; i++) { el = f->elines[i]; + el->ain = 0; + el->aout = 0; el->vflag = 0; qsort_r(el->pins, el->n_pins / 2, sizeof(uint64_t) * 2, topo_epin_cmp, f); @@ -930,13 +1064,14 @@ static void _topo_clear(ScfEfunction* f) c = f->components[i]; c->vflag = 0; c->lock = 0; + c->a = 0; for (j = 0; j < c->n_pins; j++) { p = c->pins[j]; p->vflag = 0; p->pflag = 0; p->dr = 0; - p->jdr = 0; + p->a = 0; } } } @@ -964,7 +1099,7 @@ static int _topo_paths(ScfEfunction* f, ScfEline* el, scf_vector_t* paths) if (c == B) continue; - int ret = __dfs_path(f, c, p, paths, &path); + int ret = __ses_dfs_path(f, c, p, paths, &path); if (ret < 0) return ret; diff --git a/ses_step_va.c b/ses_step_va.c index 29d5518..8f5cbc2 100644 --- a/ses_step_va.c +++ b/ses_step_va.c @@ -1,6 +1,7 @@ #include"ses_core.h" -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) +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) { ses_path_t* child; @@ -36,67 +37,70 @@ static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, int n, d if (k > n) continue; - double r; + double sr = 0; + double cv = 0; + double dv = 0; + double da = 0; + double pr; double v; - if (path->n_capacitors > 0) { - __ses_path_jpr(f, path, i, k, child, &r); + __ses_path_pr(f, path, i, k, child, &pr); - ses_ir_u(&v, NULL, *a, 0, r, 0); + ses_ir_u(&v, NULL, *a, 0, pr, 0); - ses_ur_i(&child->a0, NULL, v, 0, child->jpr, 0); - } else { - __ses_path_pr(f, path, i, k, child, &r); + ses_ur_i(&child->a0, NULL, v, 0, child->pr, 0); - ses_ir_u(&v, NULL, *a, 0, r, 0); + if (__ses_path_capacitors(f, path, i, k, &cv) > 0) + v += cv; - ses_ur_i(&child->a0, NULL, v, 0, child->pr, 0); - } + 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), v: %lg, a: %lg, r: %lg\n", - child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id, child->n_diodes, v, *a, r); + 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", + 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); - *a -= child->a0; + *a -= child->a0; el = f->elines[p1->lid]; el->v = p0->v - v; - double _pr = p1->pr; - double _sr = p1->sr; - double _jpr = p1->jpr; - double _jsr = p1->jsr; + double _pr0 = p0->pr; + double _sr0 = p0->sr; + double _pr1 = p1->pr; + double _sr1 = p1->sr; - double _cpr = cp1->pr; - double _csr = cp1->sr; - double _cjpr = cp1->jpr; - double _cjsr = cp1->jsr; + double _cpr0 = cp0->pr; + double _csr0 = cp0->sr; + double _cpr1 = cp1->pr; + double _csr1 = cp1->sr; + cp0->pr = 0; + cp0->sr = 0; cp1->pr = child->pr; cp1->sr = child->sr; - cp1->jpr = child->jpr; - cp1->jsr = child->jsr; - if (child->n_diodes > 0) { + if (child->n_diodes + child->n_NPNs > 0) { __ses_path_va_diode(f, child); __ses_path_jr (f, child); } - int ret = __ses_path_va(f, child, 0, child->pins->size - 1, changed, ns, count); + int ret = __ses_path_va(f, child, changed, ns, count); if (ret < 0) return ret; - cp1->pr = _cpr; - cp1->sr = _csr; - cp1->jpr = _cjpr; - cp1->jsr = _cjsr; + cp0->pr = _cpr0; + cp0->sr = _csr0; + cp1->pr = _cpr1; + cp1->sr = _csr1; - p1->pr = _pr; - p1->sr = _sr; - p1->jpr = _jpr; - p1->jsr = _jsr; + p0->pr = _pr0; + p0->sr = _sr0; + 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\n\n", - child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id, child->n_diodes, p0->v, v, child->a0, child->a); + 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", + 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); n_childs++; } @@ -114,10 +118,7 @@ static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i, double v; double r; - if (path->n_capacitors > 0) - __ses_path_jsr(f, path, i0, i, &r); - else - __ses_path_sr(f, path, i0, i, &r); + __ses_path_sr(f, path, i0, i, &r); ses_ir_u(&v, NULL, a, 0, r, 0); @@ -141,13 +142,13 @@ int __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, doubl int k = 0; int i; - for (i = m; i <= n; i += 2) { + for (i = m; i <= n; i++) { p = path->pins->data[i]; c = f->components[p->cid]; - if (SCF_EDA_Capacitor == c->type) { - int sign = p->id - !p->id; + if (SCF_EDA_Capacitor == c->type && (i & 0x1)) { + int sign = !p->id - p->id; v += c->v * sign; k++; @@ -158,16 +159,19 @@ int __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, doubl return k; } -int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed, int64_t ns, int64_t count) +int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count) { if (!path) return -EINVAL; - if (path->pins->size < 2 || n - m < 1) { + if (path->pins->size < 2) { scf_loge("\n"); return -EINVAL; } + if (n - m < 1) + return 0; + ses_path_t* child; ScfEcomponent* c; ScfEcomponent* B = f->components[0]; @@ -186,34 +190,20 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed, p0 = path->pins->data[m]; p1 = path->pins->data[n]; - el = f->elines[p0->lid]; - p0->v = el->v; - - el = f->elines[p1->lid]; - p1->v = el->v; - - double pr = 0; double cv = 0; double a = 0; double v = p0->v - p1->v; - child = ses_path_find_child(path, m, n); - - if (path->n_capacitors > 0) { - __ses_path_capacitors(f, path, m, n, &cv); - v -= cv; - __ses_path_jpr(f, path, m, n, child, &pr); - } else { - __ses_path_pr(f, path, m, n, child, &pr); - } + __ses_path_capacitors(f, path, m, n, &cv); + v -= cv; 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, path->jpr: %lg, a: %lg\n\n", - path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, pr, path->pr, path->jpr, 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); double r = 0; double dv = 0; @@ -226,15 +216,20 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed, for (i = m; i <= n; i++) { p = path->pins->data[i]; + c = f->components[p->cid]; + scf_logd("c%ldp%ld, p->r: %lg, dr: %lg, sr: %lg, pr: %lg\n", p->cid, p->id, p->r, p->dr, p->sr, p->pr); __ses_path_split_v(f, path, i0, i, a); - p->v -= dv0 + dvc + dv1; + p->v -= dv0 + dvc; dv1 = 0; double tmp = p->v; + el = f->elines[p->lid]; + el->v = p->v; + if (!(i & 0x1) && path->childs) { int ret = __ses_path_split_a(f, path, i, n, &a, changed, ns, count); if (ret < 0) @@ -243,74 +238,44 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed, if (ret > 0) { p0 = p; i0 = i; - dv0 = p->v - tmp; - scf_logd("i: %d, p0: c%ldp%ld\n", i, p0->cid, p0->id); + dv0 = p->v - tmp - dvc; + + scf_logi("-------i: %d, p0: c%ldp%ld, dvc: %lg\n", i, p0->cid, p0->id, dvc); } } - el = f->elines[p->lid]; el->v = p->v; - r += p->r + p->dr + p->jdr; + r += p->r + p->dr; if (i & 0x1) { p2 = path->pins->data[i - 1]; - c = f->components[p->cid]; dv -= p->v; - r += c->r + c->dr + c->jdr; + r += c->r + c->dr; ses_ur_i(&p->a, NULL, dv, 0, r, 0); - if (SCF_EDA_Capacitor == c->type) { - int sign = !p->id - p->id; + int sign = !p->id - p->id; + if (SCF_EDA_Capacitor == c->type) { cv = c->v * sign; dv -= cv; - r -= c->jdr; ses_ur_i(&p->a, NULL, dv, 0, r, 0); - c->v += p->a * ns / 1e3 / c->uf * sign; - c->jdr = c->v / p->a * sign - c->r; +// c->v += p->a * sign * ns / 1e3 / c->uf; + c->a = p->a * sign; - if (p->a > 0 || p->lid == Bn->lid) { - tmp = p2->v; - p2->v = p->v + c->v * sign; - - if (p0 == p2) - dv0 = p2->v - tmp; - } else { - tmp = p->v; - p->v = p2->v - c->v * sign; - dv1 = tmp - p->v; - } dvc += cv; - scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uf: %lg, c->jdr: %lg\n", - c->id, c->v, p->v, p2->v, dv, p->a, c->a, ns, c->uf, c->jdr); - - c->a = p->a * sign; - c->count = count; - - el = f->elines[p->lid]; - el->v = p->v; - __ses_status_check_line(f, el, changed); - - el = f->elines[p2->lid]; - el->v = p2->v; - __ses_status_check_line(f, el, changed); - + 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 (p->a > a) { p->a = a; + c->a = p->a * sign; + } else + c->a = p->a * sign; + c->count = count; - if (SCF_EDA_NPN == c->type) { - ses_ui_r(&p2->dr, NULL, dv, 0, a, 0); - p2->dr -= p2->r; - - } else if (SCF_EDA_Diode == c->type) { - ses_ui_r(&p->dr, NULL, dv, 0, a, 0); - p->dr -= p->r; - } - } scf_logd("c%ld->v: %lg, p->v: %lg, dv: %lg, ja: %lg, r: %lg\n", c->id, c->v, p->v, dv, p->a, r); p2->a = p->a; @@ -334,11 +299,18 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed, break; } } + + if (k > n) { + p0 = p; + i0 = i; + dv0 = 0; + scf_logi("----------------------i: %d, p0: c%ldp%ld\n", i, p0->cid, p0->id); + } } } - scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, r: %lg, p->a: %lg, a: %lg, p->pr: %lg\n\n", - path->index, i, p->cid, p->id, p->v, dv, r, p->a, a, p->pr); + 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) { @@ -346,8 +318,6 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed, p2 = path->pins->data[i - 1]; *changed += __ses_status_check(f, c, p2, p, 1); - - __ses_pn_dr(c, p2, p); } } else if (SCF_EDA_NPN == c->type) { @@ -358,8 +328,6 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed, if (SCF_EDA_NPN_B == p2->id) { *changed += __ses_status_check(f, c, p2, p, 1); - __ses_npn_dr(c, p2, p); - c->pins[SCF_EDA_NPN_C]->aconst = 1; } } @@ -368,8 +336,8 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed, 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, dvc: %lg\n", - path->index, i, p->cid, p->id, p->v, dv, a, p->pr, dv0, dvc); + 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); } } printf("\n"); @@ -378,10 +346,76 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed, return 0; } +int __ses_path_va2(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count) +{ + if (!path) + return -EINVAL; + + if (path->pins->size < 2) { + scf_loge("\n"); + return -EINVAL; + } + + if (n - m < 1) + return 0; + + ScfEline* el; + ScfEpin* p0 = path->pins->data[m]; + ScfEpin* p1 = path->pins->data[n]; + + el = f->elines[p0->lid]; + p0->v = el->v; + + el = f->elines[p1->lid]; + p1->v = el->v; + + return __ses_path_va3(f, path, m, n, pr, changed, ns, count); +} + +int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed, int64_t ns, int64_t count) +{ + if (!path) + return -EINVAL; + + if (path->pins->size < 2) { + scf_loge("\n"); + return -EINVAL; + } + + ScfEpin* p0 = path->pins->data[0]; + ScfEpin* p1 = path->pins->data[path->pins->size - 1]; + + double _sr0 = p0->sr; + double _pr0 = p0->pr; + double _sr1 = p1->sr; + double _pr1 = p1->pr; + + p0->sr = 0; + p0->pr = 0; + p1->sr = path->sr; + p1->pr = path->pr; + +// scf_logi("---------------\n"); + //int ret = __ses_meshs_path_solve(f, path, 0, path->pins->size - 1, changed, ns, count); + int ret = __ses_path_va2(f, path, 0, path->pins->size - 1, path->pr, changed, ns, count); + if (ret < 0) { + scf_loge("\n"); + return ret; + } +// scf_logi("---------------\n\n"); + + p0->sr = _sr0; + p0->pr = _pr0; + p1->sr = _sr1; + p1->pr = _pr1; + return ret; +} + static int _va_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) { ses_path_t* path; ScfEcomponent* B; + ScfEline* el; ScfEpin* p0; ScfEpin* p1; ScfEpin* Bp; @@ -396,6 +430,12 @@ static int _va_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ct int changed = 0; int i; + for (i = 0; i < f->n_elines; i++) { + el = f->elines[i]; + el->ain = 0; + el->aout = 0; + } + for (i = 0; i < ctx->paths->size; i++) { path = ctx->paths->data[i]; @@ -414,7 +454,7 @@ static int _va_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ct __ses_path_jr(f, path); - int ret = __ses_path_va(f, path, 0, path->pins->size - 1, &changed, ns, count); + int ret = __ses_path_va(f, path, &changed, ns, count); if (ret < 0) return ret; } diff --git a/ses_step_va_bridge.c b/ses_step_va_bridge.c deleted file mode 100644 index 908ffb3..0000000 --- a/ses_step_va_bridge.c +++ /dev/null @@ -1,428 +0,0 @@ -#include"ses_core.h" - -int __ses_flow_a_pos(ScfEfunction* f, ses_flow_t* flow, double da_vip, int* changed) -{ - if (!flow || !flow->paths || flow->paths->size <= 0 || !flow->vip) - return -EINVAL; - - ScfEcomponent* c; - ScfEcomponent* B = f->components[0]; - ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; - ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; - - ses_path_t* path = flow->paths->data[flow->paths->size - 1]; - ScfEpin* vip = flow->vip; - ScfEpin* p; - ScfEline* el; - - double v; - - ses_ir_u(&v, NULL, da_vip, 0, flow->pos_r, 0); - - int i; - int j; - - for (i = 0; i < flow->paths->size; i++) { - path = flow->paths->data[i]; - - double r = 0; - - int j0 = -1; - for (j = path->pins->size - 1; j >= 0; j--) { - p = path->pins->data[j]; - - if (j0 < 0) { - if ((j & 0x1) && p->lid == vip->lid) - j0 = j; - else - continue; - } - - r += p->r + p->dr; - - if (!(j & 0x1)) { - c = f->components[p->cid]; - r += c->r; - - ses_ir_u(&v, NULL, da_vip, 0, r, 0); - } - - el = f->elines[p->lid]; - - if (p->lid != Bp->lid && p->v - v < Bp->lid) { - p->v -= v; - el->v = p->v; - } - - p->a += da_vip; - scf_logw("c%ldp%ld->v: %lg, p->a: %lg, r: %lg, l%ld->v: %lg\n", p->cid, p->id, p->v, p->a, r, el->id, el->v); - - if (!(j & 0x1)) { - r = 0; - } - } - - vip = path->pins->data[0]; - } - - return 0; -} - -int __ses_flow_v_neg(ScfEfunction* f, ses_flow_t* flow, double dv_vip, int* changed) -{ - if (!flow || !flow->paths || flow->paths->size <= 0 || !flow->vip) - return -EINVAL; - - ScfEcomponent* c; - ScfEcomponent* B = f->components[0]; - ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; - ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; - - ses_path_t* path = flow->paths->data[flow->paths->size - 1]; - ScfEpin* vip = flow->vip; - ScfEpin* p; - ScfEpin* p2; - ScfEline* el; - - double v = dv_vip; - double da; - - int i; - int j; - - for (i = 0; i < flow->paths->size; i++) { - path = flow->paths->data[i]; - - double r = 0; - - int j0 = -1; - for (j = 0; j < path->pins->size; j++) { - p = path->pins->data[j]; - - if (j0 < 0) { - if (!(j & 0x1) && p->lid == vip->lid) { - j0 = j; - - ses_ur_i(&da, NULL, vip->v, 0, flow->neg_r, 0); - - da -= p->a; - } else - continue; - } - - r += p->r + p->dr; - - if (j & 0x1) { - c = f->components[p->cid]; - r += c->r; - - ses_ir_u(&v, NULL, da, 0, r, 0); - } - - el = f->elines[p->lid]; - - if (p->lid != Bn->lid && p->v + v > Bn->lid) { - p->v += v; - el->v = p->v; - } - - p->a += da; - - scf_logw("c%ldp%ld->v: %lg, p->a: %lg, r: %lg, v: %lg, da: %lg\n", p->cid, p->id, p->v, p->a, r, v, da); - - if (j & 0x1) { - if (SCF_EDA_Diode == c->type) { - - if (SCF_EDA_Diode_NEG == p->id) { - p2 = path->pins->data[j - 1]; - - *changed += __ses_status_check(f, c, p2, p, 1); - - __ses_pn_dr(c, p2, p); - } - - } else if (SCF_EDA_NPN == c->type) { - - if (SCF_EDA_NPN_E == p->id) { - p2 = path->pins->data[j - 1]; - - if (SCF_EDA_NPN_B == p2->id) { - *changed += __ses_status_check(f, c, p2, p, 1); - - __ses_npn_dr(c, p2, p); - } - } - } - - r = 0; - } - } - - vip = path->pins->data[j - 1]; - } - - return 0; -} - -static int __ses_bridge_v(ScfEfunction* f, ses_path_t* bridge, double vmin, ses_flow_t* flow, int64_t ns, int64_t count) -{ - ScfEline* el; - ScfEpin* p0 = bridge->pins->data[0]; - ScfEpin* p1 = bridge->pins->data[bridge->pins->size - 1]; - - double da; - double v; - double dv; - - double a = 0; - double Eta = 0.001; - - int __changed = 0; - int k = 0; - - while (p0->v - p1->v > vmin) { - - scf_logw("k: %d, ****************\n", k); - - el = f->elines[p0->lid]; - p0->v = el->v; - - el = f->elines[p1->lid]; - p1->v = el->v; - - if (bridge->n_diodes > 0) { - __ses_path_va_diode(f, bridge); - __ses_path_jr (f, bridge); - } - - __changed = 0; - - int ret = __ses_path_va(f, bridge, 0, bridge->pins->size - 1, &__changed, ns, count); - if (ret < 0) - return ret; - - da = bridge->a - a; - a += Eta * da; - - scf_loge("da: %lg, a: %lg, bridge->a: %lg, bridge->pr: %lg, p0->v: %lg, p1->v: %lg, diff: %lg, vmin: %lg\n", - da, a, bridge->a, bridge->pr, p0->v, p1->v, p0->v - p1->v, vmin); - - v = flow->vip->v; - - ret = __ses_flow_a_pos(f, flow, Eta * da, &__changed); - if (ret < 0) - return ret; - - dv = flow->vip->v - v; - - scf_logi("dv: %lg, v: %lg - %lg ----------------\n", dv, flow->vip->v, v); - - ret = __ses_flow_v_neg(f, flow, dv, &__changed); - if (ret < 0) - return ret; - - scf_logw("flow vip: c%ldp%ld->a: %lg, vip_n: c%ldp%ld->a: %lg, bridge->a: %lg, diff: %lg\n\n", - flow->vip->cid, flow->vip->id, flow->vip->a, - flow->vip_n->cid, flow->vip_n->id, flow->vip_n->a, - bridge->a, - flow->vip->a - flow->vip_n->a - bridge->a); - - ses_flow_jr(flow, f); - - if (__changed > 0 - || fabs(dv) < 0.001 - || fabs(flow->vip->a - flow->vip_n->a - bridge->a) < 1e-4) - break; - k++; - } - - return __changed; -} - -static int __ses_bridge_r(ScfEfunction* f, ses_path_t* bridge, int vmin, ses_flow_t* flow) -{ - return 0; -} - -int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns, int64_t count) -{ - ses_flow_t* flow0; - ses_flow_t* flow1; - ses_path_t* fpath; - ses_info_t* info; - - ScfEcomponent* B; - ScfEline* el; - ScfEpin* Bp; - ScfEpin* Bn; - ScfEpin* p0; - ScfEpin* p1; - - B = f->components[0]; - Bp = B->pins[SCF_EDA_Battery_POS]; - Bn = B->pins[SCF_EDA_Battery_NEG]; - - p0 = bridge->pins->data[0]; - p1 = bridge->pins->data[bridge->pins->size - 1]; - - if (p0->lid == Bp->lid && p1->lid == Bn->lid) - return 0; - - __ses_path_jr(f, bridge); - - flow0 = ses_flow_alloc(); - if (!flow0) - return -ENOMEM; - - int ret = ses_paths_find_flow(flow0, paths, p0, bridge); - if (ret < 0) { - ses_flow_free(flow0); - return ret; - } - - flow1 = ses_flow_alloc(); - if (!flow1) { - ses_flow_free(flow0); - return -ENOMEM; - } - - ret = ses_paths_find_flow(flow1, paths, p1, bridge); - if (ret < 0) { - ses_flow_free(flow0); - ses_flow_free(flow1); - return ret; - } - - ses_flow_print(flow0); - ses_flow_jr(flow0, f); - printf("\n"); - - ses_flow_print(flow1); - ses_flow_jr(flow1, f); - printf("\n"); - - double v; - double jv; - double vmin = 0; - int i; - - for (i = 0; i < bridge->infos->size; i++) { - info = bridge->infos->data[i]; - - vmin += info->n_diodes * SCF_EDA_V_Diode_ON + info->n_NPNs * SCF_EDA_V_NPN_ON; - } - - el = f->elines[p0->lid]; - p0->v = el->v; - - el = f->elines[p1->lid]; - p1->v = el->v; - - if (bridge->n_diodes > 0) { - __ses_path_va_diode(f, bridge); - __ses_path_jr (f, bridge); - } - - __ses_path_va_transistor(f, bridge); - __ses_path_jr (f, bridge); - - int __changed = 0; - - ret = __ses_path_va(f, bridge, 0, bridge->pins->size - 1, &__changed, ns, count); - if (ret < 0) - return ret; -#if 0 - if (0 == __changed) { - - ret = __ses_bridge_v(f, bridge, vmin, flow); - if (ret < 0) - return ret; - - if (0 == ret) { - ret = __ses_bridge_r(f, bridge, vmin, flow); - if (ret < 0) - return ret; - } else - __changed = ret; - } -#endif - v = p0->v - p1->v; - - changed += __changed; - - scf_loge("bridge: %d, c%ldp%ld--c%ldp%ld, __changed: %d, v: %lg, p0->v: %lg, p1->v: %lg, n_diodes: %d, p0->a: %lg, p1->a: %lg\n\n", - bridge->index, p0->cid, p0->id, p1->cid, p1->id, __changed, v, p0->v, p1->v, bridge->n_diodes, p0->a, p1->a); - - return 0; -} - -static int ses_path_va_bridge(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths, int64_t ns, int64_t count) -{ - ses_path_t* child; - - int ret; - int j; - - if (!path) - return -EINVAL; - - if (0 == path->n_capacitors) { - - ret = __ses_path_va_bridge(f, path, changed, paths, ns, count); - if (ret < 0) - return ret; - } - - if (path->bridges) { - scf_vector_t* vec = scf_vector_clone(path->childs); - if (!vec) - return -ENOMEM; - - ret = scf_vector_add(vec, path); - if (ret < 0) { - scf_vector_free(vec); - return ret; - } - - for (j = 0; j < path->bridges->size; j++) { - child = path->bridges->data[j]; - - ret = ses_path_va_bridge(f, child, changed, vec, ns, count); - if (ret < 0) { - scf_vector_free(vec); - return ret; - } - } - - scf_vector_free(vec); - vec = NULL; - } - - return 0; -} - -static int _va_bridge_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) -{ - ses_path_t* path; - - int changed = 0; - int i; - - for (i = 0; i < ctx->paths->size; i++) { - path = ctx->paths->data[i]; - - int ret = ses_path_va_bridge(f, path, &changed, ctx->paths, ns, count); - if (ret < 0) - return ret; - } - - ctx->changed += changed; - return 0; -} - -ses_step_t ses_step_va_bridge = -{ - .name = "va_bridge", - - .handler = _va_bridge_handler, -}; diff --git a/ses_step_va_capacitor.c b/ses_step_va_capacitor.c index 6c76221..9740da1 100644 --- a/ses_step_va_capacitor.c +++ b/ses_step_va_capacitor.c @@ -10,74 +10,138 @@ void __ses_status_check_line(ScfEfunction* f, ScfEline* el, int* changed) for (i = 0; i < el->n_pins; i += 2) { - c = f->components[el->pins[i]]; - p0 = c->pins [el->pins[i + 1]]; - p0->v = el->v; + c = f->components[el->pins[i]]; + p0 = c->pins [el->pins[i + 1]]; if (SCF_EDA_Diode == c->type) { p0 = c->pins[SCF_EDA_Diode_POS]; p1 = c->pins[SCF_EDA_Diode_NEG]; + double v0 = p0->v; + double v1 = p1->v; + *changed += __ses_status_check(f, c, p0, p1, 0); - } else if (SCF_EDA_NPN == c->type) { + p0->v = v0; + p1->v = v1; + + } else if (SCF_EDA_NPN == c->type + && (SCF_EDA_NPN_B == p0->id || SCF_EDA_NPN_E == p0->id)) { p0 = c->pins[SCF_EDA_NPN_B]; p1 = c->pins[SCF_EDA_NPN_E]; + double v0 = p0->v; + double v1 = p1->v; + *changed += __ses_status_check(f, c, p0, p1, 0); + + p0->v = v0; + p1->v = v1; } } } -static void ses_va_bridge( - double U0, double U1, double U2, double U3, double Vbc, - double R0, double R1, double R2, double R3, double Rb, - double* pi0, double* pi1, double* pi2, double* pi3, double* pib, - double* pVb0, double* pVb1) +int __ses_flow_va(ScfEfunction* f, ses_flow_t* flow, double* rp, double* rn, int* changed, int64_t ns, int64_t count) +{ +#if 1 + ses_path_t* fpath = flow->paths->data[0]; + ScfEline* el = NULL; + ScfEpin* p0 = fpath->pins->data[flow->vip_m]; + ScfEpin* p1 = fpath->pins->data[flow->vip_n]; + + double tmp; + + __ses_path_jr(f, fpath); + + if (rp) { + el = f->elines[p0->lid]; + tmp = el->v; + + int ret = __ses_path_va2(f, fpath, flow->vip_m, flow->vip_i, *rp, changed, ns, count); + if (ret < 0) + return ret; + + if (el->vconst) + el->v = tmp; + } + + if (rn) { + el = f->elines[p1->lid]; + tmp = el->v; + + int ret = __ses_path_va2(f, fpath, flow->vip_i + 1, flow->vip_n, *rn, changed, ns, count); + if (ret < 0) + return ret; + + if (el->vconst) + el->v = tmp; + } +#endif + return 0; +} + +void __ses_flow_solve_cross(ses_flow_t* flow0, ses_flow_t* flow1, ses_path_t* bridge) { - scf_logw("R0: %lg, R1: %lg, R2: %lg, R3: %lg, Vbc: %lg, U0: %lg, U1: %lg, U2: %lg, U3: %lg\n", R0, R1, R2, R3, Vbc, U0, U1, U2, U3); + ses_path_t* path0; + ses_path_t* path1; + ses_path_t* path; - double i1 = (R0 * R3 * (U2 - U1 + Vbc) - R0 * R2 * (U1 - U3 - Vbc) + (R2 * R3 + R3 * Rb + R2 * Rb) * (U0 - U1)) - / ((R2 + R3) * (R0 * R1 + Rb * (R0 + R1)) + R2 * R3 * (R0 + R1)); + int i; + int j; - double ib = (U0 - U1 - i1 * (R0 + R1)) / R0; - double i0 = i1 + ib; - double i3 = (R0 * (U1 - U3 - Vbc) - Rb * (U0 - U1) + i1 * (R0 * R1 + Rb * (R0 + R1))) / R0 / R3; - double i2 = i3 - ib; + for (i = 0; i < flow0->paths->size; i++) { + path0 = flow0->paths->data[i]; - double V0 = i0 * R0; - double V1 = i1 * R1; - double V2 = i2 * R2; - double V3 = i3 * R3; - double Vb = ib * Rb; + for (j = 0; j < flow1->paths->size; j++) { + path1 = flow1->paths->data[j]; - scf_logi("i0: %lg, i1: %lg, i2: %lg, i3: %lg, ib: %lg\n", i0, i1, i2, i3, ib); + if (path0 == path1) { + flow1->paths->size = j + 1; + flow0->paths->size = i + 1; + goto cross; + } + } + } + + return; - double Vb0 = U1 + V1; - double Vb1 = U3 + V3; +cross: + scf_logi("-----------\n"); - if (pi0) - *pi0 = i0; + if (i > 0) { + if (j > 0) { + scf_logi("-----------\n"); + return; + } - if (pi1) - *pi1 = i1; + path = flow0->paths->data[i - 1]; - if (pi2) - *pi2 = i2; + if (flow1->vip_i > path->parent_p0 && flow1->vip_i < path->parent_p1) { + flow1->vip_m = path->parent_p0; + flow1->vip_n = path->parent_p1; + } - if (pi3) - *pi3 = i3; + } else if (j > 0) { + path = flow1->paths->data[j - 1]; - if (pib) - *pib = ib; + if (flow0->vip_i > path->parent_p0 && flow0->vip_i < path->parent_p1) { + flow0->vip_m = path->parent_p0; + flow0->vip_n = path->parent_p1; + } - if (pVb0) - *pVb0 = Vb0; + } else { + path = flow0->paths->data[0]; - if (pVb1) - *pVb1 = Vb1; + if (flow0->vip_i < flow1->vip_i) { + flow0->vip_m = flow0->vip_i; + flow0->vip_n = flow1->vip_i; + } else { + flow1->vip_m = flow1->vip_i; + flow1->vip_n = flow0->vip_i; + } + } } static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_t* bridge, int* changed, int64_t ns, int64_t count) @@ -92,6 +156,8 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat ScfEpin* p1; ScfEpin* fp0; ScfEpin* fp1; + ScfEpin* fp2; + ScfEpin* fp3; ScfEpin* Bp; ScfEpin* Bn; @@ -131,7 +197,7 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat goto error; if (flow0->paths->size > 0) { - fpath = flow0->paths->data[flow0->paths->size - 1]; + fpath = flow0->paths->data[0]; if (!fpath->vflag) { ret = __ses_path_va_capacitor(f, paths, fpath, changed, ns, count); @@ -141,26 +207,49 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat } if (flow1->paths->size > 0) { - fpath = flow1->paths->data[flow1->paths->size - 1]; + fpath = flow1->paths->data[0]; if (!fpath->vflag) { ret = __ses_path_va_capacitor(f, paths, fpath, changed, ns, count); if (ret < 0) goto error; } - } + + if (flow0->paths->size > 0) { + + __ses_flow_solve_cross(flow0, flow1, bridge); + + flow0->paths->size = 1; + } + + flow1->paths->size = 1; + } else if (flow0->paths->size > 0) + flow0->paths->size = 1; double R; double cv; + double Dv = bridge->n_NPNs * SCF_EDA_V_NPN_ON + bridge->n_diodes * SCF_EDA_V_Diode_ON; double ja; + double tmp0; + double tmp1; __ses_path_jr(f, bridge); el = f->elines[p0->lid]; p0->v = el->v; + tmp0 = el->v; el = f->elines[p1->lid]; p1->v = el->v; + tmp1 = el->v; + + ses_flow_print(flow0); + ses_flow_jr(flow0, f); + printf("\n"); + + ses_flow_print(flow1); + ses_flow_jr(flow1, f); + printf("\n"); __ses_path_capacitors(f, bridge, 0, bridge->pins->size - 1, &cv); @@ -170,150 +259,205 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat if (p0->lid == Bp->lid) { - ret = ses_flow_find_pos(flow1, paths, f); - if (ret < 0) - goto error; - - ret = ses_flow_find_neg(flow1, paths, f); - if (ret < 0) - goto error; + fpath = flow1->paths->data[flow1->paths->size - 1]; + fp0 = fpath->pins->data[0]; + fp1 = fpath->pins->data[fpath->pins->size - 1]; - ses_flow_print(flow0); - ses_flow_jr(flow0, f); printf("\n"); + scf_logi("-----------\n"); + ret = __ses_meshs_PPN_solve(f, flow1, bridge, changed, ns, count); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + scf_logi("-----------\n\n"); - ses_flow_print(flow1); - ses_flow_jr(flow1, f); - printf("\n"); + } else if (p1->lid == Bn->lid) { - R = bridge->jpr * flow1->pos_r / (bridge->jpr + flow1->pos_r); + fpath = flow0->paths->data[flow0->paths->size - 1]; + fp0 = fpath->pins->data[0]; + fp1 = fpath->pins->data[fpath->pins->size - 1]; - ja = Bp->v / (R + flow1->neg_r); - p0->v = Bp->v; - p1->v = Bp->v - ja * R; + double U0 = fp0->v - flow0->pos_cv; + double U1 = Bn->v + cv + Dv; + double U2 = fp1->v + flow0->neg_cv; - } else if (p1->lid == Bn->lid) { + ses_va_PNN(U0, U1, U2, flow0->pos_r, bridge->pr, flow0->neg_r, + NULL, &ja, NULL, &p0->v); - ret = ses_flow_find_pos(flow0, paths, f); - if (ret < 0) + p1->v = Bn->v; + + scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n", + p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja); + + el = f->elines[p0->lid]; + el->v = p0->v; + + el = f->elines[p1->lid]; + el->v = p1->v; + + ret = __ses_path_va(f, bridge, changed, ns, count); + if (ret < 0) { + scf_loge("\n"); goto error; + } + + el = f->elines[p0->lid]; + if (el->vconst) + el->v = tmp0; - ret = ses_flow_find_neg(flow0, paths, f); + el = f->elines[p1->lid]; + if (el->vconst) + el->v = tmp1; + + ret = __ses_flow_va(f, flow0, &flow0->pos_r, &flow0->neg_r, changed, ns, count); if (ret < 0) goto error; - ses_flow_print(flow0); - ses_flow_jr(flow0, f); - printf("\n"); + } else { + fpath = flow0->paths->data[0]; + fp0 = fpath->pins->data[flow0->vip_m]; + fp1 = fpath->pins->data[flow0->vip_n]; - ses_flow_print(flow1); - ses_flow_jr(flow1, f); - printf("\n"); + double U0 = fp0->v - flow0->pos_cv; + double U1 = fp1->v + flow0->neg_cv; - R = bridge->jpr * flow0->neg_r / (bridge->jpr + flow0->neg_r); + fpath = flow1->paths->data[0]; + fp2 = fpath->pins->data[flow1->vip_m]; + fp3 = fpath->pins->data[flow1->vip_n]; - ja = Bp->v / (R + flow0->pos_r); - p0->v = Bp->v - ja * flow0->pos_r; - p1->v = Bn->v; + double U2 = fp2->v - flow1->pos_cv; + double U3 = fp3->v + flow1->neg_cv; - scf_logi("R: %lg, flow0->pos_r: %lg, flow0->neg_r: %lg\n", R, flow0->pos_r, flow0->neg_r); - } else { - ses_flow_print(flow0); - ses_flow_jr(flow0, f); - printf("\n"); + double i0 = 0; + double i1 = 0; + double i2 = 0; + double i3 = 0; - ses_flow_print(flow1); - ses_flow_jr(flow1, f); - printf("\n"); + ses_va_bridge(U0, U1, U2, U3, cv, + flow0->pos_r, flow0->neg_r, flow1->pos_r, flow1->neg_r, bridge->pr, + &i0, &i1, &i2, &i3, &ja, &p0->v, &p1->v); - fpath = flow0->paths->data[flow0->paths->size - 1]; - fp0 = fpath->pins->data[0]; - fp1 = fpath->pins->data[fpath->pins->size - 1]; + scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n", + p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja); - double U0 = fp0->v; - double U1 = fp1->v; + el = f->elines[p0->lid]; + el->v = p0->v; - fpath = flow1->paths->data[flow1->paths->size - 1]; - fp0 = fpath->pins->data[0]; - fp1 = fpath->pins->data[fpath->pins->size - 1]; + el = f->elines[p1->lid]; + el->v = p1->v; - double U2 = fp0->v; - double U3 = fp1->v; + ret = __ses_path_va(f, bridge, changed, ns, count); + if (ret < 0) { + scf_loge("\n"); + goto error; + } - ses_va_bridge(U0, U1, U2, U3, cv, - flow0->pos_r, flow0->neg_r, flow1->pos_r, flow1->neg_r, bridge->jpr, - NULL, NULL, NULL, NULL, &ja, &p0->v, &p1->v); - } + el = f->elines[p0->lid]; + if (el->vconst) + el->v = tmp0; - scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n", - p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja); - } else { - assert(p0->lid != Bp->lid); - - if (p1->lid == Bn->lid) { + el = f->elines[p1->lid]; + if (el->vconst) + el->v = tmp1; - ret = ses_flow_find_neg(flow1, paths, f); + ret = __ses_flow_va(f, flow1, &flow1->pos_r, &flow1->neg_r, changed, ns, count); if (ret < 0) goto error; - ses_flow_print(flow0); - ses_flow_jr(flow0, f); - printf("\n"); + ret = __ses_flow_va(f, flow0, &flow0->pos_r, &flow0->neg_r, changed, ns, count); + if (ret < 0) + goto error; + } + } else { + assert(p0->lid != Bp->lid); - ses_flow_print(flow1); - ses_flow_jr(flow1, f); - printf("\n"); + if (p1->lid == Bn->lid) { - R = bridge->jpr + flow0->neg_r; + R = bridge->pr + flow0->neg_r; ja = (cv - p0->v) / R; p1->v = Bn->v; - } else { - ses_flow_print(flow0); - ses_flow_jr(flow0, f); - printf("\n"); + scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n", + p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja); - ses_flow_print(flow1); - ses_flow_jr(flow1, f); - printf("\n"); + el = f->elines[p0->lid]; + el->v = p0->v; - fpath = flow1->paths->data[flow1->paths->size - 1]; - fp0 = fpath->pins->data[0]; - fp1 = fpath->pins->data[fpath->pins->size - 1]; + el = f->elines[p1->lid]; + el->v = p1->v; - double U0 = fp0->v; - double U1 = fp1->v; + ret = __ses_path_va(f, bridge, changed, ns, count); + if (ret < 0) { + scf_loge("\n"); + goto error; + } - fpath = flow0->paths->data[flow0->paths->size - 1]; - fp0 = fpath->pins->data[0]; - fp1 = fpath->pins->data[fpath->pins->size - 1]; + el = f->elines[p0->lid]; + if (el->vconst) + el->v = tmp0; + + el = f->elines[p1->lid]; + if (el->vconst) + el->v = tmp1; + + } else { + fpath = flow1->paths->data[0]; + fp0 = fpath->pins->data[flow1->vip_m]; + fp1 = fpath->pins->data[flow1->vip_n]; + + double U0 = fp0->v - flow1->pos_cv; + double U1 = fp1->v + flow1->neg_cv; - double U2 = fp0->v; - double U3 = fp1->v; + fpath = flow0->paths->data[0]; + fp2 = fpath->pins->data[flow0->vip_m]; + fp3 = fpath->pins->data[flow0->vip_n]; + + double U2 = fp2->v - flow0->pos_cv; + double U3 = fp3->v + flow0->neg_cv; + + double i0 = 0; + double i1 = 0; + double i2 = 0; + double i3 = 0; ses_va_bridge(U0, U1, U2, U3, -cv, - flow1->pos_r, flow1->neg_r, flow0->pos_r, flow0->neg_r, bridge->jpr, - NULL, NULL, NULL, NULL, &ja, &p1->v, &p0->v); - } + flow1->pos_r, flow1->neg_r, flow0->pos_r, flow0->neg_r, bridge->pr, + &i0, &i1, &i2, &i3, &ja, &p1->v, &p0->v); - scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n", - p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja); - } + scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n", + p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja); - el = f->elines[p0->lid]; - el->v = p0->v; + el = f->elines[p0->lid]; + el->v = p0->v; - el = f->elines[p1->lid]; - el->v = p1->v; + el = f->elines[p1->lid]; + el->v = p1->v; - ret = __ses_path_va(f, bridge, 0, bridge->pins->size - 1, changed, ns, count); - if (ret < 0) { - scf_loge("\n"); - goto error; + ret = __ses_path_va(f, bridge, changed, ns, count); + if (ret < 0) { + scf_loge("\n"); + goto error; + } + + el = f->elines[p0->lid]; + if (el->vconst) + el->v = tmp0; + + el = f->elines[p1->lid]; + if (el->vconst) + el->v = tmp1; + + ret = __ses_flow_va(f, flow1, &flow1->pos_r, &flow1->neg_r, changed, ns, count); + if (ret < 0) + goto error; + + ret = __ses_flow_va(f, flow0, &flow0->pos_r, &flow0->neg_r, changed, ns, count); + if (ret < 0) + goto error; + } } - __ses_status_check_line(f, f->elines[p0->lid], changed); - __ses_status_check_line(f, f->elines[p1->lid], changed); ret = 0; error: ses_flow_free(flow0); @@ -331,12 +475,9 @@ static int ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_ if (!bridge || bridge->pins->size < 2) return -EINVAL; - if (bridge->n_capacitors > 0) { - - ret = __ses_path_va_capacitor(f, paths, bridge, changed, ns, count); - if (ret < 0) - return ret; - } + ret = __ses_path_va_capacitor(f, paths, bridge, changed, ns, count); + if (ret < 0) + return ret; if (bridge->bridges) { for (j = 0; j < bridge->bridges->size; j++) { diff --git a/ses_step_va_diode.c b/ses_step_va_diode.c index 400747f..be5f8f9 100644 --- a/ses_step_va_diode.c +++ b/ses_step_va_diode.c @@ -76,10 +76,18 @@ void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double if (cp0->lid != p0->lid || cp1->lid != p1->lid) continue; - ses_ur_i(&child->a, NULL, v, 0, child->pr, 0); + double cv = 0; - if (child->a >= la) - ses_split_i(&child->a, NULL, la, 0, child->pr, 0, r, 0); + if (child->n_capacitors > 0) { + __ses_path_capacitors(f, child, 0, child->pins->size - 1, &cv); + v -= cv; + ses_ur_i(&child->a, NULL, v, 0, child->pr, 0); + } else { + ses_ur_i(&child->a, NULL, v, 0, child->pr, 0); + + if (child->a >= la) + ses_split_i(&child->a, NULL, la, 0, child->pr, 0, r, 0); + } *a -= child->a; @@ -89,7 +97,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 > 0) { + if (child->n_diodes + child->n_NPNs > 0) { int ret = __ses_path_va_diode(f, child); if (ret < 0) @@ -98,8 +106,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, child->pr: %lg, r: %lg, child->a: %lg, el->a: %lg\n", - k, cp0->cid, cp0->id, cp1->cid, cp1->id, v, child->pr, r, child->a, la); + 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); cp1->v = p1->v; cp0->v = p0->v; @@ -111,7 +119,7 @@ void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double cp0->a = ca; - if (child->n_diodes > 0) + if (child->n_diodes + child->n_NPNs > 0) __ses_path_dr_forward(f, child, 0, child->pins->size - 1, ca); ok: @@ -171,55 +179,21 @@ void __ses_path_dr_reverse(ScfEfunction* f, ses_path_t* path, int i, int j, doub } } -ses_path_t* ses_path_find_child(ses_path_t* path, int m, int n) -{ - ses_path_t* child; - ScfEpin* cp0; - ScfEpin* cp1; - - if (path->childs) { - ScfEpin* p0; - ScfEpin* p1 = path->pins->data[n]; - - int i; - int j; - - for (i = 0; i < path->childs->size; i++) { - child = path->childs->data[i]; - - cp0 = child->pins->data[0]; - cp1 = child->pins->data[child->pins->size - 1]; - - if (cp1->lid != p1->lid) - continue; - - for (j = m; j <= n; j++) { - p0 = path->pins->data[j]; - - if (cp0->lid == p0->lid) - return child; - } - } - } - return NULL; -} - -static void __ses_path_a_diode(ScfEfunction* f, ses_path_t* path, int k, double* a) +static void __ses_path_a_diode(ScfEfunction* f, ses_path_t* path, int i, int k, double cv, double* a) { ses_info_t* info; ses_path_t* child; - ScfEpin* p0 = path->pins->data[0]; + ScfEpin* p0 = path->pins->data[i]; ScfEpin* p1 = path->pins->data[path->pins->size - 1]; ScfEpin* pi; ScfEpin* pj; - double v = p0->v - p1->v; + double v = p0->v - p1->v - cv; double r = 0; double _r; - int i = 0; int j; for (j = k; j < path->infos->size; j++) { @@ -227,12 +201,9 @@ static void __ses_path_a_diode(ScfEfunction* f, ses_path_t* path, int k, double* pi = path->pins->data[i]; pj = path->pins->data[info->i]; - v -= info->n_diodes * SCF_EDA_V_Diode_ON; - v -= info->n_NPNs * SCF_EDA_V_NPN_ON; + v -= info->n_diodes * SCF_EDA_V_Diode_ON + info->n_NPNs * SCF_EDA_V_NPN_ON; - child = ses_path_find_child(path, i, info->i); - - __ses_path_pr(f, path, i, info->i, child, &_r); + __ses_path_pr(f, path, i, info->i, NULL, &_r); r += _r; @@ -247,9 +218,7 @@ static void __ses_path_a_diode(ScfEfunction* f, ses_path_t* path, int k, double* pi = path->pins->data[i]; pj = path->pins->data[j]; - child = ses_path_find_child(path, i, j); - - __ses_path_pr(f, path, i, j, child, &_r); + __ses_path_pr(f, path, i, j, NULL, &_r); r += _r; scf_logd("c%ldp%ld--c%ldp%ld, r: %lg, v: %lg, _r: %lg\n", pi->cid, pi->id, pj->cid, pj->id, r, v, _r); @@ -272,14 +241,12 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path) ScfEpin* pi; ScfEpin* pj; - int j; - - if (path->n_diodes * 2 >= path->pins->size) { + if ((path->n_diodes + path->n_NPNs) * 2 >= path->pins->size) { scf_loge("all components are diodes\n\n"); return -1; } - if (path->n_diodes <= 0) + if (path->n_diodes + path->n_NPNs <= 0) return 0; p0 = path->pins->data[0]; @@ -294,54 +261,67 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path) double v; double r; double a; + double cv = 0; + + int i = 0; + int j; for (j = 0; j < path->infos->size; j++) { info = path->infos->data[j]; pi = path->pins->data[info->i]; pj = path->pins->data[info->j]; - c = f->components[pi->cid]; + c = f->components[pi->cid]; + el = f->elines[pi->lid]; + 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)); - __ses_path_a_diode(f, path, j, &a); + __ses_path_capacitors(f, path, i, path->pins->size - 1, &cv); + + __ses_path_a_diode(f, path, i, j, cv, &a); if (a < 0) break; if (0 == j) - path->a = a; + path->a = a; pi->a = a; - __ses_path_pr(f, path, 0, info->i, NULL, &r); + __ses_path_pr(f, path, i, info->i, NULL, &r); ses_ir_u(&v, NULL, a, 0, r, 0); - pi->v = p0->v - v; + double cv2 = 0; + __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; - scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, c%ldp%ld->v: %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, r, v, a); + 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); el = f->elines[pi->lid]; - el->a = a; el->v = pi->v; - el->aconst = 1; +// el->vconst = 1; el = f->elines[pj->lid]; - el->a = a; el->v = pj->v; - el->aconst = 1; +// el->vconst = 1; - if (path->childs) - __ses_path_split_i(f, path, info->i, info->j, a, &pi->a); + if (path->childs) { + __ses_path_split_i(f, path, info->i, path->pins->size - 1, a, &pi->a); + if (info->j < path->pins->size - 1) + __ses_path_split_i(f, path, info->i, info->j, a, &pi->a); + } scf_loge("info->i: %d, info->j: %d, c%ldp%ld--c%ldp%ld, pi->v: %lg, pj->v: %lg, pi->a: %lg\n\n", info->i, info->j, pi->cid, pi->id, pj->cid, pj->id, pi->v, pj->v, pi->a); __ses_path_dr_forward(f, path, info->i, info->j, pi->a); + i = info->j + 1; } return 0; diff --git a/ses_step_va_transistor.c b/ses_step_va_transistor.c index 3c0a08c..482e3df 100644 --- a/ses_step_va_transistor.c +++ b/ses_step_va_transistor.c @@ -104,9 +104,6 @@ _changed: int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path) { - ses_path_t* parent = path->parent; - ses_path_t* child; - ScfEcomponent* c; ScfEline* el; ScfEpin* p0; @@ -157,7 +154,7 @@ int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path) __ses_path_split_i(f, path, i, j, pj->a, &pc->a); } else - pc->v = pj->v; + pc->v = pj->v; j = i; } @@ -176,8 +173,8 @@ int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path) 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\n", - i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, pc->pr, pb->cid, pb->id, pb->a); + 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; @@ -198,26 +195,26 @@ int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path) i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, _pr, pc->pr); } - el = f->elines[pc->lid]; - el->v = pc->v; - el->a = pc->a; - el->vconst = 1; + 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, el->a, &pc->a); + __ses_path_split_i(f, path, i, j, a, &pc->a); if (i > 0) { p = path->pins->data[i - 1]; - p->a = el->a; + p->a = a; p->v = el->v; - __ses_path_split_i(f, path, 0, i - 1, el->a, &p->a); + __ses_path_split_i(f, path, 0, i - 1, a, &p->a); } } else - p0->a = el->a; + p0->a = a; __ses_path_dr_transistor(f, path, i, j); diff --git a/ses_steps.c b/ses_steps.c index 86e8f58..6d9f5e0 100644 --- a/ses_steps.c +++ b/ses_steps.c @@ -17,14 +17,17 @@ 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_va_bridge; -extern ses_step_t ses_step_va_line; +extern ses_step_t ses_step_status; extern ses_step_t ses_step_open; 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; +extern ses_step_t ses_step_simplify2; static ses_step_t* ses_steps_0[] = @@ -48,20 +51,21 @@ static ses_step_t* ses_steps_1[] = // &ses_step_jr, &ses_step_va, - &ses_step_va_bridge, - &ses_step_va_line, + &ses_step_status, }; static ses_step_t* ses_steps_2[] = { &ses_step_open, +// &ses_step_simplify2, &ses_step_va_capacitor, +// &ses_step_a_stat, + &ses_step_output, &ses_step_simplify, }; - static int __ses_analyse_input(ScfEfunction* f, int64_t ns, int64_t i, ses_ctx_t* ctx) { ses_step_t* s; @@ -127,6 +131,7 @@ static int __ses_analyse_current(ScfEfunction* f, int64_t ns, int64_t i, ses_ctx } } + scf_loge("--------------- ctx->changed: %d\n", ctx->changed); return ctx->changed > 0 ? -EAGAIN : 0; } diff --git a/ses_utils.c b/ses_utils.c index 85b828d..a121ca0 100644 --- a/ses_utils.c +++ b/ses_utils.c @@ -1,770 +1,148 @@ #include"ses_core.h" -ses_flow_t* ses_flow_alloc() +ses_ctx_t* ses_ctx_alloc() { - ses_flow_t* flow = calloc(1, sizeof(ses_flow_t)); - if (!flow) + ses_ctx_t* ctx = calloc(1, sizeof(ses_ctx_t)); + if (!ctx) return NULL; - flow->paths = scf_vector_alloc(); - if (!flow->paths) { - ses_flow_free(flow); + ctx->paths = scf_vector_alloc(); + if (!ctx->paths) { + free(ctx); return NULL; } - return flow; -} - -void ses_flow_free(ses_flow_t* flow) -{ - if (flow) { - if (flow->paths) - scf_vector_free(flow->paths); - - free(flow); - } + return ctx; } -int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, ses_path_t* bridge) +void ses_ctx_free(ses_ctx_t* ctx) { - ses_path_t* path; - ScfEpin* p; - - int i; - int j; - - for (i = 0; i < paths->size; i++) { - path = paths->data[i]; - - if (path == bridge) - continue; - - for (j = 0; j < path->pins->size; j++) { - p = path->pins->data[j]; - - if (vip ->lid == p->lid) { - - if (j + 1 >= path->pins->size) - break; - - flow->vip = p; - flow->vip_n = path->pins->data[j + 1];; - - if (scf_vector_add(flow->paths, path) < 0) - return -1; - return 1; - } - } - - if (path->childs) { - int ret = ses_paths_find_flow(flow, path->childs, vip, bridge); - if (ret < 0) - return ret; - - if (1 == ret) { - if (scf_vector_add(flow->paths, path) < 0) - return -ENOMEM; - return 1; - } - } - - if (path->bridges) { - int ret = ses_paths_find_flow(flow, path->bridges, vip, bridge); - if (ret < 0) - return ret; - - if (1 == ret) { - if (scf_vector_add(flow->paths, path) < 0) - return -ENOMEM; - return 1; - } + if (ctx) { + if (ctx->paths) { + scf_vector_clear(ctx->paths, ( void (*)(void*) )ses_path_free); + scf_vector_free (ctx->paths); } - } - - return 0; -} - -int ses_flow_find_neg(ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f) -{ - if (flow->paths->size <= 0) - return 0; - - ses_path_t* path = flow->paths->data[flow->paths->size - 1]; - ScfEpin* vp = flow->vip; - ScfEpin* vn = flow->vip_n; - ScfEpin* p = path->pins->data[path->pins->size - 1]; - - ScfEcomponent* B = f->components[0]; - ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; - - while (p->lid != Bn->lid) { - int ret = ses_paths_find_flow(flow, paths, p, path); - if (ret < 0) - return ret; - - path = flow->paths->data[flow->paths->size - 1]; - p = path->pins ->data[path->pins->size - 1]; - } - - flow->vip = vp; - flow->vip_n = vn; - return 0; -} - -int ses_flow_find_pos(ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f) -{ - if (flow->paths->size <= 0) - return 0; - ses_path_t* path = flow->paths->data[flow->paths->size - 1]; - ScfEpin* vp = flow->vip; - ScfEpin* vn = flow->vip_n; - ScfEpin* p = path->pins->data[0]; - - ScfEcomponent* B = f->components[0]; - ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; - - while (p->lid != Bp->lid) { - int ret = ses_paths_find_flow(flow, paths, p, path); - if (ret < 0) - return ret; - - path = flow->paths->data[flow->paths->size - 1]; - p = path->pins ->data[0]; + free(ctx); } - - flow->vip = vp; - flow->vip_n = vn; - return 0; } -int ses_flows_make_path(ses_path_t** ppath, ses_flow_t* pos, ses_flow_t* neg, ses_path_t* bridge, int reverse) +ses_edge_t* ses_edge_alloc(ses_path_t* path, int first, int last) { - if (!pos || !neg || !bridge) - return -EINVAL; - - if (!pos->paths || !pos->vip || !neg->paths || !neg->vip_n) - return -EINVAL; - - *ppath = ses_path_alloc(); - if (!*ppath) - return -ENOMEM; - - ses_path_t* path; - ScfEcomponent* c; - ScfEpin* p; - ScfEpin* p0; - ScfEpin* vip = pos->vip; - - int i; - int j; - - for (i = 0; i < pos->paths->size; i++) { - path = pos->paths->data[i]; - - for (j = 0; j < path->pins->size; j++) { - p = path->pins->data[j]; - - if (p->lid == vip->lid) { - vip = path->pins->data[0]; - break; - } - } - - assert(j < path->pins->size); - - for ( ; j >= 0; j--) { - p = path->pins->data[j]; - - if (scf_vector_add((*ppath)->pins, p) < 0) { - ses_path_free(*ppath); - *ppath = NULL; - return -ENOMEM; - } - } - } - - // positive branch is reversed, make it normal - i = 0; - j = (*ppath)->pins->size - 1; - - while (i < j) { - SCF_XCHG((*ppath)->pins->data[i], (*ppath)->pins->data[j]); - i++; - j--; - } - - // add the bridge by the reverse flag - if (!reverse) { - for (j = 0; j < bridge->pins->size; j++) { - p = bridge->pins->data[j]; - - if (scf_vector_add((*ppath)->pins, p) < 0) { - ses_path_free(*ppath); - *ppath = NULL; - return -ENOMEM; - } - } - } else { - for (j = bridge->pins->size - 1; j >= 0; j--) { - p = bridge->pins->data[j]; - - if (scf_vector_add((*ppath)->pins, p) < 0) { - ses_path_free(*ppath); - *ppath = NULL; - return -ENOMEM; - } - } - } - - // negative branch is normal - vip = neg->vip; - - for (i = 0; i < neg->paths->size; i++) { - path = neg->paths->data[i]; - - for (j = 0; j < path->pins->size; j++) { - p = path->pins->data[j]; - - if (p->lid == vip->lid) - break; - } - - for (++j; j < path->pins->size; j++) { - p = path->pins->data[j]; + ses_edge_t* edge = calloc(1, sizeof(ses_edge_t)); + if (!edge) + return NULL; - if (scf_vector_add((*ppath)->pins, p) < 0) { - ses_path_free(*ppath); - *ppath = NULL; - return -ENOMEM; - } - } + edge->path = path; + edge->vip_m = first; + edge->vip_n = last; - vip = path->pins->data[j - 1]; - } - - return 0; + edge->refs = 1; + return edge; } -void ses_flow_jr(ses_flow_t* flow, ScfEfunction* f) +void ses_edge_free(ses_edge_t* edge) { - if (!flow) - return; + if (edge) { + if (--edge->refs > 0) + return; - flow->pos_pins = 0; - flow->neg_pins = 0; + assert(0 == edge->refs); - flow->pos_r = 0; - flow->neg_r = 0; - - if (!flow->paths || !flow->vip) - return; - - ses_path_t* path; - ses_path_t* child; - ScfEcomponent* c; - ScfEpin* p; - ScfEpin* p0; - ScfEpin* vip = flow->vip; - - int i; - int j; - - for (i = 0; i < flow->paths->size; i++) { - path = flow->paths->data[i]; - - for (j = 0; j < path->pins->size; j++) { - p = path->pins->data[j]; - - ++flow->pos_pins; - - c = f->components[p->cid]; - - if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_B == p->id) - flow->pos_NPNs++; - else if (SCF_EDA_Diode == c->type && SCF_EDA_Diode_POS == p->id) - flow->pos_diodes++; - - if (p->lid == vip->lid) { - vip = path->pins->data[0]; - - double pr = p->pr; - - if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id) - __ses_npn_epr(f, p, &pr); - - flow->pos_r += pr; - - scf_logd("flow->pos_r: %lg, c%ldp%ld->pr: %lg, pr: %lg, vip c%ldp%ld->pr: %lg\n", - flow->pos_r, p->cid, p->id, p->pr, pr, vip->cid, vip->id, vip->pr); - break; - } - } + free(edge); } - - vip = flow->vip; - - for (i = 0; i < flow->paths->size; i++) { - path = flow->paths->data[i]; - - int j0; - - p0 = NULL; - for (j = 0; j < path->pins->size; j++) { - p = path->pins->data[j]; - - if (!p0) { - if (p->lid == vip->lid) { - p0 = p; - j0 = j; - } - continue; - } - - ++flow->neg_pins; - - c = f->components[p->cid]; - - if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_B == p->id) - flow->neg_NPNs++; - else if (SCF_EDA_Diode == c->type && SCF_EDA_Diode_POS == p->id) - flow->neg_diodes++; - - if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id) { - p = path->pins->data[j - 1]; - - if (p->lid == p0->lid) - flow->neg_r += p->r + p->dr; - else - flow->neg_r += p->pr - p0->pr; - - scf_logd("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n", - flow->neg_r, p->cid, p->id, p->sr, p0->cid, p0->id, p0->pr); - - if (j + 1 < path->pins->size) { - p0 = path->pins->data[j + 1]; - j0 = j + 1; - } else { - p0 = path->pins->data[j]; - j0 = j; - } - - } else if (p->sr != p->pr) { - - child = ses_path_find_child(path, j0, j); - if (child) - flow->neg_r += child->parent_pr - p0->pr; - else - flow->neg_r += p->sr - p0->pr; - - scf_logd("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p->pr: %lg, p0 c%ldp%ld->pr: %lg\n", - flow->neg_r, p->cid, p->id, p->sr, p->pr, p0->cid, p0->id, p0->pr); - p0 = p; - j0 = j; - } - } - - if (p0) { - vip = path->pins->data[j - 1]; - c = f->components[vip->cid]; - - if (vip != p0) { - child = ses_path_find_child(path, j0, j - 1); - if (child) - flow->neg_r += child->parent_pr - p0->pr; - else - flow->neg_r += vip->sr - p0->pr; - } - - scf_logd("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n", - flow->neg_r, vip->cid, vip->id, vip->sr, p0->cid, p0->id, p0->pr); - - if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == vip->id) { - vip->pr = path->parent_pr; - vip->jpr = path->parent_jpr; - } - } - - scf_logd("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg\n", flow->neg_r, vip->cid, vip->id, vip->sr); - } - - scf_loge("flow pos_r: %lg, neg_r: %lg, vip: c%ldp%ld, pos_diodes: %d, pos_NPNs: %d, neg_diodes: %d, neg_NPNs: %d\n", - flow->pos_r, flow->neg_r, flow->vip->cid, flow->vip->id, flow->pos_diodes, flow->pos_NPNs, flow->neg_diodes, flow->neg_NPNs); } -void ses_flow_print(ses_flow_t* flow) +void ses_edge_print(ses_edge_t* edge) { - if (!flow || !flow->paths || !flow->vip) + if (!edge) return; - ses_path_t* path; - ScfEpin* p; - ScfEpin* vip = flow->vip; - - int i; - int j; - - for (i = flow->paths->size - 1; i >= 0; i--) { - - if (i > 0) { - path = flow->paths->data[i - 1]; - vip = path->pins->data[0]; - } else - vip = flow->vip; - - path = flow->paths->data[i]; + ScfEpin* p; + int j; - for (j = 0; j < path->pins->size; j++) { - p = path->pins->data[j]; + if (edge->vip_m < edge->vip_n) { - printf("c%ldp%ld ", p->cid, p->id); + for (j = edge->vip_m; j <= edge->vip_n; j++) { + p = edge->path->pins->data[j]; - if (p->lid == vip->lid) - break; + if (j < edge->vip_n) + printf("c%ldp%ld, ", p->cid, p->id); + else + printf("c%ldp%ld; ", p->cid, p->id); } - if (i > 0) - printf(", "); - } - - printf(";\n"); - - vip = flow->vip; - - for (i = 0; i < flow->paths->size; i++) { - path = flow->paths->data[i]; - - int flag = 0; - - for (j = 0; j < path->pins->size; j++) { - p = path->pins->data[j]; - - if (!flag) { - if (p->lid == vip->lid) - flag = 1; - continue; - } + } else { + for (j = edge->vip_m; j >= edge->vip_n; j--) { + p = edge->path->pins->data[j]; - printf("c%ldp%ld ", p->cid, p->id); + if (j > edge->vip_n) + printf("c%ldp%ld, ", p->cid, p->id); + else + printf("c%ldp%ld; ", p->cid, p->id); } - - if (flag) - printf(", "); - - vip = path->pins->data[j - 1]; } - - printf(".\n"); } -ses_path_t* ses_path_alloc() +ses_mesh_t* ses_mesh_alloc() { - ses_path_t* path = calloc(1, sizeof(ses_path_t)); - if (!path) + ses_mesh_t* mesh = calloc(1, sizeof(ses_mesh_t)); + if (!mesh) return NULL; - path->pins = scf_vector_alloc(); - if (!path->pins) { - free(path); + mesh->edges = scf_vector_alloc(); + if (!mesh->edges) { + free(mesh); return NULL; } - path->infos = scf_vector_alloc(); - if (!path->infos) { - scf_vector_free(path->pins); - free(path); - return NULL; - } - - return path; + return mesh; } -void ses_path_free(ses_path_t* path) +void ses_mesh_free(ses_mesh_t* mesh) { - if (path) { - if (path->pins) - scf_vector_free(path->pins); - - if (path->infos) { - scf_vector_clear(path->infos, ( void (*)(void*) )free); - scf_vector_free (path->infos); - } - - if (path->childs) { - scf_vector_clear(path->childs, ( void (*)(void*) )ses_path_free); - scf_vector_free (path->childs); - } - - if (path->bridges) { - scf_vector_clear(path->bridges, ( void (*)(void*) )ses_path_free); - scf_vector_free (path->bridges); - } - - scf_logd("path: %d\n", path->index); + if (mesh) { + scf_vector_clear(mesh->edges, (void (*)(void*) )ses_edge_free); + scf_vector_free(mesh->edges); - free(path); + free(mesh); } } -void ses_path_print(ses_path_t* path) +void ses_meshs_free(scf_vector_t* meshs) { - if (!path) - return; - - ses_path_t* path2; - ScfEpin* p; - - int i; - - if (!path->parent) - printf("\033[31mpath : %d, n_diodes: %d, infos->size: %d, \033[0m", path->index, path->n_diodes, path->infos->size); - - for (i = 0; i < path->pins->size; i++) { - p = path->pins->data[i]; - - printf("c%ldp%ldd%d ", p->cid, p->id, p->n_diodes); - } - printf("\n"); - - if (path->childs) { - for (i = 0; i < path->childs->size; i++) { - path2 = path->childs->data[i]; - - printf("\033[32mchild : %d, n_diodes: %d, infos->size: %d, parent: %d, \033[0m", path2->index, path2->n_diodes, path2->infos->size, path->index); - - ses_path_print(path2); - } - } - - if (path->bridges) { - for (i = 0; i < path->bridges->size; i++) { - path2 = path->bridges->data[i]; - - printf("\033[33mbridge: %d, n_diodes: %d, infos->size: %d, parent: %d, \033[0m", path2->index, path2->n_diodes, path2->infos->size, path->index); - - ses_path_print(path2); - } - } -} - -int ses_path_xchg(ses_path_t* path0, int k0, ses_path_t* path1, int k1) -{ - ScfEpin* p; - - int i; - - for (i = 0; i + k0 < path0->pins->size && i + k1 < path1->pins->size; i++) - SCF_XCHG(path0->pins->data[i + k0], path1->pins->data[i + k1]); - - scf_logd("path0: %d, k0: %d ... path1: %d, k1: %d, i: %d\n", path0->pins->size, k0, path1->pins->size, k1, i); - - if (i + k0 < path0->pins->size) { - - while (i + k0 < path0->pins->size) { - p = path0->pins->data[i + k0]; - - assert(0 == scf_vector_del(path0->pins, p)); - - if (scf_vector_add(path1->pins, p) < 0) - return -ENOMEM; - } - - } else if (i + k1 < path1->pins->size) { - - while (i + k1 < path1->pins->size) { - p = path1->pins->data[i + k1]; - - assert(0 == scf_vector_del(path1->pins, p)); - - if (scf_vector_add(path0->pins, p) < 0) - return -ENOMEM; - } + if (meshs) { + scf_vector_clear(meshs, (void (*)(void*) )ses_mesh_free); + scf_vector_free(meshs); } - - return 0; } -int ses_path_add(ses_path_t* parent, ses_path_t* child, ScfEfunction* f) +void ses_mesh_print(ses_mesh_t* mesh) { - if (!parent || !child) - return -EINVAL; - - if (!parent->childs) { - parent->childs = scf_vector_alloc(); - if (!parent->childs) - return -ENOMEM; - } - - ses_path_t* path; - ScfEpin* p0; - ScfEpin* p1; - ScfEpin* cp0 = child->pins->data[0]; - ScfEpin* cp1 = child->pins->data[child->pins->size - 1]; - - 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 * 2 - && path->pins->size > path->n_diodes * 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; - - for (j = 0; j < parent->pins->size; j++) { - p0 = parent->pins->data[j]; - - if (p0->lid == cp0->lid) { - child->parent_p0 = (j + 1) & ~0x1; - break; - } - } - assert(j < parent->pins->size); - - int n_capacitors = 0; - - for ( ; j < parent->pins->size; j++) { - p0 = parent->pins->data[j]; - - if (!(j & 0x1)) { - ScfEcomponent* c = f->components[p0->cid]; - - if (SCF_EDA_Capacitor == c->type) - n_capacitors++; - } - - if (p0->lid == cp1->lid) { - child->parent_p1 = j; - break; - } - } - assert(j < parent->pins->size); - - if (n_capacitors > 0 && 0 == child->n_capacitors) { - - int ret = ses_path_xchg(parent, child->parent_p0, child, 0); - if (ret < 0) - return ret; - - j = child->parent_p1 - child->parent_p0 + 1; - child->parent_p1 = parent->pins->size - 1; - - while (j < child->pins->size) { - p0 = child->pins->data[j]; - - assert(0 == scf_vector_del(child->pins, p0)); - - ret = scf_vector_add(parent->pins, p0); - if (ret < 0) - return ret; - } - - child ->n_capacitors = n_capacitors; - parent->n_capacitors -= n_capacitors; - } - - child->parent = parent; - child->type = SES_PATH_BRANCH; - return 0; -} + if (!mesh) + return; -ses_path_t* ses_path_save(ses_path_t* src) -{ - ses_path_t* dst = ses_path_alloc(); - if (!dst) - return NULL; - - ScfEpin* p; - ScfEpin* p2; + ses_edge_t* edge; int i; - for (i = 0; i < src->pins->size; i++) { - p = src->pins->data[i]; - - p2 = malloc(sizeof(ScfEpin)); - if (!p2) { - scf_vector_clear(dst->pins, (void (*)(void*) )free); - ses_path_free(dst); - return NULL; - } - if (scf_vector_add(dst->pins, p2) < 0) { - scf_vector_clear(dst->pins, (void (*)(void*) )free); - ses_path_free(dst); - free(p2); - return NULL; - } + for (i = 0; i < mesh->edges->size; i++) { + edge = mesh->edges->data[i]; - memcpy(p2, p, sizeof(ScfEpin)); + ses_edge_print(edge); } - - return dst; + printf("\n"); } -int ses_path_load(ses_path_t* dst, ses_path_t* src) +void ses_meshs_print(scf_vector_t* meshs) { - if (!dst || !src || dst->pins->size != src->pins->size) - return -EINVAL; - - ScfEpin* p; - ScfEpin* p2; + if (!meshs) + return; int i; - for (i = 0; i < src->pins->size; i++) { - p = src->pins->data[i]; - p2 = dst->pins->data[i]; - - if (p2->cid != p->cid || p2->id != p->id) - return -EINVAL; + for (i = 0; i < meshs->size; i++) { - memcpy(p, p2, sizeof(ScfEpin)); - } - - return 0; -} - -ses_ctx_t* ses_ctx_alloc() -{ - ses_ctx_t* ctx = calloc(1, sizeof(ses_ctx_t)); - if (!ctx) - return NULL; - - ctx->paths = scf_vector_alloc(); - if (!ctx->paths) { - free(ctx); - return NULL; - } - - return ctx; -} - -void ses_ctx_free(ses_ctx_t* ctx) -{ - if (ctx) { - if (ctx->paths) { - scf_vector_clear(ctx->paths, ( void (*)(void*) )ses_path_free); - scf_vector_free (ctx->paths); - } - - free(ctx); + ses_mesh_print(meshs->data[i]); } } @@ -795,3 +173,35 @@ void __ses_npn_dr(ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe) } else if (v > SCF_EDA_V_NPN_OFF) pb->dr = pb->r * (SCF_EDA_V_NPN_ON - SCF_EDA_V_NPN_OFF) / (v - SCF_EDA_V_NPN_OFF + 0.001); } + +void ses_elines_print(ScfEfunction* f) +{ + ScfEline* el; + + int i; + + for (i = 0; i < f->n_elines; i++) { + el = f->elines[i]; + + printf("### e%ld->v: %lg\n", el->id, el->v); + } +} + +void ses_components_print(ScfEfunction* f) +{ + ScfEcomponent* c; + ScfEpin* p; + + int i; + int j; + + for (i = 0; i < f->n_components; i++) { + c = f->components[i]; + + for (j = 0; j < c->n_pins; j++) { + p = c->pins[j]; + + printf("c%ldp%ld->v: %lg\n", p->cid, p->id, p->v); + } + } +} diff --git a/test/bridge_algorithm.c b/test/bridge_algorithm.c index c8532e4..823eab2 100644 --- a/test/bridge_algorithm.c +++ b/test/bridge_algorithm.c @@ -82,11 +82,97 @@ void bridge2() printf("Vbc + Vb + V0: %lg, V2: %lg\n", Vbc + Vb + V0, V2); } +void PNN() +{ + U0 = 6; + U1 = 0.7; + U2 = 0.7; + R0 = 10000; + R1 = 1000; + R2 = 750; + + double i1 = (R0 * (U2 - U1) + R2 * (U0 - U1)) / (R0 * R1 + R1 * R2 + R0 * R2); + double i0 = (U0 - U1 - i1 * R1) / R0; + double i2 = i0 - i1; + + double V0 = i0 * R0; + double V1 = i1 * R1; + double V2 = i2 * R2; + + printf("R0: %lg, i0: %lg, V0: %lg\n", R0, i0, V0); + printf("R1: %lg, i1: %lg, V1: %lg\n", R1, i1, V1); + printf("R2: %lg, i2: %lg, V2: %lg\n", R2, i2, V2); + + printf("V0 + V1: %lg, U0 - U1: %lg\n", V0 + V1, U0 - U1); + printf("V0 + V2: %lg, U0 - U2: %lg\n", V0 + V2, U0 - U2); +} + +void PPN() +{ + U0 = 6; + U1 = 0.7; + U2 = 5.3; + R0 = 2000; + R1 = 10000; + R2 = 750; + + double i1 = (R0 * (U2 - U1) + R2 * (U0 - U1)) / (R0 * R1 + R1 * R2 + R0 * R2); + double i0 = (U0 - U1 - i1 * R1) / R0; + double i2 = i1 - i0; + + double V0 = i0 * R0; + double V1 = i1 * R1; + double V2 = i2 * R2; + + printf("R0: %lg, i0: %lg, V0: %lg\n", R0, i0, V0); + printf("R1: %lg, i1: %lg, V1: %lg\n", R1, i1, V1); + printf("R2: %lg, i2: %lg, V2: %lg\n", R2, i2, V2); + + printf("U0 - V0: %lg, U2 - V2: %lg, U1 + V1: %lg\n", U0 - V0, U2 - V2, U1 + V1); +} + +void add() +{ + double R0 = 1000; + double R1 = 10000; + double R = R0 + R1 / 4; + double U = 6; + + double i0 = U / R; + double i1 = (U - i0 * R0) / R1; + + double r = R1 + (R0 * R1 / 3) / (R0 + R1 / 3); + double i3 = U / r; + double i2 = (U - i3 * R1) / R0; + double i4 = (U - i3 * R1) / R1; + + double I0 = i0 - i2; + double I3 = i3 - i1; + double I4 = i1 + i4; + + double V0 = I0 * R0; + double V3 = I3 * R1; + double V4 = I4 * R1; + + printf("R0: %lg, i0: %lg, i2: %lg, I0: %lg, V0: %lg\n", R0, i0, i2, I0, V0); + printf("R3: %lg, i3: %lg, i1: %lg, I3: %lg, V3: %lg\n", R1, i3, i1, I3, V3); + printf("R4: %lg, i4: %lg, i1: %lg, I4: %lg, V4: %lg\n", R1, i4, i1, I4, V4); +} + int main() { bridge(); printf("---------------\n\n"); bridge2(); + printf("---------------\n\n"); + + PNN(); + printf("---------------\n\n"); + + PPN(); + printf("---------------\n\n"); + + add(); return 0; } diff --git a/test/main.c b/test/main.c index 1afc2b5..4e0a284 100644 --- a/test/main.c +++ b/test/main.c @@ -70,7 +70,7 @@ int main(int argc, char* argv[]) 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 = 50; + T0->pins[SCF_EDA_NPN_C]->hfe = 80; R1->r = 1000 * 10; R2->r = 1000 * 10; @@ -92,7 +92,7 @@ int main(int argc, char* argv[]) ScfEboard_free(b); b = NULL; - FILE* fp = fopen("./sin_oscillator.pack", "wb"); + FILE* fp = fopen("./sin_oscillator.cpk", "wb"); if (!fp) return -EINVAL;