From: yu.dongliang <18588496441@163.com> Date: Sat, 20 Apr 2024 06:41:29 +0000 (+0800) Subject: support 'capacitor' & add some electronic graphs for example, such as oscillator. X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=59689b9adddfb1ba6672b92c6de9c0cf3fe601d7;p=ses.git support 'capacitor' & add some electronic graphs for example, such as oscillator. --- diff --git a/Makefile b/Makefile index 79d6c18..aaec5b7 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,6 @@ CFILES += ses_step_dc_input.c CFILES += ses_step_dc_diode.c CFILES += ses_step_dc_transistor.c -CFILES += ses_step_simplify.c CFILES += ses_step_topo.c CFILES += ses_step_jr.c @@ -21,7 +20,12 @@ 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 + CFILES += ses_step_output.c +CFILES += ses_step_simplify.c CFLAGS += -g -D_GNU_SOURCE CFLAGS += -I./ diff --git a/examples/add.pack b/examples/add.pack new file mode 100644 index 0000000..1b48349 Binary files /dev/null and b/examples/add.pack differ diff --git a/examples/add2.pack b/examples/add2.pack new file mode 100644 index 0000000..09dddba Binary files /dev/null and b/examples/add2.pack differ diff --git a/examples/and.pack b/examples/and.pack new file mode 100644 index 0000000..30d7366 Binary files /dev/null and b/examples/and.pack differ diff --git a/examples/or.pack b/examples/or.pack new file mode 100644 index 0000000..55f5edd Binary files /dev/null and b/examples/or.pack differ diff --git a/examples/oscillator.pack b/examples/oscillator.pack new file mode 100644 index 0000000..3286dcf Binary files /dev/null and b/examples/oscillator.pack differ diff --git a/main.c b/main.c index 66bb4ea..ac011ef 100644 --- a/main.c +++ b/main.c @@ -107,7 +107,7 @@ int main(int argc, char* argv[]) printf("f: %s\n", f->name); - ses_steps_analyse(f, 5, 1); + ses_steps_analyse(f, 1000, 16); } #endif diff --git a/scf_eda_pack.c b/scf_eda_pack.c index 6eec934..8d3988b 100644 --- a/scf_eda_pack.c +++ b/scf_eda_pack.c @@ -17,25 +17,25 @@ 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_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_Resistor, 0, 0, 0, 0, 10 * 1000, 0, 0, 0}, - {SCF_EDA_Capacitor, 0, 0, 0, 0, 1e12, 0.1, 0, 0}, - {SCF_EDA_Inductor, 0, 0, 0, 0, 0, 0, 1000, 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_EDA_Inductor, 0, 0, 0, 0, 0, 0, 1e3, 0}, }; static scf_edata_t pin_datas[] = { - {SCF_EDA_None, 0, 0, 0, 0, 0, 0, 0, 0}, + {SCF_EDA_None, 0, 0, 0, 0, 0, 0, 0, 0}, - {SCF_EDA_Diode, 0, SCF_EDA_Diode_NEG, 0, 0, 750, 0, 0, 0}, + {SCF_EDA_Diode, 0, SCF_EDA_Diode_NEG, 0, 0, 750, 0, 0, 0}, - {SCF_EDA_NPN, 0, SCF_EDA_NPN_B, 0, 0, 750, 0, 0, 0}, - {SCF_EDA_NPN, 0, SCF_EDA_NPN_C, 0, 0, 10, 0, 0, 150}, + {SCF_EDA_NPN, 0, SCF_EDA_NPN_B, 0, 0, 750, 0, 0, 0}, + {SCF_EDA_NPN, 0, SCF_EDA_NPN_C, 0, 0, 10, 0, 0, 150}, - {SCF_EDA_PNP, 0, SCF_EDA_PNP_B, 0, 0, 750, 0, 0, 0}, - {SCF_EDA_PNP, 0, SCF_EDA_PNP_C, 0, 0, 10, 0, 0, 150}, + {SCF_EDA_PNP, 0, SCF_EDA_PNP_B, 0, 0, 750, 0, 0, 0}, + {SCF_EDA_PNP, 0, SCF_EDA_PNP_C, 0, 0, 10, 0, 0, 150}, }; static scf_edata_t* _pin_find_data(const uint64_t type, const uint64_t model, const uint64_t pid) diff --git a/scf_eda_pack.h b/scf_eda_pack.h index e5e6d3b..3acab91 100644 --- a/scf_eda_pack.h +++ b/scf_eda_pack.h @@ -77,6 +77,7 @@ typedef struct { double v; double a; double r; + double uf; double uh; double hfe; @@ -118,7 +119,9 @@ struct scf_epin_s SCF_PACK_DEF_VAR(double, uh); SCF_PACK_DEF_VAR(double, hfe); + SCF_PACK_DEF_VAR(double, jdr); SCF_PACK_DEF_VAR(double, dr); + SCF_PACK_DEF_VAR(double, sr); SCF_PACK_DEF_VAR(double, pr); @@ -152,8 +155,11 @@ SCF_PACK_INFO_VAR(ScfEpin, uf), SCF_PACK_INFO_VAR(ScfEpin, uh), SCF_PACK_INFO_VAR(ScfEpin, hfe), +SCF_PACK_INFO_VAR(ScfEpin, jdr), SCF_PACK_INFO_VAR(ScfEpin, dr), + SCF_PACK_INFO_VAR(ScfEpin, sr), +SCF_PACK_INFO_VAR(ScfEpin, pr), SCF_PACK_INFO_VAR(ScfEpin, path), SCF_PACK_INFO_VAR(ScfEpin, x), @@ -222,6 +228,9 @@ struct scf_ecomponent_s SCF_PACK_DEF_VAR(double, v); 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_DEF_VAR(double, uh); @@ -245,6 +254,9 @@ SCF_PACK_INFO_OBJS(ScfEcomponent, pins, ScfEpin), SCF_PACK_INFO_VAR(ScfEcomponent, v), SCF_PACK_INFO_VAR(ScfEcomponent, a), +SCF_PACK_INFO_VAR(ScfEcomponent, dr), +SCF_PACK_INFO_VAR(ScfEcomponent, jdr), + SCF_PACK_INFO_VAR(ScfEcomponent, r), SCF_PACK_INFO_VAR(ScfEcomponent, uf), SCF_PACK_INFO_VAR(ScfEcomponent, uh), diff --git a/ses_core.h b/ses_core.h index d7c0f4b..d8beb94 100644 --- a/ses_core.h +++ b/ses_core.h @@ -37,12 +37,13 @@ struct ses_info_s int j; int n_diodes; int n_NPNs; + int n_capacitors; }; struct ses_path_s { scf_vector_t* pins; - scf_vector_t* diodes; + scf_vector_t* infos; scf_vector_t* childs; @@ -52,9 +53,6 @@ struct ses_path_s int parent_p0; int parent_p1; - double parent_r0; - double parent_r1; - double parent_pr; double sr; @@ -69,6 +67,7 @@ struct ses_path_s int type; int index; + int n_capacitors; int n_diodes; int n_layers; }; @@ -113,14 +112,17 @@ int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, ses 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 __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); +double __ses_path_v_capacitor(ScfEfunction* f, ses_path_t* path); + 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_sr (ScfEfunction* f, ses_path_t* path, int i, int j, double* r); -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_va (ScfEfunction* f, ses_path_t* path, int *changed, int64_t ns); +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); void __ses_npn_epr (ScfEfunction* f, ScfEpin* pe, double* r); diff --git a/ses_step_battery.c b/ses_step_battery.c index af66bdc..eef62c7 100644 --- a/ses_step_battery.c +++ b/ses_step_battery.c @@ -6,13 +6,6 @@ static int _battery_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_ ScfEline* el; ScfEpin* p; - size_t i; - - for (i = 0; i < f->n_elines; i++) { - el = f->elines[i]; - el->v = SCF_EDA_V_INIT; - } - c = f->components[0]; c->v = 6; diff --git a/ses_step_da.c b/ses_step_da.c index 07bebf1..c1993f2 100644 --- a/ses_step_da.c +++ b/ses_step_da.c @@ -1,6 +1,6 @@ #include"ses_core.h" -static int __ses_path_split_da(ScfEfunction* f, ses_path_t* path, int i, double* da, double *dja, int* changed) +static int __ses_path_split_da(ScfEfunction* f, ses_path_t* path, int i, double* da, int* changed) { ses_path_t* child; @@ -59,7 +59,7 @@ static int __ses_path_split_da(ScfEfunction* f, ses_path_t* path, int i, double* 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, 0); + int ret = __ses_path_da(f, child, changed, _da); if (ret < 0) return ret; @@ -70,7 +70,7 @@ static int __ses_path_split_da(ScfEfunction* f, ses_path_t* path, int i, double* return n; } -static void __ses_path_split_dv(ScfEfunction* f, ses_path_t* path, int i0, int i, double da, double dja) +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]; @@ -119,7 +119,7 @@ void __ses_npn_dr(ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe) 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, double dja) +int __ses_path_da(ScfEfunction* f, ses_path_t* path, int* changed, double da) { if (!path) return -EINVAL; @@ -154,9 +154,9 @@ int __ses_path_da(ScfEfunction* f, ses_path_t* path, int* changed, double da, do if (!(i & 0x1) && path->childs) { - __ses_path_split_dv(f, path, i0, i, da, 0); + __ses_path_split_dv(f, path, i0, i, da); - int ret = __ses_path_split_da(f, path, i, &da, NULL, changed); + int ret = __ses_path_split_da(f, path, i, &da, changed); if (ret < 0) return ret; @@ -166,7 +166,7 @@ int __ses_path_da(ScfEfunction* f, ses_path_t* path, int* changed, double da, do scf_logd("i: %d, p0: c%ldp%ld\n", i, p0->cid, p0->id); } } else - __ses_path_split_dv(f, path, i0, i, da, 0); + __ses_path_split_dv(f, path, i0, i, da); el = f->elines[p->lid]; el->v = p->v; @@ -205,7 +205,7 @@ int __ses_path_da(ScfEfunction* f, ses_path_t* path, int* changed, double da, do if (SCF_EDA_Diode_NEG == p->id) { p2 = path->pins->data[i - 1]; - *changed += __ses_status_check(f, c, p2, p); + *changed += __ses_status_check(f, c, p2, p, 1); __ses_pn_dr(c, p2, p); } @@ -216,7 +216,7 @@ int __ses_path_da(ScfEfunction* f, ses_path_t* path, int* changed, double da, do p2 = path->pins->data[i - 1]; if (SCF_EDA_NPN_B == p2->id) { - *changed += __ses_status_check(f, c, p2, p); + *changed += __ses_status_check(f, c, p2, p, 1); __ses_npn_dr(c, p2, p); } diff --git a/ses_step_dc_diode.c b/ses_step_dc_diode.c index 031024f..ef58df8 100644 --- a/ses_step_dc_diode.c +++ b/ses_step_dc_diode.c @@ -19,6 +19,14 @@ static int _dc_diode_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx Bp = B->pins[SCF_EDA_Battery_POS]; Bn = B->pins[SCF_EDA_Battery_NEG]; + for (i = 0; i < f->n_elines; i++) { + lb = f->elines[i]; + + if (lb->flags & (SCF_EDA_PIN_IN | SCF_EDA_PIN_POS | SCF_EDA_PIN_NEG)) + continue; + lb->vconst = 0; + } + for (i = 0; i < f->n_components; i++) { c = f->components[i]; @@ -31,6 +39,11 @@ static int _dc_diode_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx lb = f->elines[pb->lid]; le = f->elines[pe->lid]; + if (pb->lid == Bp->lid && pe->lid == Bn->lid) { + scf_loge("Diode c%ld, short connected\n", c->id); + return -EINVAL; + } + if (__ses_path_neg(f, lb) && !__ses_path_pos(f, lb)) { c->status = SCF_EDA_Status_OFF; @@ -71,15 +84,9 @@ static int _dc_diode_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx } else if (lb->v >= le->v + SCF_EDA_V_Diode_OFF) { - if (le->v == Bn->v) { - if (lb->v == Bp->v) { - scf_loge("Diode c%ld, short connected\n", c->id); - return -EINVAL; - } - + if (le->v == Bn->v) lb->vconst = 1; - - } else if (lb->v == Bp->v) + else if (lb->v == Bp->v) le->vconst = 1; lb->v = le->v + SCF_EDA_V_Diode_ON; diff --git a/ses_step_dc_transistor.c b/ses_step_dc_transistor.c index ee01625..4ada12b 100644 --- a/ses_step_dc_transistor.c +++ b/ses_step_dc_transistor.c @@ -33,6 +33,11 @@ static int _dc_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, se lb = f->elines[pb->lid]; le = f->elines[pe->lid]; + if (pb->lid == Bp->lid && pe->lid == Bn->lid) { + scf_loge("NPN c%ld, short connected\n", c->id); + return -EINVAL; + } + if (__ses_path_neg(f, lb) && !__ses_path_pos(f, lb)) { c->status = SCF_EDA_Status_OFF; @@ -40,6 +45,9 @@ static int _dc_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, se continue; } + scf_logi("c%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n", + 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) { if (le->v < SCF_EDA_V_MIN) @@ -75,15 +83,9 @@ static int _dc_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, se } else if (lb->v >= le->v + SCF_EDA_V_NPN_OFF) { - if (le->v == Bn->v) { - if (lb->v == Bp->v) { - scf_loge("NPN c%ld, short connected\n", c->id); - return -EINVAL; - } - + if (le->v == Bn->v) lb->vconst = 1; - - } else if (lb->v == Bp->v) + else if (lb->v == Bp->v) le->vconst = 1; lb->v = le->v + SCF_EDA_V_NPN_ON; diff --git a/ses_step_jr.c b/ses_step_jr.c index 36eed9b..30428c8 100644 --- a/ses_step_jr.c +++ b/ses_step_jr.c @@ -79,20 +79,20 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) c = f->components[p->cid]; r2 = r; - r += p->r + p->dr; + r += p->r + p->dr + p->jdr; if (i & 0x1) - r += c->r; + r += c->r + c->dr + c->jdr; if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E != p->id) { - p->sr = r2; - p->pr = r2; + p->sr = r2; + p->pr = r2; } else { - p->sr = r; - p->pr = r; + p->sr = r; + p->pr = r; } - scf_loge("path: %d, i: %d, c%ldp%ld, p->sr: %lg\n", path->index, i, p->cid, p->id, p->sr); + scf_loge("path: %d, i: %d, c%ldp%ld, sr: %lg\n", path->index, i, p->cid, p->id, p->sr); } if (path->childs) { @@ -135,12 +135,13 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) return -EINVAL; double pr; + double jpr; __ses_path_pr(f, path, k, j, NULL, &pr); ses_merge_r(&r, NULL, pr, 0, child->pr, 0); - double dr = pr - r; + double dr = pr - r; p1->pr -= dr; child->parent_pr = p1->pr; @@ -160,51 +161,14 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) } } - p = path->pins->data[path->pins->size - 1]; - path->pr = p->pr; - path->sr = p->sr; + p = path->pins->data[path->pins->size - 1]; + path->pr = p->pr; + path->sr = p->sr; scf_loge("path: %d, pr: %lg, sr: %lg\n\n", path->index, path->pr, path->sr); return 0; } -static void __ses_path_parent_jr(ScfEfunction* f, ses_path_t* path) -{ - ses_path_t* sp; - - int i; - - if (path->childs) { - - for (i = 0; i < path->childs->size; i++) { - sp = path->childs->data[i]; - - __ses_path_pr(f, path, 0, sp->parent_p0, NULL, &sp->parent_r0); - __ses_path_pr(f, path, sp->parent_p1, path->pins->size - 1, NULL, &sp->parent_r1); - - scf_logw("child: %d, parent_p0: %d, parent_p1: %d, r0: %lg, r1: %lg\n", - sp->index, sp->parent_p0, sp->parent_p1, sp->parent_r0, sp->parent_r1); - - __ses_path_parent_jr(f, sp); - } - } - - if (path->bridges) { - - for (i = 0; i < path->bridges->size; i++) { - sp = path->bridges->data[i]; - - __ses_path_pr(f, path, 0, sp->parent_p0, NULL, &sp->parent_r0); - __ses_path_pr(f, path, sp->parent_p1, path->pins->size - 1, NULL, &sp->parent_r1); - - scf_loge("bridges: %d, parent_p0: %d, parent_p1: %d, r0: %lg, r1: %lg\n", - sp->index, sp->parent_p0, sp->parent_p1, sp->parent_r0, sp->parent_r1); - - __ses_path_parent_jr(f, sp); - } - } -} - static int _jr_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) { ses_path_t* path; @@ -227,7 +191,6 @@ static int _jr_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ct if (ret < 0) return ret; - __ses_path_parent_jr(f, path); printf("\n"); } diff --git a/ses_step_open.c b/ses_step_open.c new file mode 100644 index 0000000..d0e611e --- /dev/null +++ b/ses_step_open.c @@ -0,0 +1,195 @@ +#include"ses_core.h" + +static int __dfs_path_pos(ScfEfunction* f, ScfEline* el) +{ + ScfEcomponent* c; + ScfEcomponent* c2; + ScfEline* el2; + ScfEpin* p; + ScfEpin* p2; + + size_t i; + size_t j; + + if (SCF_EDA_PIN_POS & el->flags) + return 1; + if (SCF_EDA_PIN_NEG & el->flags) + return 0; + + for (i = 0; i + 1 < el->n_pins; i += 2) { + + c = f->components[el->pins[i]]; + p = c->pins [el->pins[i + 1]]; + + if (p->vflag) + continue; + p->vflag = 1; + + if (SCF_EDA_Diode == c->type) { + + if (SCF_EDA_Diode_POS == p->id || SCF_EDA_Status_OFF == c->status) + continue; + + p2 = c->pins[SCF_EDA_Diode_POS]; + + } else if (SCF_EDA_NPN == c->type) { + + if (SCF_EDA_NPN_E != p->id || SCF_EDA_Status_OFF == c->status) + continue; + + p2 = c->pins[SCF_EDA_NPN_B]; + p2->vflag = 1; + + if (__dfs_path_pos(f, f->elines[p2->lid])) + return 1; + + p2 = c->pins[SCF_EDA_NPN_C]; + p2->vflag = 1; + + if (__dfs_path_pos(f, f->elines[p2->lid])) + return 1; + + continue; + } else + p2 = c->pins[!p->id]; + + if (p2->vflag) + continue; + p2->vflag = 1; + + if (__dfs_path_pos(f, f->elines[p2->lid])) + return 1; + } + + return 0; +} + +static int __dfs_path_neg(ScfEfunction* f, ScfEline* el) +{ + ScfEcomponent* c; + ScfEpin* p; + ScfEpin* p2; + + size_t i; + size_t j; + + if (SCF_EDA_PIN_NEG & el->flags) + return 1; + if (SCF_EDA_PIN_POS & el->flags) + return 0; + + for (i = 0; i + 1 < el->n_pins; i += 2) { + + c = f->components[el->pins[i]]; + p = c->pins [el->pins[i + 1]]; + + if (p->vflag) + continue; + p->vflag = 1; + + if (SCF_EDA_Diode == c->type) { + + if (SCF_EDA_Diode_NEG == p->id || SCF_EDA_Status_OFF == c->status) + continue; + p2 = c->pins[SCF_EDA_Diode_NEG]; + + } else if (SCF_EDA_NPN == c->type) { + + if (SCF_EDA_NPN_E == p->id || SCF_EDA_Status_OFF == c->status) + continue; + p2 = c->pins[SCF_EDA_NPN_E]; + } else + p2 = c->pins[!p->id]; + + if (p2->vflag) + continue; + p2->vflag = 1; + + if (__dfs_path_neg(f, f->elines[p2->lid])) + return 1; + } + + return 0; +} + +int __ses_path_pos(ScfEfunction* f, ScfEline* el) +{ + ScfEcomponent* c; + ScfEpin* p; + + size_t i; + size_t 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]; + p->vflag = 0; + } + } + + return __dfs_path_pos(f, el); +} + +int __ses_path_neg(ScfEfunction* f, ScfEline* el) +{ + ScfEcomponent* c; + ScfEpin* p; + + size_t i; + size_t 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]; + p->vflag = 0; + } + } + + return __dfs_path_neg(f, el); +} + +static int _open_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) +{ + ScfEcomponent* B = f->components[0]; + ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; + ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; + ScfEline* el; + + int i; + + for (i = 0; i < f->n_elines; i++) { + el = f->elines[i]; + + 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)) + el->v = Bp->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); + } + + printf("\n"); + return 0; +} + +ses_step_t ses_step_open = +{ + .name = "open", + + .handler = _open_handler, +}; diff --git a/ses_step_output.c b/ses_step_output.c index 7b24d91..cd13d0d 100644 --- a/ses_step_output.c +++ b/ses_step_output.c @@ -1,157 +1,5 @@ #include"ses_core.h" -static int __dfs_path_pos(ScfEfunction* f, ScfEline* el) -{ - ScfEcomponent* c; - ScfEcomponent* c2; - ScfEline* el2; - ScfEpin* p; - ScfEpin* p2; - - size_t i; - size_t j; - - if (SCF_EDA_PIN_POS & el->flags) - return 1; - if (SCF_EDA_PIN_NEG & el->flags) - return 0; - - for (i = 0; i + 1 < el->n_pins; i += 2) { - - c = f->components[el->pins[i]]; - p = c->pins [el->pins[i + 1]]; - - if (p->vflag) - continue; - p->vflag = 1; - - if (SCF_EDA_Diode == c->type) { - - if (SCF_EDA_Diode_POS == p->id || SCF_EDA_Status_OFF == c->status) - continue; - - p2 = c->pins[SCF_EDA_Diode_POS]; - - } else if (SCF_EDA_NPN == c->type) { - - if (SCF_EDA_NPN_E != p->id || SCF_EDA_Status_OFF == c->status) - continue; - - p2 = c->pins[SCF_EDA_NPN_B]; - p2->vflag = 1; - - if (__dfs_path_pos(f, f->elines[p2->lid])) - return 1; - - p2 = c->pins[SCF_EDA_NPN_C]; - p2->vflag = 1; - - if (__dfs_path_pos(f, f->elines[p2->lid])) - return 1; - - continue; - } else - p2 = c->pins[!p->id]; - - if (p2->vflag) - continue; - p2->vflag = 1; - - if (__dfs_path_pos(f, f->elines[p2->lid])) - return 1; - } - - return 0; -} - -static int __dfs_path_neg(ScfEfunction* f, ScfEline* el) -{ - ScfEcomponent* c; - ScfEpin* p; - ScfEpin* p2; - - size_t i; - size_t j; - - if (SCF_EDA_PIN_NEG & el->flags) - return 1; - if (SCF_EDA_PIN_POS & el->flags) - return 0; - - for (i = 0; i + 1 < el->n_pins; i += 2) { - - c = f->components[el->pins[i]]; - p = c->pins [el->pins[i + 1]]; - - if (p->vflag) - continue; - p->vflag = 1; - - if (SCF_EDA_Diode == c->type) { - - if (SCF_EDA_Diode_NEG == p->id || SCF_EDA_Status_OFF == c->status) - continue; - p2 = c->pins[SCF_EDA_Diode_NEG]; - - } else if (SCF_EDA_NPN == c->type) { - - if (SCF_EDA_NPN_E == p->id || SCF_EDA_Status_OFF == c->status) - continue; - p2 = c->pins[SCF_EDA_NPN_E]; - } else - p2 = c->pins[!p->id]; - - if (p2->vflag) - continue; - p2->vflag = 1; - - if (__dfs_path_neg(f, f->elines[p2->lid])) - return 1; - } - - return 0; -} - -int __ses_path_pos(ScfEfunction* f, ScfEline* el) -{ - ScfEcomponent* c; - ScfEpin* p; - - size_t i; - size_t 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]; - p->vflag = 0; - } - } - - return __dfs_path_pos(f, el); -} - -int __ses_path_neg(ScfEfunction* f, ScfEline* el) -{ - ScfEcomponent* c; - ScfEpin* p; - - size_t i; - size_t 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]; - p->vflag = 0; - } - } - - return __dfs_path_neg(f, el); -} - static int _output_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) { ScfEcomponent* B = f->components[0]; @@ -159,30 +7,20 @@ static int _output_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; ScfEline* el; - size_t i; + int i; printf("\n"); for (i = 0; i < f->n_elines; i++) { el = f->elines[i]; - if ((SCF_EDA_PIN_OUT | SCF_EDA_PIN_CF) & el->flags) { - - if (__ses_path_pos(f, el)) { - - if (!__ses_path_neg(f, el)) - el->v = Bp->v; + printf("e%ld->vconst: %d\n", el->id, el->vconst); - } else if (__ses_path_neg(f, el)) - el->v = Bn->v; - else - return -EINVAL; + if (SCF_EDA_PIN_OUT & el->flags) + scf_logw("out el: %ld, V: %lg\n", el->id, el->v); - if (SCF_EDA_PIN_OUT & el->flags) - scf_logw("out el: %ld, V: %lg\n", el->id, el->v); - else if (SCF_EDA_PIN_CF & el->flags) - scf_logw("cf el: %ld, V: %lg\n", el->id, el->v); - } + else if (SCF_EDA_PIN_CF & el->flags) + scf_logw("cf el: %ld, V: %lg\n", el->id, el->v); } return 0; diff --git a/ses_step_simplify.c b/ses_step_simplify.c index eef9d82..dfa7da6 100644 --- a/ses_step_simplify.c +++ b/ses_step_simplify.c @@ -27,8 +27,27 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) 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) + if (SCF_EDA_Capacitor == c->type) { + + 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); + + if (c->v > 1e-3 || c->v < -1e-3) + snprintf(text, sizeof(text) - 1, "%lgv", (int)(c->v * 1000) / 1000.0); + + else if (c->v > 1e-6 || c->v < -1e-6) + snprintf(text, sizeof(text) - 1, "%lgmV", (int)(c->v * 1000000) / 1000.0); + else + snprintf(text, sizeof(text) - 1, "%lguV", (int)(c->v * 1000000) / 1000000.0); + + cairo_move_to (cr, c->x + 10, c->y + 10); + 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); @@ -92,20 +111,45 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) break; case SCF_EDA_Capacitor: + + cairo_set_source_rgb(cr, 0.8, 0.0, 0.0); p = c->pins[SCF_EDA_Battery_POS]; - cairo_move_to(cr, c->x - 8, c->y - 5); - cairo_line_to(cr, c->x + 8, c->y - 5); + 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_move_to(cr, c->x, c->y - 5); - cairo_line_to(cr, p->x, p->y); + 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_move_to(cr, c->x - 8, c->y + 5); - cairo_line_to(cr, c->x + 8, c->y + 5); + 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]; - cairo_move_to(cr, c->x, c->y + 5); - cairo_line_to(cr, p->x, p->y); + 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); break; @@ -215,7 +259,7 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) } } -static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh) +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; @@ -307,7 +351,7 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw cairo_set_font_size(cr, 20); - cairo_move_to (cr, (l->x0 + l->x1) / 2 - 24, l->y0 + 24); + cairo_move_to (cr, l->x0 + 12, l->y0 + 24); cairo_show_text(cr, text); cairo_stroke(cr); } @@ -332,7 +376,10 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw __ses_function_draw(f, cr); - cairo_surface_write_to_png(surface, "./simplify.png"); + char file[128]; + snprintf(file, sizeof(file) - 1, "./simplify_%ld.png", count); + + cairo_surface_write_to_png(surface, file); cairo_destroy(cr); cairo_surface_destroy(surface); @@ -341,7 +388,7 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw static int _simplify_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) { - _simplify_draw(f, f->x, f->y, f->w, f->h); + _simplify_draw(f, f->x, f->y, f->w, f->h, count); return 0; } diff --git a/ses_step_topo.c b/ses_step_topo.c index 732b7d7..18dd489 100644 --- a/ses_step_topo.c +++ b/ses_step_topo.c @@ -68,8 +68,7 @@ int __dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __ if (SCF_EDA_NPN != rc->type || SCF_EDA_NPN_E != np->id) np->vflag = 1; - if (SCF_EDA_PIN_NEG & el->flags) { - scf_logd("neg l%ld\n\n", el->id); + if ((SCF_EDA_PIN_NEG & el->flags) || SCF_EDA_Capacitor == rc->type) { if (scf_vector_add(__paths, *ppath) < 0) return -ENOMEM; @@ -339,6 +338,93 @@ static int __topo_path_xchg(ses_path_t* path0, int k0, ses_path_t* path1, int k1 return 0; } +static int _topo_path_connect(ScfEfunction* f, scf_vector_t* paths) +{ + if (!f || !paths) + return -EINVAL; + + ses_path_t* path0; + ses_path_t* path1; + + ScfEcomponent* B = f->components[0]; + ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; + ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; + ScfEcomponent* c0; + ScfEcomponent* c1; + ScfEpin* p0; + ScfEpin* p1; + ScfEpin* p2; + ScfEpin* p3; + ScfEpin* p; + + int i; + int j; + int k; + + for (i = 0; i < paths->size; ) { + path0 = paths->data[i]; + + p0 = path0->pins->data[0]; + p1 = path0->pins->data[path0->pins->size - 1]; + + if (p0->lid == Bp->lid || p1->lid == Bn->lid) { + i++; + continue; + } + + for (j = 0; j < paths->size; j++) { + path1 = paths->data[j]; + + if (path1 == path0) + continue; + + p2 = path1->pins->data[0]; + p3 = path1->pins->data[path1->pins->size - 1]; + + if (p3->lid == p0->lid) { + for (k = 0; k < path0->pins->size; k++) { + p = path0->pins->data[k]; + + if (scf_vector_add(path1->pins, p) < 0) + return -ENOMEM; + } + goto connected; + + } else if (p3->lid == p1->lid) { + 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 connected; + + } else if (p2->lid == p1->lid) { + for (k = 0; k < path1->pins->size; k++) { + p = path1->pins->data[k]; + + if (scf_vector_add(path0->pins, p) < 0) + return -ENOMEM; + } + + SCF_XCHG(path0->pins, path1->pins); + goto connected; + } + } + + i++; + continue; + +connected: + if (scf_vector_del(paths, path0) < 0) + return -1; + ses_path_free(path0); + path0 = NULL; + } + + return 0; +} + static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths) { if (!f || !paths) @@ -479,7 +565,7 @@ static int __ses_branch_exist(ses_path_t* path, int i) return 0; } -static int __topo_path_diodes(ScfEfunction* f, ses_path_t* path) +static int __topo_path_key_infos(ScfEfunction* f, ses_path_t* path) { ses_info_t* info = NULL; ScfEcomponent* c; @@ -488,7 +574,7 @@ static int __topo_path_diodes(ScfEfunction* f, ses_path_t* path) int i; int j; - scf_vector_clear(path->diodes, ( void (*)(void*) )free); + scf_vector_clear(path->infos, ( void (*)(void*) )free); path->n_diodes = 0; for (i = 0; i < path->pins->size; i++) { @@ -548,7 +634,7 @@ _add: if (info) { info->j = j; - if (scf_vector_add(path->diodes, info) < 0) { + if (scf_vector_add(path->infos, info) < 0) { free(info); return -ENOMEM; } @@ -560,7 +646,7 @@ _add: if (info) { info->j = i - 1; - if (scf_vector_add(path->diodes, info) < 0) { + if (scf_vector_add(path->infos, info) < 0) { free(info); return -ENOMEM; } @@ -571,14 +657,14 @@ _add: return 0; } -static int _topo_path_diodes(ScfEfunction* f, ses_path_t* path) +static int _topo_path_key_infos(ScfEfunction* f, ses_path_t* path) { ses_path_t* child; int ret; int i; - ret = __topo_path_diodes(f, path); + ret = __topo_path_key_infos(f, path); if (ret < 0) return ret; @@ -586,7 +672,7 @@ static int _topo_path_diodes(ScfEfunction* f, ses_path_t* path) for (i = 0; i < path->childs->size; i++) { child = path->childs->data[i]; - ret = _topo_path_diodes(f, child); + ret = _topo_path_key_infos(f, child); if (ret < 0) return ret; } @@ -596,7 +682,7 @@ static int _topo_path_diodes(ScfEfunction* f, ses_path_t* path) for (i = 0; i < path->bridges->size; i++) { child = path->bridges->data[i]; - ret = _topo_path_diodes(f, child); + ret = _topo_path_key_infos(f, child); if (ret < 0) return ret; } @@ -624,7 +710,7 @@ static int _topo_layers(ScfEfunction* f, scf_vector_t* paths) Bp = B->pins[SCF_EDA_Battery_POS]; Bn = B->pins[SCF_EDA_Battery_NEG]; - for (i = paths->size - 1; i >= 1; i--) { + for (i = paths->size - 1; i >= 0; i--) { child = paths->data[i]; assert(child->pins->size >= 2); @@ -703,17 +789,23 @@ static int topo_epin_cmp(const void* v0, const void* v1, void* arg) if (SCF_EDA_Diode == c1->type || (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_B == p1[1])) return 1; + if (SCF_EDA_Capacitor == c0->type) + return 1; + if (SCF_EDA_Capacitor == c1->type) + return -1; + return 0; } -static int _topo_diodes(ScfEfunction* f, ses_path_t* path) +static void _topo_key_components(ScfEfunction* f, ses_path_t* path) { ScfEcomponent* c; ScfEpin* p; int i; - path->n_diodes = 0; + path->n_diodes = 0; + path->n_capacitors = 0; for (i = 0; i < path->pins->size; i++) { p = path->pins->data[i]; @@ -729,10 +821,13 @@ static int _topo_diodes(ScfEfunction* f, ses_path_t* path) if (SCF_EDA_NPN_B == p->id) path->n_diodes++; + + } else if (SCF_EDA_Capacitor == c->type) { + + if (0 == p->id) + path->n_capacitors++; } } - - return 0; } int _topo_print(scf_vector_t* paths) @@ -778,6 +873,7 @@ static void _topo_clear(ScfEfunction* f) p->vflag = 0; p->pflag = 0; p->dr = 0; + p->jdr = 0; } } } @@ -869,11 +965,9 @@ int __ses_topo_paths(ScfEfunction* f, scf_vector_t* paths) for (i = 0; i < paths->size; i++) { path = paths->data[i]; - scf_vector_clear(path->diodes, ( void (*)(void*) )free); + scf_vector_clear(path->infos, ( void (*)(void*) )free); - int ret = _topo_diodes(f, path); - if (ret < 0) - return ret; + _topo_key_components(f, path); } int ret = _topo_layers(f, paths); @@ -905,29 +999,38 @@ static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* int i; do { - size = ctx->paths->size; + do { + size = ctx->paths->size; - for (i = 0; i < ctx->paths->size; i++) { - path = ctx->paths->data[i]; + for (i = 0; i < ctx->paths->size; i++) { + path = ctx->paths->data[i]; - ret = _topo_diodes(f, path); + _topo_key_components(f, path); + } + + scf_logd("size: %d, paths->size: %d\n", size, ctx->paths->size); + + ret = _topo_layers(f, ctx->paths); if (ret < 0) return ret; - } - ret = _topo_layers(f, ctx->paths); - if (ret < 0) - return ret; + ret = _topo_path_completes(f, ctx->paths); + if (ret < 0) + return ret; + } while (size > ctx->paths->size); - ret = _topo_path_completes(f, ctx->paths); + ret = _topo_path_connect(f, ctx->paths); if (ret < 0) return ret; } while (size > ctx->paths->size); + for (i = 0; i < ctx->paths->size; i++) { path = ctx->paths->data[i]; - ret = _topo_path_diodes(f, path); + _topo_key_components(f, path); + + ret = _topo_path_key_infos(f, path); if (ret < 0) return ret; } diff --git a/ses_step_va.c b/ses_step_va.c index afa56fa..f3611bd 100644 --- a/ses_step_va.c +++ b/ses_step_va.c @@ -1,6 +1,6 @@ #include"ses_core.h" -static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, double* a, double *ja, int* changed) +static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, double* a, int* changed, int64_t ns) { ses_path_t* child; @@ -60,15 +60,15 @@ static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, double* double _cpr = cp1->pr; double _csr = cp1->sr; - cp1->pr = child->pr; - cp1->sr = child->sr; + cp1->pr = child->pr; + cp1->sr = child->sr; if (child->n_diodes > 0) { __ses_path_va_diode(f, child); __ses_path_jr (f, child); } - int ret = __ses_path_va(f, child, changed); + int ret = __ses_path_va(f, child, changed, ns); if (ret < 0) return ret; @@ -87,14 +87,14 @@ static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, double* return n; } -static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i, double a, double ja) +static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i, double a) { - ScfEpin* p2; - ScfEpin* p0 = path->pins->data[i0]; - ScfEpin* p = path->pins->data[i]; + ScfEpin* p0 = path->pins->data[i0]; + ScfEpin* p = path->pins->data[i]; + ScfEcomponent* c = f->components[p->cid]; - double v; - double r; + double v; + double r; __ses_path_sr(f, path, i0, i, &r); @@ -102,10 +102,39 @@ static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i, p->v = p0->v - v; + if (SCF_EDA_Capacitor == c->type && (i & 0x1)) { + int sign = !p->id - p->id; + + p->v -= c->v * sign; + } + 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); } -int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed) +double __ses_path_v_capacitor(ScfEfunction* f, ses_path_t* path) +{ + ScfEcomponent* c; + ScfEpin* p; + + double v = 0; + int i; + + for (i = 0; i < path->pins->size; i += 2) { + p = path->pins->data[i]; + + c = f->components[p->cid]; + + if (SCF_EDA_Capacitor == c->type) { + int sign = p->id - !p->id; + + v += c->v * sign; + } + } + + return v; +} + +int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed, int64_t ns) { if (!path) return -EINVAL; @@ -137,12 +166,18 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed) el = f->elines[p1->lid]; p1->v = el->v; - double v = p0->v - p1->v; + double cv = 0; + double v = p0->v - p1->v; + + if (path->n_capacitors > 0) { + cv = __ses_path_v_capacitor(f, path); + v -= cv; + } ses_ur_i(&path->a, NULL, v, 0, path->pr, 0); - scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, r: %lg, a: %lg\n\n", - path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, path->pr, path->a); + scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, r: %lg, a: %lg\n\n", + path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, path->pr, path->a); double a = path->a; double r = 0; @@ -155,10 +190,10 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed) 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, 0); + __ses_path_split_v(f, path, i0, i, a); if (!(i & 0x1) && path->childs) { - int ret = __ses_path_split_a(f, path, i, &a, NULL, changed); + int ret = __ses_path_split_a(f, path, i, &a, changed, ns); if (ret < 0) return ret; @@ -171,17 +206,35 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed) el = f->elines[p->lid]; el->v = p->v; - r += p->r + p->dr; + + r += p->r + p->dr + p->jdr; if (i & 0x1) { - c = f->components[p->cid]; - r += c->r; - dv -= p->v; + c = f->components[p->cid]; + r += c->r + c->dr + c->jdr; + dv -= p->v; ses_ur_i(&p->a, NULL, dv, 0, r, 0); - p2 = path->pins->data[i - 1]; - p2->a = p->a; + p2 = path->pins->data[i - 1]; + + if (SCF_EDA_Capacitor == c->type) { + int sign = !p->id - p->id; + + dv -= c->v * sign; + + 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; + + scf_logi("c%ld->v: %lg, dv: %lg, ja: %lg, ns: %ld, uf: %lg, c->jdr: %lg\n", c->id, c->v, dv, p->a, ns, c->uf, c->jdr); + + __ses_status_check_line(f, f->elines[p ->lid], changed); + __ses_status_check_line(f, f->elines[p2->lid], changed); + } + + p2->a = p->a; if (path->childs) { for (j = 0; j < path->childs->size; j++) { @@ -203,7 +256,7 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed) if (SCF_EDA_Diode_NEG == p->id) { p2 = path->pins->data[i - 1]; - *changed += __ses_status_check(f, c, p2, p); + *changed += __ses_status_check(f, c, p2, p, 1); __ses_pn_dr(c, p2, p); } @@ -214,7 +267,7 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed) p2 = path->pins->data[i - 1]; if (SCF_EDA_NPN_B == p2->id) { - *changed += __ses_status_check(f, c, p2, p); + *changed += __ses_status_check(f, c, p2, p, 1); __ses_npn_dr(c, p2, p); @@ -270,7 +323,7 @@ static int _va_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ct __ses_path_jr(f, path); - int ret = __ses_path_va(f, path, &changed); + int ret = __ses_path_va(f, path, &changed, ns); if (ret < 0) return ret; } diff --git a/ses_step_va_bridge.c b/ses_step_va_bridge.c index d2bc45d..d60f34a 100644 --- a/ses_step_va_bridge.c +++ b/ses_step_va_bridge.c @@ -136,7 +136,7 @@ int __ses_flow_v_neg(ScfEfunction* f, ses_flow_t* flow, double dv_vip, int* chan if (SCF_EDA_Diode_NEG == p->id) { p2 = path->pins->data[j - 1]; - *changed += __ses_status_check(f, c, p2, p); + *changed += __ses_status_check(f, c, p2, p, 1); __ses_pn_dr(c, p2, p); } @@ -147,7 +147,7 @@ int __ses_flow_v_neg(ScfEfunction* f, ses_flow_t* flow, double dv_vip, int* chan p2 = path->pins->data[j - 1]; if (SCF_EDA_NPN_B == p2->id) { - *changed += __ses_status_check(f, c, p2, p); + *changed += __ses_status_check(f, c, p2, p, 1); __ses_npn_dr(c, p2, p); } @@ -164,7 +164,7 @@ int __ses_flow_v_neg(ScfEfunction* f, ses_flow_t* flow, double dv_vip, int* chan return 0; } -static int __ses_bridge_v(ScfEfunction* f, ses_path_t* bridge, double vmin, ses_flow_t* flow) +static int __ses_bridge_v(ScfEfunction* f, ses_path_t* bridge, double vmin, ses_flow_t* flow, int64_t ns) { ScfEline* el; ScfEpin* p0 = bridge->pins->data[0]; @@ -197,7 +197,7 @@ static int __ses_bridge_v(ScfEfunction* f, ses_path_t* bridge, double vmin, ses_ __changed = 0; - int ret = __ses_path_va(f, bridge, &__changed); + int ret = __ses_path_va(f, bridge, &__changed, ns); if (ret < 0) return ret; @@ -244,7 +244,7 @@ static int __ses_bridge_r(ScfEfunction* f, ses_path_t* bridge, int vmin, ses_flo return 0; } -static int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths) +static int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns) { if (!bridge) return -EINVAL; @@ -300,8 +300,8 @@ static int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* change double vmin = 0; int i; - for (i = 0; i < bridge->diodes->size; i++) { - info = bridge->diodes->data[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; } @@ -319,7 +319,7 @@ static int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* change int __changed = 0; - ret = __ses_path_va(f, bridge, &__changed); + ret = __ses_path_va(f, bridge, &__changed, ns); if (ret < 0) return ret; #if 0 @@ -347,18 +347,22 @@ static int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* change return 0; } -static int ses_path_va_bridge(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths) +static int ses_path_va_bridge(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths, int64_t ns) { ses_path_t* child; - size_t j; + int ret; + int j; if (!path) return -EINVAL; - int ret = __ses_path_va_bridge(f, path, changed, paths); - if (ret < 0) - return ret; + if (0 == path->n_capacitors) { + + ret = __ses_path_va_bridge(f, path, changed, paths, ns); + if (ret < 0) + return ret; + } if (path->bridges) { scf_vector_t* vec = scf_vector_clone(path->childs); @@ -374,7 +378,7 @@ static int ses_path_va_bridge(ScfEfunction* f, ses_path_t* path, int* changed, s for (j = 0; j < path->bridges->size; j++) { child = path->bridges->data[j]; - ret = ses_path_va_bridge(f, child, changed, vec); + ret = ses_path_va_bridge(f, child, changed, vec, ns); if (ret < 0) { scf_vector_free(vec); return ret; @@ -398,7 +402,7 @@ static int _va_bridge_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ct for (i = 0; i < ctx->paths->size; i++) { path = ctx->paths->data[i]; - int ret = ses_path_va_bridge(f, path, &changed, ctx->paths); + int ret = ses_path_va_bridge(f, path, &changed, ctx->paths, ns); if (ret < 0) return ret; } diff --git a/ses_step_va_capacitor.c b/ses_step_va_capacitor.c new file mode 100644 index 0000000..1951253 --- /dev/null +++ b/ses_step_va_capacitor.c @@ -0,0 +1,218 @@ +#include"ses_core.h" + +void __ses_status_check_line(ScfEfunction* f, ScfEline* el, int* changed) +{ + ScfEcomponent* c; + ScfEpin* p0; + ScfEpin* p1; + + int i; + + 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; + + if (SCF_EDA_Diode == c->type) { + + p0 = c->pins[SCF_EDA_Diode_POS]; + p1 = c->pins[SCF_EDA_Diode_NEG]; + + *changed += __ses_status_check(f, c, p0, p1, 0); + + } else if (SCF_EDA_NPN == c->type) { + + p0 = c->pins[SCF_EDA_NPN_B]; + p1 = c->pins[SCF_EDA_NPN_E]; + + *changed += __ses_status_check(f, c, p0, p1, 0); + } + } +} + +static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_t* bridge, int* changed, int64_t ns) +{ + ses_flow_t* flow0; + ses_flow_t* flow1; + ses_path_t* fpath; + + ScfEcomponent* B; + ScfEcomponent* c; + ScfEline* el; + ScfEpin* p0; + ScfEpin* p1; + ScfEpin* Bp; + ScfEpin* Bn; + + int i; + int j; + + 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]; + + el = f->elines[p0->lid]; + p0->v = el->v; + + el = f->elines[p1->lid]; + p1->v = el->v; + + 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 jr; + double jv; + double cv; + double ja; + + cv = __ses_path_v_capacitor(f, bridge); + + 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->pr; + ja = jv / jr; + + p0->v = Bp->v - ja * flow0->pos_r; + p1->v = Bn->v + ja * flow1->neg_r; + + 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); + + } else { + jv = Bp->v + cv; + jr = flow1->pos_r + flow0->neg_r + bridge->pr; + ja = jv / jr; + + p1->v = Bp->v - ja * flow1->pos_r; + p0->v = Bn->v + ja * flow0->neg_r; + + 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); + } + + 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); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + + __ses_status_check_line(f, f->elines[p0->lid], changed); + __ses_status_check_line(f, f->elines[p1->lid], changed); + return 0; +} + +static int ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_t* bridge, int* changed, int64_t ns) +{ + ses_path_t* child; + + int ret; + int j; + + if (!bridge || bridge->pins->size < 2) + return -EINVAL; + + if (bridge->n_capacitors > 0) { + + __ses_path_jr(f, bridge); + + ret = __ses_path_va_capacitor(f, paths, bridge, changed, ns); + 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); + if (ret < 0) + return ret; + } + } + + return 0; +} + +static int _va_capacitor_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) +{ + ses_path_t* path; + + 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 changed = 0; + + int ret = ses_path_va_capacitor(f, ctx->paths, path, &changed, ns); + if (ret < 0) + return ret; + + if (changed > 0) + break; + + printf("\n"); + } + + return 0; +} + +ses_step_t ses_step_va_capacitor = +{ + .name = "va_capacitor", + + .handler = _va_capacitor_handler, +}; diff --git a/ses_step_va_diode.c b/ses_step_va_diode.c index fd1ed3c..3c56ba4 100644 --- a/ses_step_va_diode.c +++ b/ses_step_va_diode.c @@ -188,8 +188,8 @@ static void __ses_path_a_diode(ScfEfunction* f, ses_path_t* path, int k, double* int i = 0; int j; - for (j = k; j < path->diodes->size; j++) { - info = path->diodes->data[j]; + for (j = k; j < path->infos->size; j++) { + info = path->infos->data[j]; pi = path->pins->data[i]; pj = path->pins->data[info->i]; @@ -255,8 +255,8 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path) double r; double a; - for (j = 0; j < path->diodes->size; j++) { - info = path->diodes->data[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]; diff --git a/ses_step_va_transistor.c b/ses_step_va_transistor.c index 6d230fa..2ed48dc 100644 --- a/ses_step_va_transistor.c +++ b/ses_step_va_transistor.c @@ -13,13 +13,13 @@ void __ses_path_dr_transistor(ScfEfunction* f, ses_path_t* path, int i, int j) ses_ui_r(&dr, NULL, v, 0, p->a, 0); - p->dr = dr - r; + p->dr = dr - r; scf_logi("c%ldp%ld--c%ldp%ld, v: %lg, r: %lg, dr: %lg, p->sr: %lg, p->a: %lg, p->dr: %lg\n", p->cid, p->id, p1->cid, p1->id, v, r, dr, p->sr, p->a, p->dr); } -int __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe) +int __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe, int vinit) { ScfEcomponent* c2; ScfEline* el; @@ -81,7 +81,7 @@ _changed: p2 = c->pins [SCF_EDA_NPN_C]; el = f->elines[p2->lid]; - el->vinit = 1; + el->vinit = vinit; for (i = 0; i + 1 < el->n_pins; i += 2) { diff --git a/ses_steps.c b/ses_steps.c index 5f36ea2..86e8f58 100644 --- a/ses_steps.c +++ b/ses_steps.c @@ -11,7 +11,6 @@ extern ses_step_t ses_step_dc_transistor; //extern ses_step_t ses_step_ac_transistor; //extern ses_step_t ses_step_ac_diode; -extern ses_step_t ses_step_simplify; extern ses_step_t ses_step_topo; extern ses_step_t ses_step_jr; @@ -21,7 +20,11 @@ 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_open; +extern ses_step_t ses_step_va_capacitor; + extern ses_step_t ses_step_output; +extern ses_step_t ses_step_simplify; static ses_step_t* ses_steps_0[] = @@ -51,12 +54,15 @@ static ses_step_t* ses_steps_1[] = static ses_step_t* ses_steps_2[] = { + &ses_step_open, + &ses_step_va_capacitor, + &ses_step_output, &ses_step_simplify, }; -static int __ses_steps_input(ScfEfunction* f, int64_t ns, int64_t i, ses_ctx_t* ctx) +static int __ses_analyse_input(ScfEfunction* f, int64_t ns, int64_t i, ses_ctx_t* ctx) { ses_step_t* s; @@ -78,7 +84,7 @@ static int __ses_steps_input(ScfEfunction* f, int64_t ns, int64_t i, ses_ctx_t* return 0; } -static int __ses_steps_output(ScfEfunction* f, int64_t ns, int64_t i, ses_ctx_t* ctx) +static int __ses_analyse_time(ScfEfunction* f, int64_t ns, int64_t i, ses_ctx_t* ctx) { ses_step_t* s; @@ -100,7 +106,7 @@ static int __ses_steps_output(ScfEfunction* f, int64_t ns, int64_t i, ses_ctx_t* return 0; } -static int __ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t i, ses_ctx_t* ctx) +static int __ses_analyse_current(ScfEfunction* f, int64_t ns, int64_t i, ses_ctx_t* ctx) { ses_step_t* s; @@ -133,19 +139,26 @@ int ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count) if (!ctx) return -ENOMEM; - int64_t i; + ScfEline* el; + int64_t i; + + for (i = 0; i < f->n_elines; i++) { + el = f->elines[i]; + el->v = SCF_EDA_V_INIT; + } for (i = 0; i < count; i++) { + printf("\n\033[36m%s(), %d(), count: %ld\033[0m\n", __func__, __LINE__, i); - int ret = __ses_steps_input(f, ns, i, ctx); + int ret = __ses_analyse_input(f, ns, i, ctx); if (ret < 0) return ret; int j; - for (j = 0; j < 2; j++) { + for (j = 0; j < 1; j++) { printf("\n\033[33m%s(), %d(), j: %d\033[0m\n", __func__, __LINE__, j); - ret = __ses_steps_analyse(f, ns, i, ctx); + ret = __ses_analyse_current(f, ns, i, ctx); if (-EAGAIN == ret) continue; @@ -157,7 +170,7 @@ int ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count) break; } - ret = __ses_steps_output(f, ns, i, ctx); + ret = __ses_analyse_time(f, ns, i, ctx); if (ret < 0) return ret; } diff --git a/ses_utils.c b/ses_utils.c index 3208b35..a64b5f8 100644 --- a/ses_utils.c +++ b/ses_utils.c @@ -255,8 +255,8 @@ ses_path_t* ses_path_alloc() return NULL; } - path->diodes = scf_vector_alloc(); - if (!path->diodes) { + path->infos = scf_vector_alloc(); + if (!path->infos) { scf_vector_free(path->pins); free(path); return NULL; @@ -271,9 +271,9 @@ void ses_path_free(ses_path_t* path) if (path->pins) scf_vector_free(path->pins); - if (path->diodes) { - scf_vector_clear(path->diodes, ( void (*)(void*) )free); - scf_vector_free (path->diodes); + if (path->infos) { + scf_vector_clear(path->infos, ( void (*)(void*) )free); + scf_vector_free (path->infos); } if (path->childs) { @@ -303,7 +303,7 @@ void ses_path_print(ses_path_t* path) int i; if (!path->parent) - printf("\033[31mpath : %d, n_diodes: %d, diodes->size: %d, \033[0m", path->index, path->n_diodes, path->diodes->size); + 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]; @@ -316,7 +316,7 @@ void ses_path_print(ses_path_t* path) for (i = 0; i < path->childs->size; i++) { path2 = path->childs->data[i]; - printf("\033[32mchild : %d, n_diodes: %d, diodes->size: %d, parent: %d, \033[0m", path2->index, path2->n_diodes, path2->diodes->size, path->index); + 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); } @@ -326,7 +326,7 @@ void ses_path_print(ses_path_t* path) for (i = 0; i < path->bridges->size; i++) { path2 = path->bridges->data[i]; - printf("\033[33mbridge: %d, n_diodes: %d, diodes->size: %d, parent: %d, \033[0m", path2->index, path2->n_diodes, path2->diodes->size, path->index); + 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); } diff --git a/test/Makefile b/test/Makefile index 0b8c383..47e90db 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,12 +1,11 @@ CFILES += main.c -CFILES += ../scf_eda.pb-c.c -CFILES += ../scf_eda_pb.c +CFILES += ../scf_eda_pack.c +CFILES += ../pack/scf_pack.c CFLAGS += -g CFLAGS += -I../ +CFLAGS += -I../pack -LDFLAGS += -lm -LDFLAGS += -lprotobuf-c LDFLAGS += -lcairo all: diff --git a/test/main.c b/test/main.c index e395d3e..651b143 100644 --- a/test/main.c +++ b/test/main.c @@ -6,59 +6,68 @@ int main(int argc, char* argv[]) { ScfEcomponent* B; - ScfEcomponent* T0; ScfEcomponent* R0; ScfEcomponent* R1; ScfEcomponent* R2; ScfEcomponent* R3; + ScfEcomponent* T0; + ScfEcomponent* T1; ScfEcomponent* C0; + ScfEcomponent* C1; ScfEfunction* f; ScfEboard* b; b = scf_eboard__alloc(); - f = scf_efunction__alloc("test"); + f = scf_efunction__alloc("oscillator"); EDA_INST_ADD_COMPONENT(f, B, SCF_EDA_Battery); B->pins[SCF_EDA_Battery_NEG]->flags = SCF_EDA_PIN_NEG; B->pins[SCF_EDA_Battery_POS]->flags = SCF_EDA_PIN_POS; - EDA_INST_ADD_COMPONENT(f, T0, SCF_EDA_NPN); EDA_INST_ADD_COMPONENT(f, R0, SCF_EDA_Resistor); EDA_INST_ADD_COMPONENT(f, R1, SCF_EDA_Resistor); EDA_INST_ADD_COMPONENT(f, R2, SCF_EDA_Resistor); EDA_INST_ADD_COMPONENT(f, R3, SCF_EDA_Resistor); + EDA_INST_ADD_COMPONENT(f, T0, SCF_EDA_NPN); + EDA_INST_ADD_COMPONENT(f, T1, SCF_EDA_NPN); EDA_INST_ADD_COMPONENT(f, C0, SCF_EDA_Capacitor); + EDA_INST_ADD_COMPONENT(f, C1, SCF_EDA_Capacitor); EDA_PIN_ADD_PIN(B, SCF_EDA_Battery_POS, R0, 1); - EDA_PIN_ADD_PIN(R0, 0, R1, 1); - EDA_PIN_ADD_PIN(R1, 0, B, SCF_EDA_Battery_NEG); - EDA_PIN_ADD_PIN(T0, SCF_EDA_NPN_B, R1, 1); - + EDA_PIN_ADD_PIN(B, SCF_EDA_Battery_POS, R1, 1); EDA_PIN_ADD_PIN(B, SCF_EDA_Battery_POS, R2, 1); - EDA_PIN_ADD_PIN(R2, 0, T0, SCF_EDA_NPN_C); - EDA_PIN_ADD_PIN(T0, SCF_EDA_NPN_E, R3, 1); - EDA_PIN_ADD_PIN(T0, SCF_EDA_NPN_E, C0, 1); - EDA_PIN_ADD_PIN(R3, 0, B, SCF_EDA_Battery_NEG); - EDA_PIN_ADD_PIN(C0, 0, B, SCF_EDA_Battery_NEG); + EDA_PIN_ADD_PIN(B, SCF_EDA_Battery_POS, R3, 1); - scf_eboard__add_function(b, f); + EDA_PIN_ADD_PIN(R0, 0, T0, SCF_EDA_NPN_C); + EDA_PIN_ADD_PIN(T0, SCF_EDA_NPN_E, B, SCF_EDA_Battery_NEG); + EDA_PIN_ADD_PIN(R0, 0, C0, 1); + EDA_PIN_ADD_PIN(R1, 0, C0, 0); + + EDA_PIN_ADD_PIN(R3, 0, T1, SCF_EDA_NPN_C); + EDA_PIN_ADD_PIN(T1, SCF_EDA_NPN_E, B, SCF_EDA_Battery_NEG); + EDA_PIN_ADD_PIN(R3, 0, C1, 1); + EDA_PIN_ADD_PIN(R2, 0, C1, 0); + + EDA_PIN_ADD_PIN(C0, 0, T1, SCF_EDA_NPN_B); + EDA_PIN_ADD_PIN(C1, 0, T0, SCF_EDA_NPN_B); - size_t len = scf_eboard__get_packed_size(b); + T0->pins[SCF_EDA_NPN_C]->flags |= SCF_EDA_PIN_OUT; + T1->pins[SCF_EDA_NPN_C]->flags |= SCF_EDA_PIN_OUT; - scf_loge("len: %ld\n", len); + C0->uf = 0.001; + C1->uf = 0.001; + + scf_eboard__add_function(b, f); - uint8_t* buf = malloc(len); - if (!buf) { - scf_eboard__free(b); - return -ENOMEM; - } + int len = 0; + uint8_t* buf = NULL; - scf_eboard__pack(b, buf); - scf_eboard__free(b); + ScfEboard_pack(b, &buf, &len); + ScfEboard_free(b); b = NULL; - FILE* fp = fopen("./test.pb", "wb"); + FILE* fp = fopen("./oscillator.pack", "wb"); if (!fp) return -EINVAL;