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
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./
LDFLAGS += -lm
LDFLAGS += -lcairo
+LDFLAGS += -lgsl -lgslcblas
all:
gcc $(CFLAGS) $(CFILES) $(LDFLAGS)
printf("f: %s\n", f->name);
- ses_steps_analyse(f, 300, 1);
+ ses_steps_analyse(f, 100, 1);
}
#endif
#include "scf_eda_pack.h"
-//#include "scf_def.h"
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},
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);
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),
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);
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),
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);
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),
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)
}
#endif
-
#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
scf_vector_t* paths;
ScfEpin* vip;
- ScfEpin* vip_n;
+ int vip_i;
+ int vip_m;
+ int vip_n;
int pos_pins;
int neg_pins;
double pos_r;
double neg_r;
+ double pos_cv;
+ double neg_cv;
+
double v;
double a;
};
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;
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;
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);
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);
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)
*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
--- /dev/null
+#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");
+}
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;
--- /dev/null
+#include"ses_core.h"
+#include <gsl/gsl_linalg.h>
+
+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;
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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,
+};
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) {
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)
double r;
double r2;
- double jr;
- double jr2;
-
int i;
int j;
}
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) {
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);
}
}
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;
}
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");
#include<cairo/cairo.h>
#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;
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);
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);
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);
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;
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)
+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;
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;
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;
}
}
+ 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);
}
__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);
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;
}
--- /dev/null
+#include<cairo/cairo.h>
+#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,
+};
--- /dev/null
+#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,
+};
#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;
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;
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);
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;
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;
continue;
}
+ // positive pin of path
p0 = sp0->pins->data[0];
p1 = sp1->pins->data[0];
|| (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)
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;
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))
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;
}
} 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--) {
} 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;
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)
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;
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;
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];
}
info->n_NPNs++;
- path->n_diodes++;
+ path->n_NPNs++;
continue;
} else if (SCF_EDA_NPN_E == p->id) {
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;
}
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++) {
} 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++;
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);
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;
}
}
}
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;
#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;
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++;
}
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);
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++;
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];
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;
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)
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;
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) {
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) {
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;
}
}
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");
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;
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];
__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;
}
+++ /dev/null
-#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,
-};
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)
ScfEpin* p1;
ScfEpin* fp0;
ScfEpin* fp1;
+ ScfEpin* fp2;
+ ScfEpin* fp3;
ScfEpin* Bp;
ScfEpin* Bn;
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);
}
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);
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);
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++) {
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;
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)
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;
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:
}
}
-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++) {
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;
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);
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];
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;
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;
__ses_path_split_i(f, path, i, j, pj->a, &pc->a);
} else
- pc->v = pj->v;
+ pc->v = pj->v;
j = i;
}
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;
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);
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[] =
// &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;
}
}
+ scf_loge("--------------- ctx->changed: %d\n", ctx->changed);
return ctx->changed > 0 ? -EAGAIN : 0;
}
#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]);
}
}
} 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);
+ }
+ }
+}
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;
}
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;
ScfEboard_free(b);
b = NULL;
- FILE* fp = fopen("./sin_oscillator.pack", "wb");
+ FILE* fp = fopen("./sin_oscillator.cpk", "wb");
if (!fp)
return -EINVAL;