CFILES += ses_step_va.c
CFILES += ses_step_va_bridge.c
CFILES += ses_step_va_balance.c
+CFILES += ses_step_da.c
CFILES += ses_step_output.c
CFLAGS += -g -D_GNU_SOURCE
scf_vector_t* paths;
ScfEpin* vip;
+ ScfEpin* vip_n;
int pos_pins;
int neg_pins;
double a;
double ja;
+ double da;
+ double dja;
+
int type;
int index;
void ses_flow_v_pos(ses_flow_t* flow, double a, double ja);
void ses_flow_v_neg(ses_flow_t* flow, double a, double ja);
-void ses_flow_jr (ses_flow_t* flow);
+void ses_flow_jr (ses_flow_t* flow, ScfEfunction* f);
ses_ctx_t* ses_ctx_alloc();
void ses_ctx_free (ses_ctx_t* ctx);
int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, ses_path_t* bridge);
void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double la, double jla, double* a, double* ja);
-void __ses_path_pr (ScfEfunction* f, ses_path_t* path, int i, int j, ScfEpin* cp1, double* r, double* jr);
-void __ses_path_sr (ScfEfunction* f, ses_path_t* path, int i, int j, ScfEpin* cp1, double* r, double* jr);
-int __ses_path_va (ScfEfunction* f, ses_path_t* path, int *changed);
-int __ses_path_pos (ScfEfunction* f, ScfEline* el);
-int __ses_path_neg (ScfEfunction* f, ScfEline* el);
-
int __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe);
int __ses_topo_paths (ScfEfunction* f, scf_vector_t* paths);
+int __ses_path_jr (ScfEfunction* f, ses_path_t* path);
+void __ses_path_pr (ScfEfunction* f, ses_path_t* path, int i, int j, ScfEpin* cp1, double* r, double* jr);
+void __ses_path_sr (ScfEfunction* f, ses_path_t* path, int i, int j, ScfEpin* cp1, double* r, double* jr);
+int __ses_path_va (ScfEfunction* f, ses_path_t* path, int *changed);
+int __ses_path_da (ScfEfunction* f, ses_path_t* path, int *changed, double da, double dja);
+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, double* jr);
+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)
{
/*
--- /dev/null
+#include"ses_core.h"
+
+static int __ses_path_split_da(ScfEfunction* f, ses_path_t* path, int i, double* da, double *dja, int* changed)
+{
+ ses_path_t* child;
+
+ ScfEcomponent* c;
+ ScfEline* el;
+ ScfEpin* p;
+ ScfEpin* p2;
+ ScfEpin* cp0;
+ ScfEpin* cp1;
+
+ int j;
+ int k;
+ int n = 0;
+
+ p = path->pins->data[i];
+
+ for (j = 0; j < path->childs->size; j++) {
+ child = path->childs->data[j];
+
+ cp0 = child->pins->data[0];
+ cp1 = child->pins->data[child->pins->size - 1];
+
+ if (p->lid != cp0->lid)
+ continue;
+
+ for (k = i + 1; k < path->pins->size; k++) {
+ p2 = path->pins->data[k];
+
+ if (p2->lid == cp1->lid)
+ break;
+ }
+
+ if (k >= path->pins->size) {
+ scf_loge("\n");
+ return -EINVAL;
+ }
+
+ double _r = p2->pr - p->pr;
+ double _jr = p2->jpr - p->jpr;
+
+ double _dv = 0;
+ double _djv = 0;
+ double _da = 0;
+ double _dja = 0;
+
+ __ses_path_pr(f, path, i, k, cp1, &_r, &_jr);
+
+ ses_ir_u(&_dv, &_djv, *da, *dja, _r, _jr);
+
+ scf_logw("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld), _dv: %lg, da: %lg, _r: %lg, p->pr: %lg, p->dr: %lg, p2->pr: %lg\n",
+ child->index, p->cid, p->id, p2->cid, p2->id, cp0->cid, cp0->id, cp1->cid, cp1->id, _dv, *da, _r, p->pr, p->dr, p2->pr);
+
+ ses_ur_i(&_da, &_dja, _dv, _djv, child->r, child->jr);
+
+ *da -= _da;
+ *dja -= _dja;
+
+ el = f->elines[p2->lid];
+ el->v -= _dv;
+ el->jv -= _djv;
+
+ scf_loge("child: %d, c%ldp%ld, c%ldp%ld, p->v: %lg, el->v: %lg, _dv: %lg\n",
+ child->index, p->cid, p->id, p2->cid, p2->id, p->v, el->v, _dv);
+
+ int ret = __ses_path_da(f, child, changed, _da, _dja);
+ if (ret < 0)
+ return ret;
+
+ n++;
+ }
+
+ scf_logw("*****************\n");
+ return n;
+}
+
+static void __ses_path_split_dv(ScfEfunction* f, ses_path_t* path, int i0, int i, double da, double dja)
+{
+ ScfEcomponent* B = f->components[0];
+ ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS];
+ ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG];
+ ScfEpin* p0 = path->pins->data[i0];
+ ScfEpin* p = path->pins->data[i];
+
+ double dv;
+ double djv;
+ double r;
+ double jr;
+
+ __ses_path_sr(f, path, i0, i, NULL, &r, &jr);
+
+ ses_ir_u(&dv, &djv, da, dja, r, jr);
+
+ if (p->lid != Bp->lid && p->lid != Bn->lid) {
+ p->v -= dv;
+ p->jv -= djv;
+ }
+
+ scf_logd("c%ldp%ld, c%ldp%ld, da: %lg, r: %lg, dv: %lg\n", p0->cid, p0->id, p->cid, p->id, da, r, dv);
+}
+
+void __ses_pn_dr(ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe)
+{
+ double v = pb->v - pe->v;
+ double jv = pb->jv - pe->jv;
+ double r;
+ double jr;
+
+ if (v >= SCF_EDA_V_Diode_ON) {
+
+ ses_ui_r(&r, &jr, v, jv, pb->a, pb->ja);
+ pe->dr = r - pe->r;
+
+ } else if (v > SCF_EDA_V_Diode_OFF)
+ pe->dr = pb->r * (SCF_EDA_V_Diode_ON - SCF_EDA_V_Diode_OFF) / (v - SCF_EDA_V_Diode_OFF + 0.001);
+ else
+ pe->dr = 1e12;
+}
+
+void __ses_npn_dr(ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe)
+{
+ double v = pb->v - pe->v;
+ double jv = pb->jv - pe->jv;
+ double r;
+ double jr;
+
+ if (v >= SCF_EDA_V_NPN_ON) {
+
+ ses_ui_r(&r, &jr, v, jv, pb->a, pb->ja);
+ pb->dr = r - pb->r;
+
+ } 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);
+ else
+ pb->dr = 1e12;
+
+ scf_loge("v: %lg, pb->dr: %lg\n", v, pb->dr);
+}
+
+int __ses_path_da(ScfEfunction* f, ses_path_t* path, int* changed, double da, double dja)
+{
+ if (!path)
+ return -EINVAL;
+
+ if (path->pins->size < 2) {
+ scf_loge("\n");
+ return -EINVAL;
+ }
+
+ ses_path_t* child;
+ ScfEcomponent* c;
+ ScfEline* el;
+ ScfEpin* p;
+ ScfEpin* p0;
+ ScfEpin* p1;
+ ScfEpin* p2;
+ ScfEpin* cp0;
+ ScfEpin* cp1;
+
+ int i;
+ int j;
+
+ double r = 0;
+ double jr = 0;
+ double dv = 0;
+ double jdv = 0;
+
+ path->da = da;
+ path->dja = dja;
+
+ int i0 = 0;
+
+ for (i = 0; i < path->pins->size; i++) {
+ p = path->pins->data[i];
+
+ if (!(i & 0x1) && path->childs) {
+
+ __ses_path_split_dv(f, path, i0, i, da, dja);
+
+ int ret = __ses_path_split_da(f, path, i, &da, &dja, changed);
+ if (ret < 0)
+ return ret;
+
+ if (ret > 0) {
+ p0 = p;
+ i0 = i;
+ scf_logd("i: %d, p0: c%ldp%ld\n", i, p0->cid, p0->id);
+ }
+ } else
+ __ses_path_split_dv(f, path, i0, i, da, dja);
+
+ el = f->elines[p->lid];
+ el->v = p->v;
+ el->jv = p->jv;
+
+ r += p->r + p->dr;
+ jr += p->jr + p->jdr;
+
+ if (i & 0x1) {
+ c = f->components[p->cid];
+ r += c->r;
+ jr += c->jr;
+
+ dv -= p->v;
+ jdv -= p->jv;
+
+ p->a += da;
+ p->ja += dja;
+
+ p2 = path->pins->data[i - 1];
+ p2->a += da;
+ p2->ja += dja;
+
+ if (path->childs) {
+ for (j = 0; j < path->childs->size; j++) {
+ child = path->childs->data[j];
+
+ cp0 = child->pins->data[0];
+ cp1 = child->pins->data[child->pins->size - 1];
+
+ if (p->lid == cp1->lid) {
+ da += child->da;
+ dja += child->dja;
+
+ scf_logd("path: %d, i: %d, c%ldp%ld, child->da: %lg\n", child->index, i, cp1->cid, cp1->id, child->da);
+ }
+ }
+ }
+
+ scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, r: %lg, p->a: %lg, da: %lg, p->pr: %lg\n\n", path->index, i, p->cid, p->id,
+ p->v, dv, r, p->a, da, p->pr);
+
+ if (SCF_EDA_Diode == c->type) {
+
+ if (SCF_EDA_Diode_NEG == p->id) {
+ p2 = path->pins->data[i - 1];
+
+ *changed += __ses_status_check(f, c, p2, p);
+
+ __ses_pn_dr(c, p2, p);
+ }
+
+ } else if (SCF_EDA_NPN == c->type) {
+
+ if (SCF_EDA_NPN_E == p->id) {
+ p2 = path->pins->data[i - 1];
+
+ if (SCF_EDA_NPN_B == p2->id) {
+ *changed += __ses_status_check(f, c, p2, p);
+
+ __ses_npn_dr(c, p2, p);
+ }
+ }
+ }
+
+ r = 0;
+ jr = 0;
+ } else {
+ dv = p->v;
+ jdv = p->jv;
+
+ scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, p->a: %lg, da: %lg, p->pr: %lg\n", path->index, i, p->cid, p->id, p->v, dv, p->a, da, p->pr);
+ }
+ }
+ printf("\n");
+
+ return 0;
+}
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);
}
-static int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
+int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
{
if (!path)
return -EINVAL;
if (SCF_EDA_Diode_NEG == p->id) {
p2 = path->pins->data[i - 1];
+
*changed += __ses_status_check(f, c, p2, p);
+
+ __ses_pn_dr(c, p2, p);
}
} else if (SCF_EDA_NPN == c->type) {
if (SCF_EDA_NPN_E == p->id) {
p2 = path->pins->data[i - 1];
- if (SCF_EDA_NPN_B == p2->id)
+ if (SCF_EDA_NPN_B == p2->id) {
*changed += __ses_status_check(f, c, p2, p);
+
+ __ses_npn_dr(c, p2, p);
+ }
}
}
ses_flow_print(flow0);
printf("\n");
- ses_flow_jr(flow0);
+ ses_flow_jr(flow0, f);
printf("-------------\n");
ses_flow_print(flow1);
printf("\n");
- ses_flow_jr(flow1);
+ ses_flow_jr(flow1, f);
printf("-------------\n");
ret = __ses_path_va_balance(f, bridge, flow0, flow1);
#include"ses_core.h"
-int __ses_flow_a_pos(ScfEfunction* f, ses_flow_t* flow, double da_vip, double dja_vip)
+int __ses_flow_a_pos(ScfEfunction* f, ses_flow_t* flow, double da_vip, double dja_vip, int* changed)
{
if (!flow || !flow->paths || flow->paths->size <= 0 || !flow->vip)
return -EINVAL;
ses_ir_u(&v, &jv, da_vip, dja_vip, r, jr);
}
- if (p->lid != Bp->lid) {
+ if (p->v - v < Bp->lid) {
p->v -= v;
p->jv -= jv;
el->v = p->v;
el->jv = p->jv;
}
- scf_logw("c%ldp%ld->v: %lg, r: %lg, l%ld->v: %lg\n", p->cid, p->id, p->v, r, el->id, el->v);
+
+ p->a += da_vip;
+ p->ja += dja_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;
return 0;
}
-int __ses_flow_v_neg(ScfEfunction* f, ses_flow_t* flow, double dv_vip, double djv_vip)
+int __ses_flow_v_neg(ScfEfunction* f, ses_flow_t* flow, double dv_vip, double djv_vip, int* changed)
{
if (!flow || !flow->paths || flow->paths->size <= 0 || !flow->vip)
return -EINVAL;
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;
ses_ir_u(&v, &jv, da, dja, r, jr);
}
- if (p->lid != Bn->lid) {
+ if (p->v + v > Bn->lid) {
p->v += v;
p->jv += jv;
el->jv = p->jv;
}
- scf_logw("c%ldp%ld->v: %lg, r: %lg, v: %lg, l%ld->v: %lg\n", p->cid, p->id, p->v, r, v, el->id, el->v);
+ p->a += da;
+ p->ja += dja;
+
+ scf_logw("c%ldp%ld->v: %lg, p->a: %lg, r: %lg, v: %lg, l%ld->v: %lg\n", p->cid, p->id, p->v, p->a, r, v, el->id, el->v);
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);
+
+ __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);
+
+ __ses_npn_dr(c, p2, p);
+ }
+ }
+ }
+
r = 0;
jr = 0;
}
ses_flow_t* flow;
ses_path_t* fpath;
- ScfEpin* fp0;
- ScfEpin* fp1;
ScfEcomponent* B;
ScfEline* el;
if (p0->lid == Bp->lid && p1->lid == Bn->lid)
return 0;
- el = f->elines[p0->lid];
- p0->v = el->v;
- p0->jv = el->jv;
-
- el = f->elines[p1->lid];
- p1->v = el->v;
- p1->jv = el->jv;
-
flow = ses_flow_alloc();
if (!flow)
return -ENOMEM;
}
ses_flow_print(flow);
- ses_flow_jr(flow);
+ ses_flow_jr(flow, f);
fpath = flow->paths->data[flow->paths->size - 1];
- fp0 = fpath->pins->data[0];
- fp1 = fpath->pins->data[fpath->pins->size - 1];
- scf_logw("flow vip: c%ldp%ld->a: %lg, fp0: c%ldp%ld->a: %lg, fp1: c%ldp%ld->a: %lg\n\n",
- flow->vip->cid, flow->vip->id, flow->vip->a, fp0->cid, fp0->id, fp0->a, fp1->cid, fp1->id, fp1->a);
+ scf_logw("flow vip: c%ldp%ld->a: %lg, vip_n: c%ldp%ld->a: %lg\n\n",
+ flow->vip->cid, flow->vip->id, flow->vip->a, flow->vip_n->cid, flow->vip_n->id, flow->vip_n->a);
double da;
double dja;
double a = 0;
double ja = 0;
- double Eta = 0.01;
+ double Eta = 0.001;
int k = 0;
do {
scf_logw("k: %d, ****************\n", k);
+ el = f->elines[p0->lid];
+ p0->v = el->v;
+ p0->jv = el->jv;
+
+ el = f->elines[p1->lid];
+ p1->v = el->v;
+ p1->jv = el->jv;
+
ret = __ses_path_va(f, bridge, changed);
if (ret < 0)
return ret;
+ __ses_path_jr(f, bridge);
+
da = bridge->a - a;
dja = bridge->ja - ja;
a += Eta * da;
ja += Eta * dja;
- scf_loge("da: %lg, a: %lg\n", da, a);
+ scf_loge("da: %lg, a: %lg, bridge->a: %lg, bridge->r: %lg, p0->v: %lg, p1->v: %lg\n",
+ da, a, bridge->a, bridge->r, p0->v, p1->v);
v = flow->vip->v;
jv = flow->vip->jv;
- ret = __ses_flow_a_pos(f, flow, Eta * da, Eta * dja);
+ ret = __ses_flow_a_pos(f, flow, Eta * da, Eta * dja, changed);
if (ret < 0)
return ret;
scf_logi("dv: %lg, v: %lg - %lg ----------------\n", dv, flow->vip->v, v);
- ret = __ses_flow_v_neg(f, flow, dv, djv);
+ ret = __ses_flow_v_neg(f, flow, dv, djv, changed);
if (ret < 0)
return ret;
- printf("\n");
+
+ __ses_path_jr(f, fpath);
+ ses_flow_jr(flow, f);
+
+ 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);
k++;
- } while (da > 1e-4);
+ } while (fabs(flow->vip->a - flow->vip_n->a - bridge->a) > 1e-4);
v = p0->v - p1->v;
jv = p0->jv - p1->jv;
return ret;
int j;
- for (j = 0; j < 1; j++) {
+ for (j = 0; j < 3; j++) {
printf("\n\033[33m%s(), %d(), j: %d\033[0m\n", __func__, __LINE__, j);
ret = __ses_steps_analyse(f, ns, i, ctx);
p = path->pins->data[j];
if (vip ->lid == p->lid) {
- flow->vip = p;
+
+ if (j + 1 >= path->pins->size) {
+ scf_loge("ses_paths_find_flow error\n");
+ return -1;
+ }
+
+ flow->vip = p;
+ flow->vip_n = path->pins->data[j + 1];;
if (scf_vector_add(flow->paths, path) < 0)
return -1;
return 0;
}
-void ses_flow_jr(ses_flow_t* flow)
+void ses_flow_jr(ses_flow_t* flow, ScfEfunction* f)
{
if (!flow)
return;
if (!flow->paths || !flow->vip)
return;
- ses_path_t* path;
- ScfEpin* p;
- ScfEpin* p0;
- ScfEpin* vip = flow->vip;
+ ses_path_t* path;
+ ScfEcomponent* c;
+ ScfEpin* p;
+ ScfEpin* p0;
+ ScfEpin* vip = flow->vip;
int i;
int j;
if (p->lid == vip->lid) {
vip = path->pins->data[0];
+ c = f->components[p->cid];
+
+ double pr = p->pr;
+ double jpr = p->jpr;
- flow->pos_r += p->pr;
- flow->pos_jr += p->jpr;
+ if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id)
+ __ses_npn_epr(f, p, &pr, &jpr);
- 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);
+ flow->pos_r += pr;
+ flow->pos_jr += jpr;
+
+ 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;
}
}
++flow->neg_pins;
- if (p->sr != p->pr) {
+ c = f->components[p->cid];
+
+ if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id) {
+ p = path->pins->data[j - 1];
+
+ if (p == p0) {
+ flow->neg_r += p->r + p->dr;
+ flow->neg_jr += p->jr + p->jdr;
+ } else {
+ flow->neg_r += p->pr - p0->pr;
+ flow->neg_jr += p->jpr - p0->jpr;
+ }
+
+ scf_loge("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];
+ else
+ p0 = path->pins->data[j];
+
+ } else if (p->sr != p->pr) {
flow->neg_r += p->sr - p0->pr;
flow->neg_jr += p->jsr - p0->jpr;
- scf_logd("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+ scf_logw("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);
-
p0 = p;
}
}
if (vip != p0) {
flow->neg_r += vip->sr - p0->pr;
flow->neg_jr += vip->jsr - p0->jpr;
+ scf_loge("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);
}
- scf_logd("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+ scf_logi("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);
}