printf("f: %s\n", f->name);
- ses_steps_analyse(f, 1000, 1);
+ ses_steps_analyse(f, 1000, 4);
}
#endif
SCF_PACK_DEF_VAR(double, uf);
SCF_PACK_DEF_VAR(double, uh);
+ SCF_PACK_DEF_VAR(int64_t, count);
SCF_PACK_DEF_VAR(int64_t, color);
SCF_PACK_DEF_VAR(int, status);
SCF_PACK_DEF_VAR(int, x);
SCF_PACK_INFO_VAR(ScfEcomponent, uf),
SCF_PACK_INFO_VAR(ScfEcomponent, uh),
+SCF_PACK_INFO_VAR(ScfEcomponent, count),
SCF_PACK_INFO_VAR(ScfEcomponent, color),
SCF_PACK_INFO_VAR(ScfEcomponent, status),
SCF_PACK_INFO_VAR(ScfEcomponent, x),
int pos_pins;
int neg_pins;
+ int pos_diodes;
+ int pos_NPNs;
+
+ int neg_diodes;
+ int neg_NPNs;
+
double pos_r;
double neg_r;
void ses_path_print(ses_path_t* path);
int ses_path_add (ses_path_t* path, ses_path_t* child);
+ses_path_t* ses_path_save (ses_path_t* src);
+int ses_path_load (ses_path_t* dst, ses_path_t* src);
+
ses_flow_t* ses_flow_alloc();
void ses_flow_free (ses_flow_t* flow);
void ses_flow_print(ses_flow_t* flow);
int ses_layout_board (ScfEboard* b);
int ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count);
-int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, ses_path_t* bridge);
+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_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);
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);
+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_pos(ScfEfunction* f, ScfEline* el);
int __ses_path_neg(ScfEfunction* f, ScfEline* el);
ScfEcomponent* B;
ScfEcomponent* c;
ScfEline* el;
- ScfEpin* p;
- ScfEpin* pb;
- ScfEpin* pc;
- ScfEpin* pe;
ScfLine* l;
cairo_surface_t* surface;
cairo_fill(cr);
cairo_stroke(cr);
- size_t i;
- size_t j;
- size_t k;
+ long i;
+ long j;
+ long k;
B = f->components[0];
cairo_set_font_size(cr, 20);
- cairo_move_to (cr, l->x0 + 12, l->y0 + 24);
+ 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;
+ }
+ }
+
+ if (cy > l->y0)
+ cairo_move_to(cr, l->x0 + 12, l->y0 - 8);
+ else
+ cairo_move_to(cr, l->x0 + 12, l->y0 + 24);
+
cairo_show_text(cr, text);
cairo_stroke(cr);
}
#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)
+static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, double* a, int* changed, int64_t ns, int64_t count)
{
ses_path_t* child;
__ses_path_jr (f, child);
}
- int ret = __ses_path_va(f, child, changed, ns);
+ int ret = __ses_path_va(f, child, changed, ns, count);
if (ret < 0)
return ret;
return v;
}
-int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed, int64_t ns)
+int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed, int64_t ns, int64_t count)
{
if (!path)
return -EINVAL;
__ses_path_split_v(f, path, i0, i, a);
if (!(i & 0x1) && path->childs) {
- int ret = __ses_path_split_a(f, path, i, &a, changed, ns);
+ int ret = __ses_path_split_a(f, path, i, &a, changed, ns, count);
if (ret < 0)
return ret;
else
p->v = p2->v - c->v * sign;
- scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ns: %ld, uf: %lg, c->jdr: %lg\n",
- c->id, c->v, p->v, p2->v, dv, p->a, ns, c->uf, c->jdr);
+ 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_path_jr(f, path);
- int ret = __ses_path_va(f, path, &changed, ns);
+ int ret = __ses_path_va(f, path, &changed, ns, count);
if (ret < 0)
return ret;
}
return 0;
}
-static int __ses_bridge_v(ScfEfunction* f, ses_path_t* bridge, double vmin, ses_flow_t* flow, int64_t ns)
+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];
__changed = 0;
- int ret = __ses_path_va(f, bridge, &__changed, ns);
+ int ret = __ses_path_va(f, bridge, &__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)
+static 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;
int __changed = 0;
- ret = __ses_path_va(f, bridge, &__changed, ns);
+ ret = __ses_path_va(f, bridge, &__changed, ns, count);
if (ret < 0)
return ret;
#if 0
return 0;
}
-static int ses_path_va_bridge(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths, int64_t ns)
+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;
if (0 == path->n_capacitors) {
- ret = __ses_path_va_bridge(f, path, changed, paths, ns);
+ ret = __ses_path_va_bridge(f, path, changed, paths, ns, count);
if (ret < 0)
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);
+ ret = ses_path_va_bridge(f, child, changed, vec, ns, count);
if (ret < 0) {
scf_vector_free(vec);
return ret;
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);
+ int ret = ses_path_va_bridge(f, path, &changed, ctx->paths, ns, count);
if (ret < 0)
return ret;
}
}
}
-static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_t* bridge, int* changed, int64_t ns)
+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_flow_t* flow1;
el = f->elines[p1->lid];
el->v = p1->v;
- ret = __ses_path_va(f, bridge, changed, ns);
+ ret = __ses_path_va(f, bridge, changed, ns, count);
if (ret < 0) {
scf_loge("\n");
return ret;
return 0;
}
-static int ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_t* bridge, int* changed, int64_t ns)
+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_path_t* child;
__ses_path_jr(f, bridge);
- ret = __ses_path_va_capacitor(f, paths, bridge, changed, ns);
+ ret = __ses_path_va_capacitor(f, paths, bridge, changed, ns, count);
if (ret < 0)
return ret;
}
-#if 0
- if (bridge->childs) {
- for (j = 0; j < bridge->childs->size; j++) {
- child = bridge->childs->data[j];
- ret = ses_path_va_capacitor(f, paths, child, changed, ns);
- if (ret < 0)
- return ret;
- }
- }
-#endif
if (bridge->bridges) {
for (j = 0; j < bridge->childs->size; j++) {
child = bridge->childs->data[j];
- ret = ses_path_va_capacitor(f, paths, child, changed, ns);
+ ret = ses_path_va_capacitor(f, paths, child, changed, ns, count);
if (ret < 0)
return ret;
}
int changed = 0;
- int ret = ses_path_va_capacitor(f, ctx->paths, path, &changed, ns);
+ int ret = ses_path_va_capacitor(f, ctx->paths, path, &changed, ns, count);
if (ret < 0)
return ret;
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)
+{
+ 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];
+
+ if (scf_vector_add((*ppath)->pins, p) < 0) {
+ ses_path_free(*ppath);
+ *ppath = NULL;
+ return -ENOMEM;
+ }
+ }
+
+ vip = path->pins->data[j - 1];
+ }
+
+ return 0;
+}
+
void ses_flow_jr(ses_flow_t* flow, ScfEfunction* f)
{
if (!flow)
++flow->pos_pins;
- if (p->lid == vip->lid) {
+ 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];
- c = f->components[p->cid];
double pr = p->pr;
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];
else
flow->neg_r += p->pr - p0->pr;
- scf_loge("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+ 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)
flow->neg_r += p->sr - p0->pr;
- scf_logw("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+ 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);
p0 = p;
}
if (vip != p0) {
flow->neg_r += vip->sr - p0->pr;
- scf_loge("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+ 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_logi("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+ 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_loge("flow pos_pins: %d, neg_pins: %d, pos_r: %lg, neg_r: %lg, vip: c%ldp%ld\n",
- flow->pos_pins, flow->neg_pins, flow->pos_r, flow->neg_r, flow->vip->cid, flow->vip->id);
+ 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)
return 0;
}
+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;
+
+ 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;
+ }
+
+ memcpy(p2, p, sizeof(ScfEpin));
+ }
+
+ return dst;
+}
+
+int ses_path_load(ses_path_t* dst, ses_path_t* src)
+{
+ if (!dst || !src || dst->pins->size != src->pins->size)
+ return -EINVAL;
+
+ ScfEpin* p;
+ ScfEpin* p2;
+
+ 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;
+
+ memcpy(p, p2, sizeof(ScfEpin));
+ }
+
+ return 0;
+}
+
ses_ctx_t* ses_ctx_alloc()
{
ses_ctx_t* ctx = calloc(1, sizeof(ses_ctx_t));