CFILES += ses_step_va.c
CFILES += ses_step_va_bridge.c
CFILES += ses_step_va_line.c
-CFILES += ses_step_da.c
CFILES += ses_step_open.c
CFILES += ses_step_va_capacitor.c
printf("f: %s\n", f->name);
- ses_steps_analyse(f, 1000, 4);
+ ses_steps_analyse(f, 300, 1);
}
#endif
int n_capacitors;
int n_diodes;
+ int n_transistors;
int n_layers;
+
+ uint8_t vflag:1;
};
struct ses_ctx_s
ses_path_t* ses_path_save (ses_path_t* src);
int ses_path_load (ses_path_t* dst, ses_path_t* src);
+ses_path_t* ses_path_find_child(ses_path_t* path, int m, int n);
+
ses_flow_t* ses_flow_alloc();
void ses_flow_free (ses_flow_t* flow);
void ses_flow_print(ses_flow_t* flow);
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_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_flow_find_neg (ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f);
+
+int __ses_path_va_diode (ScfEfunction* f, ses_path_t* path);
+int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path);
+int __ses_path_va_bridge (ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns, int64_t count);
+
+void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double la, double* a);
+int __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe, int vinit);
+int __ses_topo_paths (ScfEfunction* f, scf_vector_t* paths);
-int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path);
-void __ses_path_split_i (ScfEfunction* f, ses_path_t* path, int i, int j, double la, double* a);
-int __ses_status_check (ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe, int vinit);
-int __ses_topo_paths (ScfEfunction* f, scf_vector_t* paths);
+void __ses_status_check_line(ScfEfunction* f, ScfEline* el, int* changed);
-void __ses_status_check_line(ScfEfunction* f, ScfEline* el, int* changed);
-double __ses_path_v_capacitor(ScfEfunction* f, ses_path_t* path);
+int __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv);
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 *changed, int64_t ns, int64_t count);
-int __ses_path_da (ScfEfunction* f, ses_path_t* path, int* changed, double da);
+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_pos(ScfEfunction* f, ScfEline* el);
int __ses_path_neg(ScfEfunction* f, ScfEline* el);
void __ses_npn_epr (ScfEfunction* f, ScfEpin* pe, double* r);
__ses_layout_path2(f, path, base);
+ scf_logd("path: %d, base: %d, ------------------------\n", path->index, base->index);
+
base = path;
if (base->childs) {
if (base->bridges) {
for (i = 0; i < base->bridges->size; i++) {
- path = base->childs->data[i];
+ path = base->bridges->data[i];
__ses_layout_path(f, path, base);
}
}
-
- scf_logd("path: %d, ------------------------\n\n", base->index);
}
static int __ses_layout_lines4(ScfEfunction* f)
+++ /dev/null
-#include"ses_core.h"
-
-static int __ses_path_split_da(ScfEfunction* f, ses_path_t* path, int i, double* da, 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 _dv = 0;
- double _da = 0;
-
- __ses_path_pr(f, path, i, k, child, &_r);
-
- ses_ir_u(&_dv, NULL, *da, 0, _r, 0);
-
- 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, NULL, _dv, 0, child->pr, 0);
-
- *da -= _da;
-
- el = f->elines[p2->lid];
- el->v -= _dv;
-
- 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);
- 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)
-{
- 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 r;
-
- __ses_path_sr(f, path, i0, i, &r);
-
- ses_ir_u(&dv, NULL, da, 0, r, 0);
-
- if (p->lid != Bp->lid && p->lid != Bn->lid)
- p->v -= dv;
-
- 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 r;
-
- if (v >= SCF_EDA_V_Diode_ON) {
-
- ses_ui_r(&r, NULL, v, 0, pb->a, 0);
- 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);
-}
-
-void __ses_npn_dr(ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe)
-{
- double v = pb->v - pe->v;
- double r;
-
- if (v >= SCF_EDA_V_NPN_ON) {
-
- ses_ui_r(&r, NULL, v, 0, pb->a, 0);
- 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);
-}
-
-int __ses_path_da(ScfEfunction* f, ses_path_t* path, int* changed, double da)
-{
- 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 dv = 0;
-
- path->da = da;
-
- 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);
-
- int ret = __ses_path_split_da(f, path, i, &da, 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);
-
- el = f->elines[p->lid];
- el->v = p->v;
- r += p->r + p->dr;
-
- if (i & 0x1) {
- c = f->components[p->cid];
- r += c->r;
- dv -= p->v;
-
- p->a += da;
-
- p2 = path->pins->data[i - 1];
- p2->a += da;
-
- 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;
-
- 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, 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[i - 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;
- } else {
- dv = p->v;
-
- 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;
-}
}
}
+ if (path->bridges) {
+ for (i = path->bridges->size - 1; i >= 0; i--) {
+ child = path->bridges->data[i];
+
+ cp1 = child->pins->data[child->pins->size - 1];
+
+ for (j = 0; j < path->pins->size; j++) {
+ p = path->pins->data[j];
+
+ 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;
cairo_stroke(cr);
if (el->v < SCF_EDA_V_MIN)
- snprintf(text, sizeof(text) - 1, "%lgv", B->pins[SCF_EDA_Battery_NEG]->v);
+ 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);
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)
+ return -1;
+ 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, p1, 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)
+ return -1;
+ if (p0->n_capacitors > p1->n_capacitors)
+ return 1;
+ return 0;
+}
+
static int _topo_path_connect(ScfEfunction* f, scf_vector_t* paths)
{
if (!f || !paths)
return -EINVAL;
+ scf_vector_t* vec;
ses_path_t* path0;
ses_path_t* path1;
int i;
int j;
int k;
+ int m;
- for (i = 0; i < paths->size; ) {
- path0 = paths->data[i];
+ vec = scf_vector_clone(paths);
+ if (!vec)
+ return -ENOMEM;
+
+ // qsort in 'vec' and keep the origin order in 'paths'
+ qsort_r(vec->data, vec->size, sizeof(void*), _ses_connect_cmp, f);
+
+ i = 0;
+ while (i < vec->size) {
+ path0 = vec->data[i];
p0 = path0->pins->data[0];
p1 = path0->pins->data[path0->pins->size - 1];
continue;
}
- for (j = 0; j < paths->size; j++) {
- path1 = paths->data[j];
+ for (j = 0; j < vec->size; j++) {
+ path1 = vec->data[j];
if (path1 == path0)
continue;
p = path0->pins->data[k];
if (scf_vector_add(path1->pins, p) < 0)
- return -ENOMEM;
+ goto error;
}
goto connected;
} else if (p3->lid == p1->lid) {
+
+ if (path0->n_diodes > 0 || path0->n_transistors > 0)
+ continue;
+
for (k = path0->pins->size - 1; k >= 0; k--) {
p = path0->pins->data[k];
if (scf_vector_add(path1->pins, p) < 0)
- return -ENOMEM;
+ goto error;
}
goto connected;
p = path1->pins->data[k];
if (scf_vector_add(path0->pins, p) < 0)
- return -ENOMEM;
+ goto error;
+ }
+
+ SCF_XCHG(path0->pins, path1->pins);
+ goto connected;
+
+ } else if (p2->lid == p0->lid) {
+
+ if (path0->n_diodes > 0 || path0->n_transistors > 0)
+ continue;
+
+ m = path0->pins->size - 1;
+ k = 0;
+ while (k < m) {
+ SCF_XCHG(path0->pins->data[k], path0->pins->data[m]);
+ k++;
+ m--;
+ }
+
+ for (k = 0; k < path1->pins->size; k++) {
+ p = path1->pins->data[k];
+
+ if (scf_vector_add(path0->pins, p) < 0)
+ goto error;
}
SCF_XCHG(path0->pins, path1->pins);
continue;
connected:
- if (scf_vector_del(paths, path0) < 0)
- return -1;
+ assert(0 == scf_vector_del(vec, path0));
+ assert(0 == scf_vector_del(paths, path0));
+
ses_path_free(path0);
path0 = NULL;
+ i = 0;
}
+ scf_vector_free(vec);
return 0;
+
+error:
+ scf_vector_free(vec);
+ return -ENOMEM;
}
static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths)
if (SCF_EDA_NPN_B == p->id)
path->n_diodes++;
+ else if (SCF_EDA_NPN_C == p->id)
+ path->n_transistors++;
+
} else if (SCF_EDA_Capacitor == c->type) {
if (0 == p->id)
#include"ses_core.h"
-static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, 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;
int j;
int k;
- int n = 0;
+ int n_childs = 0;
p0 = path->pins->data[i];
if (p0->lid != cp0->lid)
continue;
- for (k = i + 1; k < path->pins->size; k++) {
- p1 = path->pins->data[k];
+ for (k = i + 1; k <= n; k++) {
+ p1 = path->pins->data[k];
if (p1->lid == cp1->lid)
break;
}
- if (k >= path->pins->size) {
- scf_loge("\n");
- return -EINVAL;
- }
+ if (k > n)
+ continue;
double r;
double v;
__ses_path_jr (f, child);
}
- int ret = __ses_path_va(f, child, changed, ns, count);
+ int ret = __ses_path_va(f, child, 0, child->pins->size - 1, changed, ns, count);
if (ret < 0)
return ret;
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);
- n++;
+ n_childs++;
}
scf_logw("*****************\n");
- return n;
+ return n_childs;
}
static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i, double a)
scf_logd("c%ldp%ld, c%ldp%ld, a: %lg, r: %lg, v: %lg, p0->v: %lg, p->v: %lg\n", p0->cid, p0->id, p->cid, p->id, a, r, v, p0->v, p->v);
}
-double __ses_path_v_capacitor(ScfEfunction* f, ses_path_t* path)
+int __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv)
{
ScfEcomponent* c;
ScfEpin* p;
double v = 0;
+ int k = 0;
int i;
- for (i = 0; i < path->pins->size; i += 2) {
- p = path->pins->data[i];
+ for (i = m; i <= n; i += 2) {
+ p = path->pins->data[i];
c = f->components[p->cid];
int sign = p->id - !p->id;
v += c->v * sign;
+ k++;
}
}
- return v;
+ *cv = v;
+ return k;
}
-int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed, int64_t ns, int64_t count)
+int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed, int64_t ns, int64_t count)
{
if (!path)
return -EINVAL;
- if (path->pins->size < 2) {
+ if (path->pins->size < 2 || n - m < 1) {
scf_loge("\n");
return -EINVAL;
}
ses_path_t* child;
ScfEcomponent* c;
+ ScfEcomponent* B = f->components[0];
+ ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG];
ScfEline* el;
ScfEpin* p;
ScfEpin* p0;
int i;
int j;
- p0 = path->pins->data[0];
- p1 = path->pins->data[path->pins->size - 1];
+ 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) {
- cv = __ses_path_v_capacitor(f, path);
+ __ses_path_capacitors(f, path, m, n, &cv);
v -= cv;
- ses_ur_i(&path->a, NULL, v, 0, path->jpr, 0);
- } else
- ses_ur_i(&path->a, NULL, v, 0, path->pr, 0);
+ __ses_path_jpr(f, path, m, n, child, &pr);
+ } else {
+ __ses_path_pr(f, path, m, n, child, &pr);
+ }
+
+ 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, r: %lg, jr: %lg, a: %lg\n\n",
- path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, path->pr, path->jpr, path->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);
- double a = path->a;
- double r = 0;
- double dv = 0;
+ double r = 0;
+ double dv = 0;
+ double dv0 = 0;
+ double dv1 = 0;
+ double dvc = 0;
- int i0 = 0;
+ int i0 = m;
- for (i = 0; i < path->pins->size; i++) {
- p = path->pins->data[i];
+ for (i = m; i <= n; i++) {
+ p = path->pins->data[i];
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;
+ dv1 = 0;
+
+ double tmp = p->v;
+
if (!(i & 0x1) && path->childs) {
- int ret = __ses_path_split_a(f, path, i, &a, changed, ns, count);
+ int ret = __ses_path_split_a(f, path, i, n, &a, changed, ns, count);
if (ret < 0)
return ret;
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);
}
}
- el = f->elines[p->lid];
- el->v = p->v;
+ el = f->elines[p->lid];
+ el->v = p->v;
r += p->r + p->dr + p->jdr;
if (SCF_EDA_Capacitor == c->type) {
int sign = !p->id - p->id;
- dv -= c->v * sign;
+ 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;
- if (p->a > 0)
+ if (p->a > 0 || p->lid == Bn->lid) {
+ tmp = p2->v;
p2->v = p->v + c->v * sign;
- else
- p->v = p2->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);
el = f->elines[p2->lid];
el->v = p2->v;
__ses_status_check_line(f, el, changed);
+
+ } else if (p->a > a) {
+ p->a = a;
+
+ 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;
cp0 = child->pins->data[0];
cp1 = child->pins->data[child->pins->size - 1];
- if (p->lid == cp1->lid)
- a += child->a0;
+ if (p->lid != cp1->lid)
+ continue;
+
+ int k;
+ for (k = m; k <= n; k++) {
+ p2 = path->pins->data[k];
+
+ if (p2->lid == cp0->lid) {
+ a += child->a0;
+ break;
+ }
+ }
}
}
- 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\n\n",
+ path->index, i, p->cid, p->id, p->v, dv, r, p->a, a, p->pr);
if (SCF_EDA_Diode == c->type) {
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\n", path->index, i, p->cid, p->id, p->v, dv, a, p->pr);
+ 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);
}
}
printf("\n");
+ path->vflag = 1;
return 0;
}
__ses_path_jr(f, path);
- int ret = __ses_path_va(f, path, &changed, ns, count);
+ int ret = __ses_path_va(f, path, 0, path->pins->size - 1, &changed, ns, count);
if (ret < 0)
return ret;
}
__changed = 0;
- int ret = __ses_path_va(f, bridge, &__changed, ns, count);
+ int ret = __ses_path_va(f, bridge, 0, bridge->pins->size - 1, &__changed, ns, count);
if (ret < 0)
return ret;
return 0;
}
-static int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns, int64_t count)
+int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns, int64_t count)
{
- if (!bridge)
- return -EINVAL;
-
- if (bridge->pins->size < 2) {
- scf_loge("\n");
- return -EINVAL;
- }
-
- ses_flow_t* flow;
+ ses_flow_t* flow0;
+ ses_flow_t* flow1;
ses_path_t* fpath;
ses_info_t* info;
__ses_path_jr(f, bridge);
- flow = ses_flow_alloc();
- if (!flow)
+ flow0 = ses_flow_alloc();
+ if (!flow0)
return -ENOMEM;
- int ret = ses_paths_find_flow(flow, paths, p0, bridge);
+ int ret = ses_paths_find_flow(flow0, paths, p0, bridge);
if (ret < 0) {
- ses_flow_free(flow);
+ ses_flow_free(flow0);
return ret;
}
- ses_flow_print(flow);
- ses_flow_jr(flow, f);
+ 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;
+ }
- fpath = flow->paths->data[flow->paths->size - 1];
+ ses_flow_print(flow0);
+ ses_flow_jr(flow0, f);
+ printf("\n");
- scf_logw("flow vip: c%ldp%ld->a: %lg, v:%lg, vip_n: c%ldp%ld->a: %lg, v: %lg\n\n",
- flow->vip->cid, flow->vip->id, flow->vip->a, flow->vip->v, flow->vip_n->cid, flow->vip_n->id, flow->vip_n->a, flow->vip_n->v);
+ ses_flow_print(flow1);
+ ses_flow_jr(flow1, f);
+ printf("\n");
double v;
double jv;
__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, &__changed, ns, count);
+ ret = __ses_path_va(f, bridge, 0, bridge->pins->size - 1, &__changed, ns, count);
if (ret < 0)
return ret;
#if 0
}
}
+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)
+{
+ 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;
+}
+
static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_t* bridge, int* changed, int64_t ns, int64_t count)
{
ses_flow_t* flow0;
ses_path_t* fpath;
ScfEcomponent* B;
- ScfEcomponent* c;
ScfEline* el;
ScfEpin* p0;
ScfEpin* p1;
+ ScfEpin* fp0;
+ ScfEpin* fp1;
ScfEpin* Bp;
ScfEpin* Bn;
- int i;
- int j;
+ if (bridge->vflag)
+ return 0;
B = f->components[0];
Bp = B->pins[SCF_EDA_Battery_POS];
if (p0->lid == Bp->lid && p1->lid == Bn->lid)
return 0;
- __ses_path_jr(f, bridge);
+ scf_loge("c%ldp%ld-c%ldp%ld-------------------------\n", p0->cid, p0->id, p1->cid, p1->id);
flow0 = ses_flow_alloc();
if (!flow0)
}
ret = ses_paths_find_flow(flow1, paths, p1, bridge);
- if (ret < 0) {
- ses_flow_free(flow0);
- ses_flow_free(flow1);
- return ret;
+ if (ret < 0)
+ goto error;
+
+ if (flow0->paths->size > 0) {
+ fpath = flow0->paths->data[flow0->paths->size - 1];
+
+ if (!fpath->vflag) {
+ ret = __ses_path_va_capacitor(f, paths, fpath, changed, ns, count);
+ if (ret < 0)
+ goto error;
+ }
}
- ses_flow_print(flow0);
- ses_flow_jr(flow0, f);
- printf("\n");
+ if (flow1->paths->size > 0) {
+ fpath = flow1->paths->data[flow1->paths->size - 1];
- ses_flow_print(flow1);
- ses_flow_jr(flow1, f);
- printf("\n");
+ if (!fpath->vflag) {
+ ret = __ses_path_va_capacitor(f, paths, fpath, changed, ns, count);
+ if (ret < 0)
+ goto error;
+ }
+ }
- double jr;
- double jv;
+ double R;
double cv;
double ja;
+ __ses_path_jr(f, bridge);
+
el = f->elines[p0->lid];
p0->v = el->v;
el = f->elines[p1->lid];
p1->v = el->v;
- cv = __ses_path_v_capacitor(f, bridge);
+ __ses_path_capacitors(f, bridge, 0, bridge->pins->size - 1, &cv);
scf_logw("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg\n", p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v);
if (p0->v - p1->v > cv) {
- jv = Bp->v - cv;
- jr = flow0->pos_r + flow1->neg_r + bridge->jpr;
- ja = jv / jr;
+ 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;
+
+ ses_flow_print(flow0);
+ ses_flow_jr(flow0, f);
+ printf("\n");
+
+ ses_flow_print(flow1);
+ ses_flow_jr(flow1, f);
+ printf("\n");
+
+ R = bridge->jpr * flow1->pos_r / (bridge->jpr + flow1->pos_r);
+
+ ja = Bp->v / (R + flow1->neg_r);
+ p0->v = Bp->v;
+ p1->v = Bp->v - ja * R;
+
+ } else if (p1->lid == Bn->lid) {
+
+ ret = ses_flow_find_pos(flow0, paths, f);
+ if (ret < 0)
+ goto error;
+
+ ret = ses_flow_find_neg(flow0, paths, f);
+ if (ret < 0)
+ goto error;
+
+ ses_flow_print(flow0);
+ ses_flow_jr(flow0, f);
+ printf("\n");
+
+ ses_flow_print(flow1);
+ ses_flow_jr(flow1, f);
+ printf("\n");
+
+ R = bridge->jpr * flow0->neg_r / (bridge->jpr + flow0->neg_r);
+
+ ja = Bp->v / (R + flow0->pos_r);
+ p0->v = Bp->v - ja * flow0->pos_r;
+ p1->v = Bn->v;
+
+ 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");
+
+ ses_flow_print(flow1);
+ ses_flow_jr(flow1, f);
+ printf("\n");
+
+ fpath = flow0->paths->data[flow0->paths->size - 1];
+ fp0 = fpath->pins->data[0];
+ fp1 = fpath->pins->data[fpath->pins->size - 1];
+
+ double U0 = fp0->v;
+ double U1 = fp1->v;
- p0->v = Bp->v - ja * flow0->pos_r;
- p1->v = Bn->v + ja * flow1->neg_r;
+ fpath = flow1->paths->data[flow1->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, jr: %lg, jv: %lg, ja: %lg\n\n",
- p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, jr, jv, ja);
+ double U2 = fp0->v;
+ double U3 = fp1->v;
+ 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);
+ }
+
+ 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 {
- jv = Bp->v + cv;
- jr = flow1->pos_r + flow0->neg_r + bridge->jpr;
- ja = jv / jr;
+ assert(p0->lid != Bp->lid);
+
+ if (p1->lid == Bn->lid) {
+
+ ret = ses_flow_find_neg(flow1, paths, f);
+ if (ret < 0)
+ goto error;
+
+ ses_flow_print(flow0);
+ ses_flow_jr(flow0, f);
+ printf("\n");
+
+ ses_flow_print(flow1);
+ ses_flow_jr(flow1, f);
+ printf("\n");
+
+ R = bridge->jpr + flow0->neg_r;
+ ja = (cv - p0->v) / R;
+ p1->v = Bn->v;
+
+ } else {
+ ses_flow_print(flow0);
+ ses_flow_jr(flow0, f);
+ printf("\n");
- p1->v = Bp->v - ja * flow1->pos_r;
- p0->v = Bn->v + ja * flow0->neg_r;
+ ses_flow_print(flow1);
+ ses_flow_jr(flow1, f);
+ printf("\n");
- scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, jr: %lg, jv: %lg, ja: %lg\n\n",
- p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, jr, jv, ja);
+ fpath = flow1->paths->data[flow1->paths->size - 1];
+ fp0 = fpath->pins->data[0];
+ fp1 = fpath->pins->data[fpath->pins->size - 1];
+
+ double U0 = fp0->v;
+ double U1 = fp1->v;
+
+ fpath = flow0->paths->data[flow0->paths->size - 1];
+ fp0 = fpath->pins->data[0];
+ fp1 = fpath->pins->data[fpath->pins->size - 1];
+
+ double U2 = fp0->v;
+ double U3 = fp1->v;
+
+ 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);
+ }
+
+ 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 = f->elines[p1->lid];
el->v = p1->v;
- ret = __ses_path_va(f, bridge, changed, ns, count);
+ ret = __ses_path_va(f, bridge, 0, bridge->pins->size - 1, changed, ns, count);
if (ret < 0) {
scf_loge("\n");
- return ret;
+ goto error;
}
__ses_status_check_line(f, f->elines[p0->lid], changed);
__ses_status_check_line(f, f->elines[p1->lid], changed);
- return 0;
+ ret = 0;
+error:
+ ses_flow_free(flow0);
+ ses_flow_free(flow1);
+ return ret;
}
static int ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_t* bridge, int* changed, int64_t ns, int64_t count)
}
if (bridge->bridges) {
- for (j = 0; j < bridge->childs->size; j++) {
- child = bridge->childs->data[j];
+ for (j = 0; j < bridge->bridges->size; j++) {
+ child = bridge->bridges->data[j];
ret = ses_path_va_capacitor(f, paths, child, changed, ns, count);
if (ret < 0)
}
}
+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)
{
ses_info_t* info;
+ ses_path_t* child;
ScfEpin* p0 = path->pins->data[0];
ScfEpin* p1 = path->pins->data[path->pins->size - 1];
v -= info->n_diodes * SCF_EDA_V_Diode_ON;
v -= info->n_NPNs * SCF_EDA_V_NPN_ON;
- __ses_path_pr(f, path, i, info->i, NULL, &_r);
+ child = ses_path_find_child(path, i, info->i);
+
+ __ses_path_pr(f, path, i, info->i, child, &_r);
r += _r;
i = info->j;
}
- scf_logd("c%ldp%ld--c%ldp%ld, r: %lg, v: %lg\n", p0->cid, p0->id, p1->cid, p1->id, r, v);
+ j = path->pins->size - 1;
- if (i < path->pins->size - 1) {
+ if (i < j) {
pi = path->pins->data[i];
+ pj = path->pins->data[j];
- __ses_path_pr(f, path, i, path->pins->size - 1, NULL, &_r);
+ child = ses_path_find_child(path, i, j);
+
+ __ses_path_pr(f, path, i, j, child, &_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);
}
ses_ur_i(a, NULL, v, 0, r, 0);
return 1;
}
-static int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
+int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
{
ses_path_t* parent = path->parent;
ses_path_t* child;
ScfEpin* p;
ScfEpin* pc;
+ ScfEpin* pb;
int i;
int j = path->pins->size - 1;
if (!pc->aconst)
break;
- pc->a = pc->hfe * c->pins[SCF_EDA_NPN_B]->a;
+ pb = c->pins[SCF_EDA_NPN_B];
+ pc->a = pc->hfe * pb->a;
__ses_path_pr(f, path, 0, i, NULL, &pr);
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);
+
if (pc->v < pj->v) {
v = p0->v - pj->v;
}
}
- if (!path->childs)
- continue;
+ 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;
+ }
+ }
+ }
- int ret = ses_paths_find_flow(flow, path->childs, vip, bridge);
+ 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;
- if (1 == ret) {
- if (scf_vector_add(flow->paths, path) < 0)
- return -1;
- return 1;
- }
+ 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];
+ }
+
+ flow->vip = vp;
+ flow->vip_n = vn;
return 0;
}
return;
ses_path_t* path;
+ ses_path_t* child;
ScfEcomponent* c;
ScfEpin* p;
ScfEpin* p0;
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)
+ if (p->lid == vip->lid) {
p0 = p;
+ j0 = j;
+ }
continue;
}
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)
+ if (j + 1 < path->pins->size) {
p0 = path->pins->data[j + 1];
- else
+ j0 = j + 1;
+ } else {
p0 = path->pins->data[j];
+ j0 = j;
+ }
} else if (p->sr != p->pr) {
- flow->neg_r += p->sr - p0->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, p0 c%ldp%ld->pr: %lg\n",
- flow->neg_r, p->cid, p->id, p->sr, p0->cid, p0->id, 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;
}
}
- assert(p0);
+ if (p0) {
+ vip = path->pins->data[j - 1];
+ c = f->components[vip->cid];
- vip = path->pins->data[j - 1];
+ 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;
+ }
- if (vip != p0) {
- 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, 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\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",
int i;
int j;
- for (i = 0; i < flow->paths->size; i++) {
- path = flow->paths->data[i];
+ 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];
for (j = 0; j < path->pins->size; j++) {
p = path->pins->data[j];
printf("c%ldp%ld ", p->cid, p->id);
- if (p->lid == vip->lid) {
- vip = path->pins->data[0];
+ if (p->lid == vip->lid)
break;
- }
}
- printf(", ");
+
+ if (i > 0)
+ printf(", ");
}
printf(";\n");
printf("c%ldp%ld ", p->cid, p->id);
}
- printf(", ");
+ if (flag)
+ printf(", ");
vip = path->pins->data[j - 1];
}
free(ctx);
}
}
+
+void __ses_pn_dr(ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe)
+{
+ double v = pb->v - pe->v;
+ double r;
+
+ if (v >= SCF_EDA_V_Diode_ON) {
+
+ ses_ui_r(&r, NULL, v, 0, pb->a, 0);
+ 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);
+}
+
+void __ses_npn_dr(ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe)
+{
+ double v = pb->v - pe->v;
+ double r;
+
+ if (v >= SCF_EDA_V_NPN_ON) {
+
+ ses_ui_r(&r, NULL, v, 0, pb->a, 0);
+ 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);
+}
--- /dev/null
+#include<stdio.h>
+#include<stdlib.h>
+#include<math.h>
+#include<complex.h>
+
+double V = 6;
+double R0 = 7000;
+double R1 = 3000;
+double R2 = 9000;
+double R3 = 1000;
+
+double Rb = 100;
+double Vbc = 0.05;
+
+void bridge()
+{
+ double i1 = (V * (R2 * (R3 + Rb) + R3 * (R0 + Rb)) + Vbc * R0 * (R2 + R3))
+ / (R0 * R1 * (R2 + R3) + (R0 + R1) * (R2 * Rb + R2 * R3 + R3 * Rb));
+
+ double ib = (V - i1 * (R0 + R1)) / R0;
+ double i0 = i1 + ib;
+ double i3 = (i1 * (R0 * R1 + Rb * (R0 + R1)) - Vbc * R0 - V * Rb) / R0 / R3;
+ double i2 = i3 - ib;
+ double i3_ = (V + ib * R2) / (R2 + R3);
+
+ double V0 = i0 * R0;
+ double V1 = i1 * R1;
+ double V2 = i2 * R2;
+ double V3 = i3 * R3;
+ double Vb = ib * Rb;
+
+ 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("R3: %lg, i3: %lg, V3: %lg, i3_: %lg\n", R3, i3, V3, i3_);
+ printf("Rb: %lg, ib: %lg, Vb: %lg, Vbc: %lg\n", Rb, ib, Vb, Vbc);
+
+ printf("V0 + V1: %lg\n", V0 + V1);
+ printf("V2 + V3: %lg\n", V2 + V3);
+ printf("i1 + ib: %lg, i0: %lg\n", i1 + ib, i0);
+ printf("i2 + ib: %lg, i3: %lg\n", i2 + ib, i3);
+
+ printf("Vbc + Vb + V3: %lg, V1: %lg\n", Vbc + Vb + V3, V1);
+ printf("Vbc + Vb + V0: %lg, V2: %lg\n", Vbc + Vb + V0, V2);
+}
+
+double U0 = 6;
+double U1 = 0;
+double U2 = 6;
+double U3 = 0;
+
+void bridge2()
+{
+ 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 i3_ = (U2 - U3 - i2 * R2) / R3;
+
+ double V0 = i0 * R0;
+ double V1 = i1 * R1;
+ double V2 = i2 * R2;
+ double V3 = i3 * R3;
+ double Vb = ib * Rb;
+
+ 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("R3: %lg, i3: %lg, V3: %lg, i3_: %lg\n", R3, i3, V3, i3_);
+ printf("Rb: %lg, ib: %lg, Vb: %lg, Vbc: %lg\n", Rb, ib, Vb, Vbc);
+
+ printf("V0 + V1: %lg, U0 - U1: %lg\n", V0 + V1, U0 - U1);
+ printf("V2 + V3: %lg, U2 - U3: %lg\n", V2 + V3, U2 - U3);
+
+ printf("i1 + ib: %lg, i0: %lg\n", i1 + ib, i0);
+ printf("i2 + ib: %lg, i3: %lg\n", i2 + ib, i3);
+
+ printf("Vbc + Vb + V3: %lg, V1: %lg\n", Vbc + Vb + V3, V1);
+ printf("Vbc + Vb + V0: %lg, V2: %lg\n", Vbc + Vb + V0, V2);
+}
+
+int main()
+{
+ bridge();
+ printf("---------------\n\n");
+
+ bridge2();
+ 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;
- R4->r = 1000 * 47;
- R5->r = 1000 * 27;
- R3->r = 1000 * 10;
- R2->r = 1000 * 10;
R1->r = 1000 * 10;
+ R2->r = 1000 * 10;
+ R3->r = 1000 * 10;
+ R4->r = 1000 * 10;
+ R5->r = 1000;
R0->r = 1000;
C0->uf = 10;
C1->uf = 0.01;