From c254d056472f998c1c6fc94a949dfb9047f30fb4 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Wed, 21 Aug 2024 15:17:18 +0800 Subject: [PATCH] support simple IC (based on NPN, PNP and resistor) --- Makefile | 2 - cpk/Makefile | 4 +- cpk/add_gate.c | 3 +- cpk/nand.c | 46 ++- cpk/nand.cpk | Bin 301 -> 401 bytes cpk/nor.c | 13 +- cpk/nor.cpk | Bin 304 -> 391 bytes cpk/not.c | 12 +- cpk/not.cpk | Bin 194 -> 260 bytes cpk/or_gate.c | 2 +- examples/add.cpk | Bin 1336 -> 0 bytes examples/add2.cpk | Bin 3331 -> 0 bytes examples/and.cpk | Bin 728 -> 0 bytes examples/and_gate.cpk | Bin 0 -> 537 bytes examples/or.cpk | Bin 731 -> 0 bytes examples/sin_oscillator.cpk | Bin 1021 -> 1034 bytes examples/sub.cpk | Bin 1397 -> 0 bytes main.c | 111 +++++- scf_eda_pack.c | 213 +++++++++++- scf_eda_pack.h | 9 +- ses_core.h | 96 +++--- ses_layout.c | 178 +--------- ses_node_analysis.c | 55 +-- ses_path.c | 56 +-- ses_step_dc_diode.c | 101 ++++-- ses_step_dc_npn.c | 71 ++-- ses_step_dc_pnp.c | 77 +++-- ses_step_jr.c | 70 +--- ses_step_open.c | 135 +++++--- ses_step_topo.c | 655 +++++++++++++++++------------------- ses_step_va.c | 562 +------------------------------ ses_steps.c | 9 +- test/main.c | 2 +- 33 files changed, 1061 insertions(+), 1421 deletions(-) delete mode 100644 examples/add.cpk delete mode 100644 examples/add2.cpk delete mode 100644 examples/and.cpk create mode 100644 examples/and_gate.cpk delete mode 100644 examples/or.cpk delete mode 100644 examples/sub.cpk diff --git a/Makefile b/Makefile index be7e530..17f9afc 100644 --- a/Makefile +++ b/Makefile @@ -20,9 +20,7 @@ CFILES += ses_step_dc_pnp.c CFILES += ses_step_topo.c CFILES += ses_step_jr.c -CFILES += ses_step_va_diode.c CFILES += ses_step_va.c -CFILES += ses_step_status.c CFILES += ses_step_open.c CFILES += ses_step_va_nodes.c diff --git a/cpk/Makefile b/cpk/Makefile index bcf56ea..2f54c61 100644 --- a/cpk/Makefile +++ b/cpk/Makefile @@ -1,7 +1,7 @@ -#CFILES += nand.c +CFILES += nand.c #CFILES += nor.c #CFILES += not.c -CFILES += and_gate.c +#CFILES += and_gate.c #CFILES += or_gate.c #CFILES += add_gate.c CFILES += ../scf_eda_pack.c diff --git a/cpk/add_gate.c b/cpk/add_gate.c index 4868d60..89305c2 100644 --- a/cpk/add_gate.c +++ b/cpk/add_gate.c @@ -53,10 +53,9 @@ int main(int argc, char* argv[]) NOR1->pins[SCF_EDA_NOR_OUT]->flags = SCF_EDA_PIN_OUT; - scf_logi("\n"); scf_eboard__add_function(b, f); - int len = 0; + long len = 0; uint8_t* buf = NULL; ScfEboard_pack(b, &buf, &len); diff --git a/cpk/nand.c b/cpk/nand.c index f2b7a01..acbbf0e 100644 --- a/cpk/nand.c +++ b/cpk/nand.c @@ -5,7 +5,9 @@ int main(int argc, char* argv[]) { - ScfEcomponent* B; + ScfEcomponent* c; + ScfEline* el; + ScfEpin* p; ScfEcomponent* R0; ScfEcomponent* T0; @@ -22,16 +24,46 @@ int main(int argc, char* argv[]) EDA_PIN_ADD_PIN(R0, 0, T0, SCF_EDA_NPN_C); EDA_PIN_ADD_PIN(T0, SCF_EDA_NPN_E, T1, SCF_EDA_NPN_C); - R0->pins[1]->flags = SCF_EDA_PIN_POS; - T1->pins[SCF_EDA_NPN_E]->flags = SCF_EDA_PIN_NEG; + R0->pins[1]->flags = SCF_EDA_PIN_POS; + T1->pins[SCF_EDA_NPN_E]->flags = SCF_EDA_PIN_NEG; - T0->pins[SCF_EDA_NPN_B]->flags = SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0; - T1->pins[SCF_EDA_NPN_B]->flags = SCF_EDA_PIN_IN; - R0->pins[0]->flags = SCF_EDA_PIN_OUT; + T0->pins[SCF_EDA_NPN_B]->flags = SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0; + T1->pins[SCF_EDA_NPN_B]->flags = SCF_EDA_PIN_IN; + R0->pins[0]->flags = SCF_EDA_PIN_OUT; - int len = 0; + R0->pins[1]->ic_lid = SCF_EDA_NAND_POS; + T1->pins[SCF_EDA_NPN_E]->ic_lid = SCF_EDA_NAND_NEG; + + T0->pins[SCF_EDA_NPN_B]->ic_lid = SCF_EDA_NAND_IN0; + T1->pins[SCF_EDA_NPN_B]->ic_lid = SCF_EDA_NAND_IN1; + R0->pins[0]->ic_lid = SCF_EDA_NAND_OUT; + + int ret = scf_pins_same_line(f); + if (ret < 0) + return ret; + + long len = 0; uint8_t* buf = NULL; + scf_logi("f->n_components: %ld\n", f->n_components); + + long i; + long j; + long k; + + for (i = 0; i < f->n_elines; i++) { + el = f->elines[i]; + + for (j = 0; j + 1 < el->n_pins; j += 2) { + + c = f->components[el->pins[j]]; + p = c->pins [el->pins[j + 1]]; + + scf_logi("e%ld->flags: %#lx, c%ldp%ld\n", el->id, el->flags, c->id, p->id); + } + printf("\n"); + } + ScfEfunction_pack(f, &buf, &len); ScfEfunction_free(f); f = NULL; diff --git a/cpk/nand.cpk b/cpk/nand.cpk index b80fcfaa098fef1c4330139eaaf7ff1f1981c9ad..d8cd77991ed7a4fcbf4b5a21243655932f3f65f8 100644 GIT binary patch literal 401 zcma)2I|@QU5E~&yie=bh!B<*XdjP9Erpins[SCF_EDA_NPN_B]->flags = SCF_EDA_PIN_IN; R0->pins[0]->flags = SCF_EDA_PIN_OUT; - int len = 0; + R0->pins[1]->ic_lid = SCF_EDA_NOR_POS; + T0->pins[SCF_EDA_NPN_E]->ic_lid = SCF_EDA_NOR_NEG; + + T0->pins[SCF_EDA_NPN_B]->ic_lid = SCF_EDA_NOR_IN0; + T1->pins[SCF_EDA_NPN_B]->ic_lid = SCF_EDA_NOR_IN1; + R0->pins[0]->ic_lid = SCF_EDA_NOR_OUT; + + int ret = scf_pins_same_line(f); + if (ret < 0) + return ret; + + long len = 0; uint8_t* buf = NULL; ScfEfunction_pack(f, &buf, &len); diff --git a/cpk/nor.cpk b/cpk/nor.cpk index 9fc5bc88ee2b512a4a79a785177f6164985ae354..3fb988d46a32512595309a6c7de07da117762ac0 100644 GIT binary patch literal 391 zcmb7=u?+%23Gx5w;NwVZf%I1^4@7=sKtZf+sf$>OSB4ZVn36$gecYCs)~-Jr5dnAEx#9 zL@Z*OvA|0C;UyYnDBxO(`j^+<0?>l(4FVPPbFR#kxfc~3popins[SCF_EDA_NPN_B]->flags = SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0; R0->pins[0]->flags = SCF_EDA_PIN_OUT; - int len = 0; + R0->pins[1]->ic_lid = SCF_EDA_NOT_POS; + T0->pins[SCF_EDA_NPN_E]->ic_lid = SCF_EDA_NOT_NEG; + + T0->pins[SCF_EDA_NPN_B]->ic_lid = SCF_EDA_NOT_IN; + R0->pins[0]->ic_lid = SCF_EDA_NOT_OUT; + + int ret = scf_pins_same_line(f); + if (ret < 0) + return ret; + + long len = 0; uint8_t* buf = NULL; ScfEfunction_pack(f, &buf, &len); diff --git a/cpk/not.cpk b/cpk/not.cpk index f74503d7aef56bff56abe1a48c53a50146e4bede..ebf9f729ea5aa09df6827e3bdacf9d8ee50cb043 100644 GIT binary patch literal 260 zcmZXPyA8uI3`Ebs6;}|1x}?+u86cH*aT&mNksXq~vQZ{58NiMJ9Sef@2!86aK5z5( zfPMj!C^HNqSU?Vb8t(5;>j-S1U3QROHlW=wxR296o^zk U4JsCwvy5+$cO0@n!DBacdke6Sgmt2s|zyXE~3>+LR91{(NSy&ht1ST4aOmtwG=qkp_V8zG4FfmaN SC<|1=0A$ZppXk8K$N&JhzYC=R diff --git a/cpk/or_gate.c b/cpk/or_gate.c index 2641657..854c884 100644 --- a/cpk/or_gate.c +++ b/cpk/or_gate.c @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) scf_eboard__add_function(b, f); - int len = 0; + long len = 0; uint8_t* buf = NULL; ScfEboard_pack(b, &buf, &len); diff --git a/examples/add.cpk b/examples/add.cpk deleted file mode 100644 index ad32f5061b8ad2c55302396f605016a8791e98d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1336 zcmb7EK}y6x5bQ%E4Tf=qfOE)U4ncAVl0y#SLE=+{_3ZvaKj4cz@6|VW_61fYn2p0M z%nt0*(=}67-JL}J^KK{iqGBQv2h&=EHri^ZNTdrnA1n15wa?)^fAR5k`+a$L{phY< z4u_{Bg$Ai0BtFQ%taJOf=?Kq}0ym?VbQzI~*`FKyIXAsd+?`rRH4ynmMxM#40ncgC z1Aa79s8$(>;LfYnIY$c2SbTOl_x?F;5KlHQldrAaq}NdWIczmM0ar`+vV9=BvTp-c zV^AyYL!ef`ow?Mk7SXN58e?K&k=wEfH`HoyXQs<)5ncJWff0$!lxamy1m{Dr#yZ|h zmqu!pPPnCa%y#K*);rNuWZv_cu%2O=_l{cdywsc3BAVACa)wsVKJ_T8wJyh~;41IZ oKsJ0UmZvE-sDnJXH2JqrU#XE)BdBt&M8}hp!-wPl%Q-9j0`-A4u>b%7 diff --git a/examples/add2.cpk b/examples/add2.cpk deleted file mode 100644 index ae8ca9aa82ed41b209a0da9463b64acda7155b47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3331 zcmb7Fv5MP35S?NO12KvMhNy6%!UPv4xNu>D2^(;s!i5VLE?hX^fC@ugxNzaZg(3F? z`J&X<<{MJy3-X?h^ZDcvtQPKWwQuLWH#56?ntt1Eksz5kND`~LX&^@U6`>A--bnT)ua zB>SJ?1+Hca+>9RU!-#aa`tJjNB}w=Z_|-IwY9LB`GUgsv4Y;R85BQ;(NVSfE2<}p~ zuIEUB8IyNMl05tlH%LmhR6^FZzRYic>r~S=d|lQ8zMksmR)Xl2{dU593~I5J$f%Ve zrb^b;B6=%voug-BIX~li+@n?xF%_MwMfA#lJ24_TSK_pC_5}O0%z8FpTzzOxt=Jy- z>AjDLsd2S$Z4GS0kz=yDPLEMsINt&h1QUD8X~Q}4Ln8#SA3O5WW#Im zbeif0btIpY`r`9<{ZfrdH3pUEN_5=VIXoS&ujhnJ6I}MGmCtIoe-&7Kic>acibr`N zD>=%UOm2&?$AV|xh(I&;I0PyNC>FAmgIpNtDq@cnO1L&G0GSerJAgA*Y$h@&Y+*~= zNa?XEcEs1MU={@;;HAMo&}?oC4W61Y7K*Vs%&CXRI6dKMZc+s9bqK3Os#?ZXY(cdJ zV$j=$?1=i^A<`nVCAF4_35{ArS6*gDq=nXsS}Vjf=S7r8?uHRrvX^l+T=UeeCD_K} z(=~O-=8gKD-_Z945mm14Z6WGW3C_D1)M9;a>3fSOw6vYasM|KqOFAzRQN0kZbD~vV zb^CnZ3~I5?chuS;X3rQ`izvanVMJPJ?O7%0e8`54(#056_^d82|tP diff --git a/examples/and.cpk b/examples/and.cpk deleted file mode 100644 index 717e76d4bebb0889739ad2958d4820de3954c6d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 728 zcmb7Cu?@mN40K^3OS~QStx27}F);G!~{2FoqPk;c5YOpQ8amD-*SX7?Jg+ESX2hh6x6DBgXqP zbr1!cnhlxP9qT__8C`i$j^WU3VJT=2Rxz!xhyG`yw4F zQOe_W9Hih?i#a_)YV}4UypW0&n+{456AbGi*{oNH4G9)w)r<<_VBsl8@Y7%|bITQQ V3ICGykWN;iNM+Agooi&?U%$7B4|xCp literal 0 HcmV?d00001 diff --git a/examples/or.cpk b/examples/or.cpk deleted file mode 100644 index a861ebd124931f1a2da9e0bc458cea2ba4923012..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 731 zcmb7Bu?@mN40K^3OT5e@MdFJTRFn)rfu3QggIEFv+aaU|m6<@ecV z`^=%b(w3Nnh_;DYxL|XKX0aFpM-M~p;_=$Om;3cmSLeDub>*BW7(GcsO!ach9oTpb zbP#L50wloyZ0u3ZRmN}1tVaNql*n*<0d>m-$c$b=jL7m6i%8*7vY~?2T~ob3a}SB& zi)38hd>rR+70|(EYWHz<0NU%`x!6Ul+rOG8%x$;Dt;S~8Kj=8zMurlUpt9596l3FZ MQcFAaub55s7duEB^8f$< diff --git a/examples/sin_oscillator.cpk b/examples/sin_oscillator.cpk index ddeef15c536b97182b845c924d9c062b5c9df318..5e1c5c88a00b62008dd3ab9d89f00c8be8b67393 100644 GIT binary patch delta 281 zcmey%-o-INg^_WxB9kx|1A~Bo28#|01LH(T8;ID%37kO2Lng6_8>FEk_t+VM@}d)e zD*y$g8RdYaC8G?G3}sZGT+7G$Pfv$&|4fPO*4#;AV(O_@#vjQE#zyJWHPcvHp delta 278 zcmY+9L2d#u3`LzdK$r#yGpstOjMR}p6(?W^Czu60j=)V25{>=^dV*PZ!Gfc-K$ks1 zg+vmnih5-~e}CH>eQCXxIC0umMAlB!RN<2cZux>Qwr*!|?zBCuWj9)HW!#2~eC!m) zyBGezQVkU5oHdoN^e`@~I8VwTC_OR(HC0H9-|jfrwbaBTiqBy$GQ6|7@#!CTb=IH| ESIJ{Ut^fc4 diff --git a/examples/sub.cpk b/examples/sub.cpk deleted file mode 100644 index aea4f8909d3ac6a128af4debd569d811f37655b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1397 zcmb7^K}y9i5Qb+l$bcnADA+|8T@>k}NEdHWM5JCtaIGMoK`-EmT)(YnaP0~F|GXzP zA%z%tkjbB!|LY`q>Yrcka2akPfW*LABCGdmVE-ka6<`gL$FhcEjZ_4-nTyUnz5Z3X2D|V@oX5kc1p4m_ zD9$a9OS~hBDsorg_BKVrF;Hm5+@9PX#X8wBKT8hXYMw?qj0)^TipXo4q1V1;-#5&l z=d6f;pJ!r`S;ICpxIwLTHpmnl>H23V^x{^vq;C%#8|+Yhmoq{ZGhtUq-_fi?3Oc-D zMzzhE8I^LYo{j2du_4!Y?NRJ-TqKD{`U(b855Ml&yF@iEa*S|BVlXRg&`9c0%%)s9 z9sfZ+k$OTxxXD>+s-dGPI-j7ytdM#~YCN>Vv8KgzC)X}rJjQ9OXI7d~DfjuJ^VX5! Kg~$I~q5cnO-Z=pP diff --git a/main.c b/main.c index 8d9aa7b..d45a58b 100644 --- a/main.c +++ b/main.c @@ -49,14 +49,86 @@ static void print_board(ScfEboard* b) } } +int ses_init_component(ScfEcomponent* c) +{ + ScfEcomponent* c2; + ScfEdata* ed; + + ed = scf_ecomponent__find_data(c->type, c->model); + if (!ed) + return -EINVAL; + c->ops = ed->ops; + + if (!ed->cpk) + return 0; + + uint8_t* buf = NULL; + + long len = scf_pack_read(&buf, ed->cpk); + if (len < 0) { + scf_loge("scf_pack_read '%s' error: %ld\n", ed->cpk, len); + return len; + } + + long ret = ScfEfunction_unpack(&c->f, buf, len); + + free(buf); + buf = NULL; + + if (ret < 0) { + scf_loge("ScfEfunction_unpack error: %ld\n", ret); + return ret; + } + + scf_logi("c->f->n_components: %ld, c->f->n_elines: %ld\n", c->f->n_components, c->f->n_elines); + + long i; + long j; + for (i = 0; i < c->f->n_components; i++) { + c2 = c->f->components[i]; + + for (j = 0; j < c2->n_pins; j++) + c2->pins[j]->IC = c; + + ret = ses_init_component(c2); + if (ret < 0) + return ret; + + c2->pf = c->f; + } + + return 0; +} + +int ses_draw_IC(ScfEcomponent* c) +{ + ses_lines_same_components(c->f); + + int ret = ses_layout_function(c->f, 100); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + + char file[128]; + snprintf(file, sizeof(file) - 1, "./IC%ld.png", c->id); + + ses_draw(c->f, file, c->f->x, c->f->y, c->f->w, c->f->h, 0, 0); + return 0; +} + int main(int argc, char* argv[]) { if (argc < 2) { - scf_loge("./a.out 1.pb\n"); + printf("usage: ./a.out src.cpk [fname cid]\n\n"); + printf("fname: optional, function name in board\n"); + printf("cid : optional, component id in function, only for IC\n\n"); + printf("if set fname & cid, only show the internal graph of this IC\n"); return -EINVAL; } ScfEcomponent* c; + ScfEcomponent* c2; ScfEfunction* f; ScfEboard* b = NULL; ScfEdata* ed = NULL; @@ -70,30 +142,48 @@ int main(int argc, char* argv[]) } long ret = ScfEboard_unpack(&b, buf, len); + + free(buf); + buf = NULL; + if (ret < 0) { scf_loge("ScfEboard__unpack error: %ld\n", ret); + + ScfEboard_free(b); return ret; } - free(buf); - buf = NULL; - long i; long j; - for (i = 0; i < b->n_functions; i++) { f = b->functions[i]; for (j = 0; j < f->n_components; j++) { c = f->components[j]; - ed = scf_ecomponent__find_data(c->type, c->model); - if (ed) - c->ops = ed->ops; + ret = ses_init_component(c); + if (ret < 0) { + scf_loge("ses_init_component error: %ld\n", ret); + + ScfEboard_free(b); + return ret; + } + + if (4 == argc && c->f && !strcmp(argv[2], f->name) && atol(argv[3]) == c->id) { + + ret = ses_draw_IC(c); + if (ret < 0) + scf_loge("ses_draw_IC error: %ld\n", ret); + + ScfEboard_free(b); + return 0; + } + + c->pf = f; } } // print_board(b); -#if 1 + ses_layout_board(b, 100); for (i = 0; i < b->n_functions; i++) { @@ -101,9 +191,8 @@ int main(int argc, char* argv[]) printf("f: %s\n", f->name); -// ses_steps_analyse(f, 100, 1); + ses_steps_analyse(f, 100, 4); } -#endif ScfEboard_free(b); return 0; diff --git a/scf_eda_pack.c b/scf_eda_pack.c index c56a19f..0538826 100644 --- a/scf_eda_pack.c +++ b/scf_eda_pack.c @@ -510,16 +510,6 @@ ScfEcomponent* scf_ecomponent__alloc(uint64_t type) c->uf = ed->uf; c->uh = ed->uh; c->ops = ed->ops; - - if (ed->cpk) { - c->n_cpk = strlen(ed->cpk) + 1; - - c->cpk = strdup(ed->cpk); - if (!c->cpk) { - ScfEcomponent_free(c); - return NULL; - } - } } int i; @@ -531,7 +521,10 @@ ScfEcomponent* scf_ecomponent__alloc(uint64_t type) return NULL; } - pin->id = i; + pin->id = i; + pin->ic_lid = -1; + + scf_loge("pin %p, id: %ld, ic_lid: %ld\n", pin, pin->id, pin->ic_lid); if (scf_ecomponent__add_pin(c, pin) < 0) { ScfEcomponent_free(c); @@ -744,3 +737,201 @@ int scf_eboard__del_function(ScfEboard* b, ScfEfunction* f) return -EINVAL; } + +static int epin_cmp(const void* v0, const void* v1) +{ + const uint64_t* t0 = v0; + const uint64_t* t1 = v1; + + if (t0[0] < t1[0]) + return -1; + + if (t0[0] > t1[0]) + return 1; + + if (t0[1] < t1[1]) + return -1; + + if (t0[1] > t1[1]) + return 1; + return 0; +} + +int scf_pins_same_line(ScfEfunction* f) +{ + ScfEcomponent* c; + ScfEline* el; + ScfEline* el2; + ScfEpin* p; + ScfEpin* p2; + + long i; + long j; + long k; + long m; + long n; + + for (i = 0; i < f->n_components; i++) { + c = f->components[i]; + + for (j = 0; j < c->n_pins; j++) { + p = c->pins[j]; + + qsort(p->tos, p->n_tos / 2, sizeof(uint64_t) * 2, epin_cmp); + + for (k = 0; k < f->n_elines; k++) { + el = f->elines[k]; + + for (m = 0; m + 1 < el->n_pins; m += 2) { + + if (el->pins[m] == p->cid && el->pins[m + 1] == p->id) + goto next; + } + + m = 0; + n = 0; + while (m + 1 < el->n_pins && n + 1 < p->n_tos) { + + if (el->pins[m] < p->tos[n]) + m += 2; + else if (el->pins[m] > p->tos[n]) + n += 2; + + else if (el->pins[m + 1] < p->tos[n + 1]) + m += 2; + else if (el->pins[m + 1] > p->tos[n + 1]) + n += 2; + + else { + if (scf_eline__add_pin(el, p->cid, p->id) < 0) + return -ENOMEM; + + p ->lid = el->id; + p ->c_lid = el->id; + el->flags |= p->flags; + goto next; + } + } + } + + el = scf_eline__alloc(); + if (!el) + return -ENOMEM; + el->id = f->n_elines; + + if (scf_efunction__add_eline(f, el) < 0) { + ScfEline_free(el); + return -ENOMEM; + } + + if (scf_eline__add_pin(el, p->cid, p->id) < 0) + return -ENOMEM; + + p ->lid = el->id; + p ->c_lid = el->id; + el->flags |= p->flags; +next: + for (n = 0; n + 1 < p->n_tos; n += 2) { + + p2 = f->components[p->tos[n]]->pins[p->tos[n + 1]]; + + if (p2->cid > p->cid + || (p2->cid == p->cid && p2->id > p->id)) + break; + + el2 = f->elines[p2->lid]; + + if (el2 == el) + continue; + + if (el2->id < el->id) + SCF_XCHG(el2, el); + + for (m = 0; m + 1 < el2->n_pins; m += 2) { + p2 = f->components[el2->pins[m]]->pins[el2->pins[m + 1]]; + + if (scf_eline__add_pin(el, p2->cid, p2->id) < 0) + return -ENOMEM; + + p2->lid = el->id; + p2->c_lid = el->id; + el->flags |= p2->flags; + } + + qsort(el->pins, el->n_pins / 2, sizeof(uint64_t) * 2, epin_cmp); + + el2->n_pins = 0; + } + p = NULL; + } + } + + for (i = 0; i < f->n_elines; ) { + el = f->elines[i]; + + if (0 == el->n_pins) { + scf_efunction__del_eline(f, el); + ScfEline_free(el); + continue; + } + + el->c_pins = el->n_pins; + i++; + } + + for (i = 0; i < f->n_elines; ) { + el = f->elines[i]; + el->id = i; + + int64_t eid = -1; + + for (j = 0; j + 1 < el->n_pins; j += 2) { + + c = f->components[el->pins[j]]; + p = c->pins [el->pins[j + 1]]; + + p->lid = i; + p->c_lid = i; + + if (p->ic_lid < 0) + continue; + + if (eid < 0) + eid = p->ic_lid; + + else if (eid != p->ic_lid) { + scf_loge("IC pin number set error, prev: %ld, current: %ld\n", eid, p->ic_lid); + return -EINVAL; + } + + scf_logd("pin j: %ld, c%ldp%ld\n", j, el->pins[j], el->pins[j + 1]); + } + + if (eid >= f->n_elines) { + scf_loge("IC pin number set error, max: %ld, current: %ld\n", f->n_elines - 1, eid); + return -EINVAL; + } + + scf_logd("i: %ld, eid: %ld\n", i, eid); + + if (eid >= 0 && eid != i) { + el->id = eid; + + for (j = 0; j + 1 < el->n_pins; j += 2) { + + c = f->components[el->pins[j]]; + p = c->pins [el->pins[j + 1]]; + + p->lid = eid; + p->c_lid = eid; + } + + SCF_XCHG(f->elines[eid], f->elines[i]); + continue; + } + + i++; + } + + return 0; +} diff --git a/scf_eda_pack.h b/scf_eda_pack.h index 2f094ab..f76525e 100644 --- a/scf_eda_pack.h +++ b/scf_eda_pack.h @@ -162,6 +162,7 @@ struct scf_epin_s SCF_PACK_DEF_VARS(uint64_t, tos); SCF_PACK_DEF_VAR(uint64_t, c_lid); + SCF_PACK_DEF_VAR(int64_t, ic_lid); SCF_PACK_DEF_OBJ(ScfEcomponent, IC); SCF_PACK_DEF_VAR(double, v); @@ -199,6 +200,8 @@ SCF_PACK_INFO_VAR(ScfEpin, flags), SCF_PACK_INFO_VARS(ScfEpin, tos, uint64_t), SCF_PACK_INFO_VAR(ScfEpin, c_lid), +SCF_PACK_INFO_VAR(ScfEpin, ic_lid), + SCF_PACK_INFO_VAR(ScfEpin, v), SCF_PACK_INFO_VAR(ScfEpin, a), @@ -277,7 +280,7 @@ struct scf_ecomponent_s SCF_PACK_DEF_VAR(uint64_t, model); SCF_PACK_DEF_OBJS(ScfEpin, pins); - SCF_PACK_DEF_VARS(uint8_t, cpk); + SCF_PACK_DEF_OBJ(ScfEfunction, pf); SCF_PACK_DEF_OBJ(ScfEfunction, f); SCF_PACK_DEF_OBJ(ScfEops, ops); @@ -308,8 +311,6 @@ SCF_PACK_INFO_VAR(ScfEcomponent, type), SCF_PACK_INFO_VAR(ScfEcomponent, model), SCF_PACK_INFO_OBJS(ScfEcomponent, pins, ScfEpin), -SCF_PACK_INFO_VARS(ScfEcomponent, cpk, uint8_t), - SCF_PACK_INFO_VAR(ScfEcomponent, v), SCF_PACK_INFO_VAR(ScfEcomponent, a), @@ -394,6 +395,8 @@ ScfEboard* scf_eboard__alloc(); int scf_eboard__add_function(ScfEboard* b, ScfEfunction* f); int scf_eboard__del_function(ScfEboard* b, ScfEfunction* f); +int scf_pins_same_line(ScfEfunction* f); + #define EDA_INST_ADD_COMPONENT(_ef, _c, _type) \ do { \ _c = scf_ecomponent__alloc(_type); \ diff --git a/ses_core.h b/ses_core.h index 0a3cd52..9aad531 100644 --- a/ses_core.h +++ b/ses_core.h @@ -8,60 +8,19 @@ typedef struct ses_step_s ses_step_t; typedef struct ses_path_s ses_path_t; typedef struct ses_edge_s ses_edge_t; -typedef struct ses_flow_s ses_flow_t; typedef struct ses_node_s ses_node_t; -typedef struct ses_info_s ses_info_t; typedef struct ses_ctx_s ses_ctx_t; -struct ses_flow_s -{ - scf_vector_t* paths; - - ScfEpin* vip; - int vip_i; - int vip_m; - int vip_n; - - int pos_pins; - int neg_pins; - - int pos_diodes; - int pos_NPNs; - - int neg_diodes; - int neg_NPNs; - - double pos_r; - double neg_r; - - double pos_cv; - double neg_cv; - - double v; - double a; -}; - #define SES_PATH_MAIN 0 #define SES_PATH_BRANCH 1 #define SES_PATH_BRIDGE 2 -struct ses_info_s -{ - int i; - int j; - int n_diodes; - int n_NPNs; - int n_PNPs; - int n_capacitors; -}; - struct ses_path_s { int refs; scf_vector_t* pins; - scf_vector_t* infos; scf_vector_t* childs; scf_vector_t* bridges; @@ -130,7 +89,7 @@ struct ses_node_s double a; double a0; - int64_t lid; + ScfEline* el; int index; int vip_i; @@ -153,17 +112,16 @@ struct ses_step_s void* priv; }; -void ses_data_free(scf_vector_t* vec); ses_path_t* ses_path_alloc(); void ses_path_free (ses_path_t* path); void ses_path_print(ses_path_t* path); ses_path_t* ses_path_ref (ses_path_t* src); -int ses_path_add (ses_path_t* path, ses_path_t* child); int ses_path_xchg (ses_path_t* path0, int k0, ses_path_t* path1, int k1); -ses_path_t* ses_path_same_net(ses_path_t* path0, ses_path_t* path1); -int ses_path_is_child(ses_path_t* parent, ses_path_t* child); +int ses_path_add (ScfEfunction* f, ses_path_t* path, ses_path_t* child); + +int ses_path_is_child(ScfEfunction* f, ses_path_t* parent, ses_path_t* child); ses_path_t* ses_path_find_child(ses_path_t* path, int m, int n); ses_path_t* ses_path_find_bridge(ses_path_t* path, int m, int n); void ses_path_sort_childs(ses_path_t* path); @@ -186,18 +144,19 @@ void ses_ctx_free (ses_ctx_t* ctx); void ses_components_print(ScfEfunction* f); void ses_elines_print (ScfEfunction* f); -int ses_layout_board (ScfEboard* b, int d); -int ses_layout_paths (ScfEfunction* f, scf_vector_t* paths); -int ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count); +int ses_pins_same_line (ScfEfunction* f); +int ses_layout_function(ScfEfunction* f, int d); -int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh, int64_t ns, int64_t count); +int ses_lines_same_components(ScfEfunction* f); -int __ses_path_va_diode (ScfEfunction* f, ses_path_t* path); -int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count); +int ses_layout_board(ScfEboard* b, int d); +int ses_layout_paths(ScfEfunction* f, scf_vector_t* paths); -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_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count); + +int ses_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh, int64_t ns, int64_t count); +int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count); int __ses_nodes_path (ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t** pnodes, scf_vector_t** pedges); int __ses_nodes_path_solve(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int* changed, int64_t ns, int64_t count); @@ -211,9 +170,34 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int __ses_path_va2(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count); int __ses_path_va (ScfEfunction* f, ses_path_t* path, int *changed, int64_t ns, int64_t count); -int __ses_path_pos(ScfEfunction* f, ScfEline* el); -int __ses_path_neg(ScfEfunction* f, ScfEline* el); +int __ses_path_pos(ScfEfunction* f, ScfEline* el, ScfEline* LP, ScfEline* LN); +int __ses_path_neg(ScfEfunction* f, ScfEline* el, ScfEline* LP, ScfEline* LN); + + +static inline ScfEcomponent* ses_component(ScfEfunction* f, ScfEpin* p) +{ + if (!p->IC) + return f->components[p->cid]; + + return p->IC->f->components[p->cid]; +} + +static inline ScfEline* ses_line(ScfEfunction* f, ScfEpin* p) +{ + if (!p->IC) + return f->elines[p->lid]; + if (p->lid >= p->IC->n_pins) + return p->IC->f->elines[p->lid]; + + p = p->IC->pins[p->lid]; + return f->elines[p->lid]; +} + +static inline int ses_same_line(ScfEfunction* f, ScfEpin* p0, ScfEpin* p1) +{ + return ses_line(f, p0) == ses_line(f, p1); +} static inline void vertical(int* px, int* py, int dx, int dy, int d) { diff --git a/ses_layout.c b/ses_layout.c index d64d5bb..8af1a24 100644 --- a/ses_layout.c +++ b/ses_layout.c @@ -4,25 +4,6 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr); -int epin_cmp(const void* v0, const void* v1) -{ - const uint64_t* t0 = v0; - const uint64_t* t1 = v1; - - if (t0[0] < t1[0]) - return -1; - - if (t0[0] > t1[0]) - return 1; - - if (t0[1] < t1[1]) - return -1; - - if (t0[1] > t1[1]) - return 1; - return 0; -} - int epin_cmp_color(const void* v0, const void* v1, void* arg) { const uint64_t* t0 = v0; @@ -128,147 +109,6 @@ int ecomponent_cmp_cx(const void* v0, const void* v1) return 0; } -int ses_pins_same_line(ScfEfunction* f) -{ - ScfEcomponent* c; - ScfEline* el; - ScfEline* el2; - ScfEpin* p; - ScfEpin* p2; - - size_t i; - size_t j; - size_t k; - size_t m; - size_t n; - - for (i = 0; i < f->n_components; i++) { - c = f->components[i]; - - for (j = 0; j < c->n_pins; j++) { - p = c->pins[j]; - - qsort(p->tos, p->n_tos / 2, sizeof(uint64_t) * 2, epin_cmp); - - for (k = 0; k < f->n_elines; k++) { - el = f->elines[k]; - - for (m = 0; m + 1 < el->n_pins; m += 2) { - - if (el->pins[m] == p->cid && el->pins[m + 1] == p->id) - goto next; - } - - m = 0; - n = 0; - while (m + 1 < el->n_pins && n + 1 < p->n_tos) { - - if (el->pins[m] < p->tos[n]) - m += 2; - else if (el->pins[m] > p->tos[n]) - n += 2; - - else if (el->pins[m + 1] < p->tos[n + 1]) - m += 2; - else if (el->pins[m + 1] > p->tos[n + 1]) - n += 2; - - else { - if (scf_eline__add_pin(el, p->cid, p->id) < 0) - return -ENOMEM; - - p ->lid = el->id; - p ->c_lid = el->id; - el->flags |= p->flags; - goto next; - } - } - } - - el = scf_eline__alloc(); - if (!el) - return -ENOMEM; - el->id = f->n_elines; - - if (scf_efunction__add_eline(f, el) < 0) { - ScfEline_free(el); - return -ENOMEM; - } - - if (scf_eline__add_pin(el, p->cid, p->id) < 0) - return -ENOMEM; - - p ->lid = el->id; - p ->c_lid = el->id; - el->flags |= p->flags; -next: - for (n = 0; n + 1 < p->n_tos; n += 2) { - - p2 = f->components[p->tos[n]]->pins[p->tos[n + 1]]; - - if (p2->cid > p->cid - || (p2->cid == p->cid && p2->id > p->id)) - break; - - el2 = f->elines[p2->lid]; - - if (el2 == el) - continue; - - if (el2->id < el->id) - SCF_XCHG(el2, el); - - for (m = 0; m + 1 < el2->n_pins; m += 2) { - p2 = f->components[el2->pins[m]]->pins[el2->pins[m + 1]]; - - if (scf_eline__add_pin(el, p2->cid, p2->id) < 0) - return -ENOMEM; - - p2->lid = el->id; - p2->c_lid = el->id; - el->flags |= p2->flags; - } - - qsort(el->pins, el->n_pins / 2, sizeof(uint64_t) * 2, epin_cmp); - - el2->n_pins = 0; - } - p = NULL; - } - } - - - for (i = 0; i < f->n_elines; ) { - el = f->elines[i]; - - if (0 == el->n_pins) { - scf_efunction__del_eline(f, el); - ScfEline_free(el); - continue; - } - - el->c_pins = el->n_pins; - el->id = i; - - scf_logd("line i: %ld, %p, el->flags: %#lx\n", i, el, el->flags); - - for (j = 0; j + 1 < el->n_pins; j += 2) { - - c = f->components[el->pins[j]]; - p = c->pins [el->pins[j + 1]]; - - p->lid = i; - p->c_lid = i; - - scf_logd("pin j: %ld, c%ldp%ld\n", j, el->pins[j], el->pins[j + 1]); - } - - i++; - } - - return 0; -} - static inline int __ses_find_eline_index(ScfEfunction* f, uint64_t lid) { ScfEline* el; @@ -566,15 +406,13 @@ static int __ses_layout_lines4(ScfEfunction* f) ses_path_t* base; ses_path_t* path; - ScfEcomponent* B; ScfEline* el; - ScfEpin* Bp; ScfEpin* p; - intptr_t i; - intptr_t j; - intptr_t n; - intptr_t __n; + long i; + long j; + long n; + long __n; paths = scf_vector_alloc(); if (!paths) @@ -588,14 +426,12 @@ static int __ses_layout_lines4(ScfEfunction* f) ses_paths_print(paths); - B = f->components[0]; - Bp = B->pins[SCF_EDA_Battery_POS]; - for (i = 0; i < paths->size; i++) { base = paths->data[i]; p = base->pins->data[0]; - if (p->lid == Bp->lid) + + if (SCF_EDA_PIN_POS & f->elines[p->lid]->flags) break; } @@ -1818,7 +1654,7 @@ int ses_layout_board(ScfEboard* b, int d) printf("f: %s\n", f->name); - ses_pins_same_line(f); + scf_pins_same_line(f); ses_lines_same_components(f); diff --git a/ses_node_analysis.c b/ses_node_analysis.c index 3893ccf..a3a756c 100644 --- a/ses_node_analysis.c +++ b/ses_node_analysis.c @@ -105,7 +105,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s for (i = vip_n - 1; i >= vip_m; i -= 2) { p = path->pins->data[i]; - c = f->components[p->cid]; + c = ses_component(f, p); switch (c->type) { @@ -221,7 +221,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s node->vip_i = i; node->path = path; - node->lid = p->lid; + node->el = ses_line(f, p); edge = ses_edge_alloc(path, i, j); if (!edge) @@ -457,12 +457,12 @@ static void __ses_nodes_set_Ab(ScfEfunction* f, scf_vector_t* nodes, scf_vector_ else A[(n + edge->index) * N + n + edge->index] = -r - uh * 1000.0 / ns; - if (edge->node0 && edge->node0->lid != Bn->lid) + if (edge->node0 && edge->node0->el != ses_line(f, Bn)) A[(n + edge->index) * N + edge->node0->index] = -1; else b[n + edge->index] += Bn->v; - if (edge->node1 && edge->node1->lid != Bp->lid) + if (edge->node1 && edge->node1->el != ses_line(f, Bp)) A[(n + edge->index) * N + edge->node1->index] = 1; else b[n + edge->index] -= Bp->v; @@ -490,18 +490,18 @@ static int __ses_edges_update_Ab(ScfEfunction* f, scf_vector_t* edges, double* A p0 = edge->path->pins->data[edge->vip_m]; p1 = edge->path->pins->data[edge->vip_n]; - c = f->components[p0->cid]; + c = ses_component(f, p0); if (edge->bflag) { double Vb; double Ve; - if (edge->node1 && edge->node1->lid != Bp->lid) + if (edge->node1 && edge->node1->el != ses_line(f, Bp)) Vb = X[edge->node1->index]; else Vb = Bp->v; - if (edge->node0 && edge->node0->lid != Bn->lid) + if (edge->node0 && edge->node0->el != ses_line(f, Bn)) Ve = X[edge->node0->index]; else Ve = Bn->v; @@ -513,8 +513,12 @@ static int __ses_edges_update_Ab(ScfEfunction* f, scf_vector_t* edges, double* A if (-1e8 < Rb && Rb < 1e8) { if (dV < SCF_EDA_V_NPN_ON * 0.99 || dV > SCF_EDA_V_NPN_ON * 1.01) { - scf_logi("edge: [%d] c%ldp%ld-c%ldp%ld, Vb: %lg, Ve: %lg, dV: %lg, Ib: %lg, Rb: %lg\n", - edge->index, p0->cid, p0->id, p1->cid, p1->id, Vb, Ve, dV, Ib, Rb); + if (p0->IC) + scf_logi("edge: [%d] IC%ld_c%ldp%ld-c%ldp%ld, Vb: %lg, Ve: %lg, dV: %lg, Ib: %lg, Rb: %lg\n", + edge->index, p0->IC->id, p0->cid, p0->id, p1->cid, p1->id, Vb, Ve, dV, Ib, Rb); + else + scf_logi("edge: [%d] c%ldp%ld-c%ldp%ld, Vb: %lg, Ve: %lg, dV: %lg, Ib: %lg, Rb: %lg\n", + edge->index, p0->cid, p0->id, p1->cid, p1->id, Vb, Ve, dV, Ib, Rb); A[(n + edge->index) * N + n + edge->index] = -Rb; k++; @@ -524,7 +528,10 @@ static int __ses_edges_update_Ab(ScfEfunction* f, scf_vector_t* edges, double* A c->lock = 1; (*n_offs)++; - scf_logi("\033[34mc%ld, status: %d, dV: %lg, Ib: %lg, Rb: %lg, edge->index: %d\033[0m\n", c->id, c->status, dV, Ib, Rb, edge->index); + if (p0->IC) + scf_logi("\033[34mIC%ld_c%ld, status: %d, dV: %lg, Ib: %lg, Rb: %lg, edge->index: %d\033[0m\n", p0->IC->id, c->id, c->status, dV, Ib, Rb, edge->index); + else + scf_logi("\033[34mc%ld, status: %d, dV: %lg, Ib: %lg, Rb: %lg, edge->index: %d\033[0m\n", c->id, c->status, dV, Ib, Rb, edge->index); } } else if (edge->edge_b) { @@ -536,12 +543,12 @@ static int __ses_edges_update_Ab(ScfEfunction* f, scf_vector_t* edges, double* A double Vb; double Ve; - if (edge->edge_b->node1 && edge->edge_b->node1->lid != Bp->lid) + if (edge->edge_b->node1 && edge->edge_b->node1->el != ses_line(f, Bp)) Vb = X[edge->edge_b->node1->index]; else Vb = Bp->v; - if (edge->edge_b->node0 && edge->edge_b->node0->lid != Bn->lid) + if (edge->edge_b->node0 && edge->edge_b->node0->el != ses_line(f, Bn)) Ve = X[edge->edge_b->node0->index]; else Ve = Bn->v; @@ -555,8 +562,12 @@ static int __ses_edges_update_Ab(ScfEfunction* f, scf_vector_t* edges, double* A if (!edge->amplify_flag) { edge->amplify_flag = 1; - scf_logi("edge: [%d] c%ldp%ld-c%ldp%ld [b%d], Ic: %lg, Ib: %lg, dI: %lg, dVbe: %lg, Rb: %lg\n", - edge->index, p0->cid, p0->id, p1->cid, p1->id, edge->edge_b->index, Ic, Ib, dI, dV, Rb); + if (p0->IC) + scf_logi("edge: [%d] IC%ld_c%ldp%ld-c%ldp%ld [b%d], Ic: %lg, Ib: %lg, dI: %lg, dVbe: %lg, Rb: %lg\n", + edge->index, p0->IC->id, p0->cid, p0->id, p1->cid, p1->id, edge->edge_b->index, Ic, Ib, dI, dV, Rb); + else + scf_logi("edge: [%d] c%ldp%ld-c%ldp%ld [b%d], Ic: %lg, Ib: %lg, dI: %lg, dVbe: %lg, Rb: %lg\n", + edge->index, p0->cid, p0->id, p1->cid, p1->id, edge->edge_b->index, Ic, Ib, dI, dV, Rb); for (i = 0; i < N; i++) A[(n + edge->index) * N + i] = 0; @@ -597,13 +608,13 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int m = edges->size; int n = nodes->size; - if (pm->lid == Bp->lid) + if (ses_same_line(f, pm, Bp)) n = nodes->size - 1; int N = n + m; - pm->v = f->elines[pm->lid]->v; - pn->v = f->elines[pn->lid]->v; + pm->v = ses_line(f, pm)->v; + pn->v = ses_line(f, pn)->v; scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, n: %d, m: %d, N: %d\n", pm->cid, pm->id, pm->v, pn->cid, pn->id, pn->v, n, m, N); @@ -632,7 +643,7 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int n_offs = 0; -#define MAX_TRYS 100 +#define MAX_TRYS 200 int try = 0; do { n_offs = 0; @@ -657,7 +668,7 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, for (i = 0; i < n; i++) { node = nodes->data[i]; - el = f->elines[node->lid]; + el = node->el; el->v = X[i]; } @@ -673,10 +684,10 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, p0 = edge->path->pins->data[edge->vip_m]; p1 = edge->path->pins->data[edge->vip_n]; - c = f->components[p0->cid]; + c = ses_component(f, p0); - p0->v = f->elines[p0->lid]->v; - p1->v = f->elines[p1->lid]->v; + p0->v = ses_line(f, p0)->v; + p1->v = ses_line(f, p1)->v; scf_logd("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, a: %lg, edge->index: %d\n", p0->cid, p0->id, p0->v, p1->cid, p1->id, p1->v, edge->a, edge->index); diff --git a/ses_path.c b/ses_path.c index 0a1fdbd..957f315 100644 --- a/ses_path.c +++ b/ses_path.c @@ -12,13 +12,6 @@ ses_path_t* ses_path_alloc() return NULL; } - path->infos = scf_vector_alloc(); - if (!path->infos) { - scf_vector_free(path->pins); - free(path); - return NULL; - } - path->refs = 1; return path; } @@ -34,11 +27,6 @@ void ses_path_free(ses_path_t* path) if (path->pins) scf_vector_free(path->pins); - if (path->infos) { - scf_vector_clear(path->infos, ( void (*)(void*) )free); - scf_vector_free (path->infos); - } - if (path->childs) { scf_vector_clear(path->childs, ( void (*)(void*) )ses_path_free); scf_vector_free (path->childs); @@ -58,19 +46,6 @@ void ses_path_free(ses_path_t* path) } } -ses_path_t* ses_path_same_net(ses_path_t* path0, ses_path_t* path1) -{ - while (path0->parent) - path0 = path0->parent; - - while (path1->parent) - path1 = path1->parent; - - if (path0 == path1) - return path0; - return NULL; -} - void ses_path_print(ses_path_t* path) { if (!path) @@ -83,12 +58,15 @@ void ses_path_print(ses_path_t* path) int j; if (!path->parent) - printf("\033[31mpath : %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, \033[0m", - path->index, path->n_diodes, path->n_NPNs, path->n_PNPs, path->n_capacitors); + printf("\033[31mpath : %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, n_transistors: %d, \033[0m", + path->index, path->n_diodes, path->n_NPNs, path->n_PNPs, path->n_capacitors, path->n_transistors); for (i = 0; i < path->pins->size; i++) { p = path->pins->data[i]; + if (p->IC) + printf("IC%ld_", p->IC->id); + printf("c%ldp%ld ", p->cid, p->id); } printf("\n"); @@ -98,8 +76,8 @@ void ses_path_print(ses_path_t* path) child = path->connections->data[i]; if (child->parent == path) { - printf("\033[34mconnection: %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, parent: %d, \033[0m", - child->index, child->n_diodes, child->n_NPNs, child->n_PNPs, child->n_capacitors, path->index); + printf("\033[34mconnection: %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, n_transistors: %d, parent: %d, \033[0m", + child->index, child->n_diodes, child->n_NPNs, child->n_PNPs, child->n_capacitors, child->n_transistors, path->index); ses_path_print(child); } else @@ -111,8 +89,8 @@ void ses_path_print(ses_path_t* path) for (i = 0; i < path->childs->size; i++) { child = path->childs->data[i]; - printf("\033[32mchild : %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, parent: %d, \033[0m", - child->index, child->n_diodes, child->n_NPNs, child->n_PNPs, child->n_capacitors, path->index); + printf("\033[32mchild : %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, n_transistors: %d, parent: %d, \033[0m", + child->index, child->n_diodes, child->n_NPNs, child->n_PNPs, child->n_capacitors, child->n_transistors, path->index); ses_path_print(child); } @@ -122,8 +100,8 @@ void ses_path_print(ses_path_t* path) for (i = 0; i < path->bridges->size; i++) { child = path->bridges->data[i]; - printf("\033[33mbridge: %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, parent: %d, \033[0m", - child->index, child->n_diodes, child->n_NPNs, child->n_PNPs, child->n_capacitors, path->index); + printf("\033[33mbridge: %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, n_transistors: %d, parent: %d, \033[0m", + child->index, child->n_diodes, child->n_NPNs, child->n_PNPs, child->n_capacitors, child->n_transistors, path->index); ses_path_print(child); } @@ -143,7 +121,7 @@ void ses_paths_print(scf_vector_t* paths) } } -int ses_path_is_child(ses_path_t* parent, ses_path_t* child) +int ses_path_is_child(ScfEfunction* f, ses_path_t* parent, ses_path_t* child) { ScfEpin* cp0 = child->pins->data[0]; ScfEpin* cp1 = child->pins->data[child->pins->size - 1]; @@ -155,12 +133,12 @@ int ses_path_is_child(ses_path_t* parent, ses_path_t* child) for (i = 0; i < parent->pins->size; i++) { p = parent->pins->data[i]; - if (p->lid == cp0->lid) { + if (ses_same_line(f, p, cp0)) { j = i; continue; } - if (p->lid == cp1->lid) { + if (ses_same_line(f, p, cp1)) { if (j >= 0) return 1; return 0; @@ -333,7 +311,7 @@ int ses_path_xchg(ses_path_t* path0, int k0, ses_path_t* path1, int k1) return 0; } -int ses_path_add(ses_path_t* parent, ses_path_t* child) +int ses_path_add(ScfEfunction* f, ses_path_t* parent, ses_path_t* child) { if (!parent || !child) return -EINVAL; @@ -359,10 +337,10 @@ int ses_path_add(ses_path_t* parent, ses_path_t* child) for (j = 0; j < parent->pins->size; j++) { p0 = parent->pins->data[j]; - if (p0->lid == cp0->lid) + if (ses_same_line(f, p0, cp0)) child->parent_p0 = (j + 1) & ~0x1; - else if (p0->lid == cp1->lid) + else if (ses_same_line(f, p0, cp1)) child->parent_p1 = j; if (child->parent_p0 >= 0 && child->parent_p1 >= 0) diff --git a/ses_step_dc_diode.c b/ses_step_dc_diode.c index ef58df8..b4eaa99 100644 --- a/ses_step_dc_diode.c +++ b/ses_step_dc_diode.c @@ -1,58 +1,87 @@ #include"ses_core.h" -static int _dc_diode_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) +static void __dc_dfs_init(ScfEfunction* f, ScfEcomponent* IC) { - ScfEcomponent* c; - ScfEcomponent* B; - ScfEline* lb; - ScfEline* le; - ScfEpin* pb; - ScfEpin* pe; - ScfEpin* Bp; - ScfEpin* Bn; - - size_t i; - size_t j; - size_t k; - - B = f->components[0]; - Bp = B->pins[SCF_EDA_Battery_POS]; - Bn = B->pins[SCF_EDA_Battery_NEG]; + ScfEcomponent* c; + ScfEline* el; + ScfEline* parent; + ScfEpin* p; + long i; for (i = 0; i < f->n_elines; i++) { - lb = f->elines[i]; + el = f->elines[i]; + + if (!IC) { + if (el->flags & (SCF_EDA_PIN_IN | SCF_EDA_PIN_POS | SCF_EDA_PIN_NEG)) + continue; + + } else if (i < IC->n_pins) { + p = IC->pins[i]; + parent = IC->pf->elines[p->lid]; - if (lb->flags & (SCF_EDA_PIN_IN | SCF_EDA_PIN_POS | SCF_EDA_PIN_NEG)) + el->vconst = parent->vconst; continue; - lb->vconst = 0; + } + + el->vconst = 0; + } + + for (i = 0; i < f->n_components; i++) { + c = f->components[i]; + + if (c->f) + __dc_dfs_init(c->f, c); } +} + +static int __dc_diode_status(ScfEfunction* root, ScfEfunction* f, ScfEpin* Bp, ScfEpin* Bn, ScfEline* LP, ScfEline* LN) +{ + ScfEcomponent* c; + ScfEpin* pb; + ScfEpin* pe; + ScfEline* lb; + ScfEline* le; + long i; for (i = 0; i < f->n_components; i++) { c = f->components[i]; + if (c->f) { + int ret = __dc_diode_status(root, c->f, Bp, Bn, LP, LN); + if (ret < 0) + return ret; + + continue; + } + if (SCF_EDA_Diode != c->type) continue; pb = c->pins[SCF_EDA_Diode_POS]; pe = c->pins[SCF_EDA_Diode_NEG]; - lb = f->elines[pb->lid]; - le = f->elines[pe->lid]; + lb = ses_line(root, pb); + le = ses_line(root, pe); - if (pb->lid == Bp->lid && pe->lid == Bn->lid) { - scf_loge("Diode c%ld, short connected\n", c->id); + if (lb == LP && le == LN) { + if (pb->IC) + scf_loge("Diode IC%ld_c%ld, short connected\n", pb->IC->id, c->id); + else + scf_loge("Diode c%ld, short connected\n", c->id); return -EINVAL; } - if (__ses_path_neg(f, lb) && !__ses_path_pos(f, lb)) { + if (__ses_path_neg(root, lb, LP, LN) && !__ses_path_pos(root, lb, LP, LN)) { c->status = SCF_EDA_Status_OFF; - scf_loge("\033[34mDiode c%ld, status: %d\033[0m\n", c->id, c->status); + if (pb->IC) + scf_loge("\033[34mDiode IC%ld_c%ld, status: %d\033[0m\n", pb->IC->id, c->id, c->status); + else + scf_loge("\033[34mDiode c%ld, status: %d\033[0m\n", c->id, c->status); continue; } if (lb->v < SCF_EDA_V_MIN) { - if (le->v < SCF_EDA_V_MIN) continue; @@ -103,12 +132,28 @@ static int _dc_diode_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx c->status = SCF_EDA_Status_OFF; } - scf_loge("\033[34mDiode c%ld, status: %d, pb: %lg, pe: %lg, diff: %lg\033[0m\n", c->id, c->status, pb->v, pe->v, pb->v - pe->v); + if (pb->IC) + scf_loge("\033[34mDiode IC%ld_c%ld, status: %d, pb: %lg, pe: %lg, diff: %lg\033[0m\n", pb->IC->id, c->id, c->status, pb->v, pe->v, pb->v - pe->v); + else + scf_loge("\033[34mDiode c%ld, status: %d, pb: %lg, pe: %lg, diff: %lg\033[0m\n", c->id, c->status, pb->v, pe->v, pb->v - pe->v); } return 0; } +static int _dc_diode_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* LP = ses_line(f, Bp); + ScfEline* LN = ses_line(f, Bn); + + __dc_dfs_init(f, NULL); + + return __dc_diode_status(f, f, Bp, Bn, LP, LN); +} + ses_step_t ses_step_dc_diode = { .name = "dc_diode", diff --git a/ses_step_dc_npn.c b/ses_step_dc_npn.c index 1dcf564..830c957 100644 --- a/ses_step_dc_npn.c +++ b/ses_step_dc_npn.c @@ -1,28 +1,26 @@ #include"ses_core.h" -static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) +static int __dc_npn_status(ScfEfunction* root, ScfEfunction* f, ScfEpin* Bp, ScfEpin* Bn, ScfEline* LP, ScfEline* LN) { ScfEcomponent* c; - ScfEcomponent* B; - ScfEline* lb; - ScfEline* le; ScfEpin* pb; ScfEpin* pc; ScfEpin* pe; - ScfEpin* Bp; - ScfEpin* Bn; - - size_t i; - size_t j; - size_t k; - - B = f->components[0]; - Bp = B->pins[SCF_EDA_Battery_POS]; - Bn = B->pins[SCF_EDA_Battery_NEG]; + ScfEline* lb; + ScfEline* le; + long i; for (i = 0; i < f->n_components; i++) { c = f->components[i]; + if (c->f) { + int ret = __dc_npn_status(root, c->f, Bp, Bn, LP, LN); + if (ret < 0) + return ret; + + continue; + } + if (SCF_EDA_NPN != c->type) continue; @@ -30,24 +28,34 @@ static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t pc = c->pins[SCF_EDA_NPN_C]; pe = c->pins[SCF_EDA_NPN_E]; - lb = f->elines[pb->lid]; - le = f->elines[pe->lid]; + lb = ses_line(root, pb); + le = ses_line(root, pe); - if (pb->lid == Bp->lid && pe->lid == Bn->lid) { - scf_loge("NPN c%ld, short connected\n", c->id); + if (lb == LP && le == LN) { + if (pb->IC) + scf_loge("NPN IC%ld_c%ld, short connected\n", pb->IC->id, c->id); + else + scf_loge("NPN c%ld, short connected\n", c->id); return -EINVAL; } - if (__ses_path_neg(f, lb) && !__ses_path_pos(f, lb)) { + if (__ses_path_neg(root, lb, LP, LN) && !__ses_path_pos(root, lb, LP, LN)) { c->status = SCF_EDA_Status_OFF; - scf_loge("NPN c%ld, status: %d\n", c->id, c->status); + if (pb->IC) + scf_loge("NPN IC%ld_c%ld, status: %d\n", pb->IC->id, c->id, c->status); + else + scf_loge("NPN c%ld, status: %d\n", c->id, c->status); continue; } if (c->lock) { - scf_loge("\033[34mc%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", - c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF); + if (pb->IC) + scf_loge("\033[34mIC%ld_c%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", + pb->IC->id, c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF); + else + scf_loge("\033[34mc%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", + c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF); continue; } @@ -103,13 +111,28 @@ static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t c->status = SCF_EDA_Status_OFF; } - scf_loge("\033[34mc%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", - c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF); + if (pb->IC) + scf_loge("\033[34mIC%ld_c%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", + pb->IC->id, c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF); + else + scf_loge("\033[34mc%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", + c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF); } return 0; } +static int _dc_npn_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* LP = ses_line(f, Bp); + ScfEline* LN = ses_line(f, Bn); + + return __dc_npn_status(f, f, Bp, Bn, LP, LN); +} + ses_step_t ses_step_dc_npn = { .name = "dc_npn", diff --git a/ses_step_dc_pnp.c b/ses_step_dc_pnp.c index 5c1a75d..b93920b 100644 --- a/ses_step_dc_pnp.c +++ b/ses_step_dc_pnp.c @@ -1,28 +1,26 @@ #include"ses_core.h" -static int _dc_pnp_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) +static int __dc_pnp_status(ScfEfunction* root, ScfEfunction* f, ScfEpin* Bp, ScfEpin* Bn, ScfEline* LP, ScfEline* LN) { - ScfEcomponent* c; - ScfEcomponent* B; - ScfEline* lb; - ScfEline* le; - ScfEpin* pb; - ScfEpin* pc; - ScfEpin* pe; - ScfEpin* Bp; - ScfEpin* Bn; - - size_t i; - size_t j; - size_t k; - - B = f->components[0]; - Bp = B->pins[SCF_EDA_Battery_POS]; - Bn = B->pins[SCF_EDA_Battery_NEG]; - + ScfEcomponent* c; + ScfEpin* pb; + ScfEpin* pc; + ScfEpin* pe; + ScfEline* lb; + ScfEline* le; + + long i; for (i = 0; i < f->n_components; i++) { c = f->components[i]; + if (c->f) { + int ret = __dc_pnp_status(root, c->f, Bp, Bn, LP, LN); + if (ret < 0) + return ret; + + continue; + } + if (SCF_EDA_PNP != c->type) continue; @@ -30,26 +28,28 @@ static int _dc_pnp_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t pc = c->pins[SCF_EDA_PNP_C]; pe = c->pins[SCF_EDA_PNP_E]; - lb = f->elines[pb->lid]; - le = f->elines[pe->lid]; + lb = ses_line(root, pb); + le = ses_line(root, pe); - if (pe->lid == Bp->lid && pb->lid == Bn->lid) { - scf_loge("PNP c%ld, short connected\n", c->id); + if (le == LP && lb == LN) { + if (pb->IC) + scf_loge("PNP IC%ld_c%ld, short connected\n", pb->IC->id, c->id); + else + scf_loge("PNP c%ld, short connected\n", c->id); return -EINVAL; } - if (__ses_path_pos(f, lb) && !__ses_path_neg(f, lb)) { + if (__ses_path_pos(root, lb, LP, LN) && !__ses_path_neg(root, lb, LP, LN)) { c->status = SCF_EDA_Status_OFF; - scf_loge("PNP c%ld, status: %d\n", c->id, c->status); + if (pb->IC) + scf_loge("PNP IC%ld_c%ld, status: %d\n", pb->IC->id, c->id, c->status); + else + scf_loge("PNP c%ld, status: %d\n", c->id, c->status); continue; } - scf_logd("c%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n", - c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_PNP_OFF); - if (lb->v < SCF_EDA_V_MIN) { - if (le->v < SCF_EDA_V_MIN) continue; @@ -104,13 +104,28 @@ static int _dc_pnp_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t c->status = SCF_EDA_Status_OFF; } - scf_loge("\033[34mc%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", - c->id, c->status, c->lock, pb->v, pe->v, pe->v - pb->v, SCF_EDA_V_PNP_OFF); + if (pb->IC) + scf_loge("\033[34mIC%ld_c%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", + pb->IC->id, c->id, c->status, c->lock, pb->v, pe->v, pe->v - pb->v, SCF_EDA_V_PNP_OFF); + else + scf_loge("\033[34mc%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", + c->id, c->status, c->lock, pb->v, pe->v, pe->v - pb->v, SCF_EDA_V_PNP_OFF); } return 0; } +static int _dc_pnp_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* LP = ses_line(f, Bp); + ScfEline* LN = ses_line(f, Bn); + + return __dc_pnp_status(f, f, Bp, Bn, LP, LN); +} + ses_step_t ses_step_dc_pnp = { .name = "dc_pnp", diff --git a/ses_step_jr.c b/ses_step_jr.c index d297356..3619044 100644 --- a/ses_step_jr.c +++ b/ses_step_jr.c @@ -1,14 +1,5 @@ #include"ses_core.h" -void __ses_npn_epr(ScfEfunction* f, ScfEpin* pe, double* r) -{ - ScfEcomponent* c = f->components[pe->cid]; - ScfEpin* pb = c->pins[SCF_EDA_NPN_B]; - ScfEpin* pc = c->pins[SCF_EDA_NPN_C]; - - ses_merge_r(r, NULL, pb->pr, 0, pc->pr, 0); -} - void __ses_path_sr(ScfEfunction* f, ses_path_t* path, int i, int j, double* r) { ScfEpin* p0 = path->pins->data[i]; @@ -99,25 +90,24 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) } } - r = 0; + r = 0; for (i = 0; i < path->pins->size; i++) { p = path->pins->data[i]; - c = f->components[p->cid]; + c = ses_component(f, p); r2 = r; r += p->r + p->dr; - if (i & 0x1) { + if (i & 0x1) r += c->r + c->dr; - } if (SCF_EDA_NPN == c->type && !(i & 0x1)) { - 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_logd("path: %d, i: %d, c%ldp%ld, sr: %lg\n", path->index, i, p->cid, p->id, p->sr); @@ -135,14 +125,11 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) p0 = NULL; p1 = NULL; - int k; - for (j = 0; j < path->pins->size; j++) { p = path->pins->data[j]; - if (p->lid == cp0->lid) { + if (ses_same_line(f, p, cp0)) { p0 = p; - k = j; break; } } @@ -153,7 +140,7 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) for ( ; j < path->pins->size; j++) { p = path->pins->data[j]; - if (p->lid == cp1->lid) { + if (ses_same_line(f, p, cp1)) { p1 = p; break; } @@ -196,8 +183,8 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) for (j = 0; j < path->pins->size; j++) { p = path->pins->data[j]; - if (p->lid == cp1->lid) { - child->parent_pr = p->pr; + if (ses_same_line(f, p, cp1)) { + child->parent_pr = p->pr; break; } } @@ -211,38 +198,3 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) scf_logi("path: %d, pr: %lg, sr: %lg\n\n", path->index, path->pr, path->sr); return 0; } - -static int _jr_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) -{ - ses_path_t* path; - ScfEcomponent* B; - ScfEpin* p0; - ScfEpin* p1; - ScfEpin* Bp; - ScfEpin* Bn; - - size_t i; - size_t j; - size_t k; - - for (i = 0; i < ctx->paths->size; i++) { - path = ctx->paths->data[i]; - - scf_logi("i: %ld, path->type: %d\n", i, path->type); - - int ret = __ses_path_jr(f, path); - if (ret < 0) - return ret; - - printf("\n"); - } - - return 0; -} - -ses_step_t ses_step_jr = -{ - .name = "jr", - - .handler = _jr_handler, -}; diff --git a/ses_step_open.c b/ses_step_open.c index a0a9ae4..1cc28e7 100644 --- a/ses_step_open.c +++ b/ses_step_open.c @@ -1,19 +1,38 @@ #include"ses_core.h" -static int __dfs_path_pos(ScfEfunction* f, ScfEline* el) +static int __dfs_path_pos(ScfEfunction* f, ScfEline* el, ScfEline* LP, ScfEline* LN); +static int __dfs_path_neg(ScfEfunction* f, ScfEline* el, ScfEline* LP, ScfEline* LN); + +static int __dfs_path_pos2(ScfEfunction* f, ScfEpin* p2, ScfEline* LP, ScfEline* LN) +{ + ScfEcomponent* c; + ScfEpin* p; + + if (__dfs_path_pos(f, f->elines[p2->lid], LP, LN)) + return 1; + + if (p2->IC && p2->lid < p2->IC->n_pins) { + c = p2->IC; + p = c->pins[p2->lid]; + p->vflag = 1; + + if (__dfs_path_pos(c->pf, c->pf->elines[p->lid], LP, LN)) + return 1; + } + return 0; +} + +static int __dfs_path_pos(ScfEfunction* f, ScfEline* el, ScfEline* LP, ScfEline* LN) { - ScfEcomponent* c; - ScfEcomponent* c2; - ScfEline* el2; - ScfEpin* p; - ScfEpin* p2; + ScfEcomponent* c; + ScfEpin* p; + ScfEpin* p2; - size_t i; - size_t j; + long i; - if (SCF_EDA_PIN_POS & el->flags) + if (LP == el) return 1; - if (SCF_EDA_PIN_NEG & el->flags) + if (LN == el) return 0; for (i = 0; i + 1 < el->n_pins; i += 2) { @@ -25,6 +44,14 @@ static int __dfs_path_pos(ScfEfunction* f, ScfEline* el) continue; p->vflag = 1; + if (c->f) { + assert(p->id < c->f->n_elines); + + if (__dfs_path_pos(c->f, c->f->elines[p->id], LP, LN)) + return 1; + continue; + } + if (SCF_EDA_Diode == c->type) { if (SCF_EDA_Diode_POS == p->id || SCF_EDA_Status_OFF == c->status) @@ -40,15 +67,14 @@ static int __dfs_path_pos(ScfEfunction* f, ScfEline* el) p2 = c->pins[SCF_EDA_NPN_B]; p2->vflag = 1; - if (__dfs_path_pos(f, f->elines[p2->lid])) + if (__dfs_path_pos2(f, p2, LP, LN)) return 1; p2 = c->pins[SCF_EDA_NPN_C]; p2->vflag = 1; - if (__dfs_path_pos(f, f->elines[p2->lid])) + if (__dfs_path_pos2(f, p2, LP, LN)) return 1; - continue; } else p2 = c->pins[!p->id]; @@ -57,25 +83,43 @@ static int __dfs_path_pos(ScfEfunction* f, ScfEline* el) continue; p2->vflag = 1; - if (__dfs_path_pos(f, f->elines[p2->lid])) + if (__dfs_path_pos2(f, p2, LP, LN)) return 1; } return 0; } -static int __dfs_path_neg(ScfEfunction* f, ScfEline* el) +static int __dfs_path_neg2(ScfEfunction* f, ScfEpin* p2, ScfEline* LP, ScfEline* LN) +{ + ScfEcomponent* c; + ScfEpin* p; + + if (__dfs_path_neg(f, f->elines[p2->lid], LP, LN)) + return 1; + + if (p2->IC && p2->lid < p2->IC->n_pins) { + c = p2->IC; + p = c->pins[p2->lid]; + p->vflag = 1; + + if (__dfs_path_neg(c->pf, c->pf->elines[p->lid], LP, LN)) + return 1; + } + return 0; +} + +static int __dfs_path_neg(ScfEfunction* f, ScfEline* el, ScfEline* LP, ScfEline* LN) { ScfEcomponent* c; ScfEpin* p; ScfEpin* p2; - size_t i; - size_t j; + long i; - if (SCF_EDA_PIN_NEG & el->flags) + if (LN == el) return 1; - if (SCF_EDA_PIN_POS & el->flags) + if (LP == el) return 0; for (i = 0; i + 1 < el->n_pins; i += 2) { @@ -87,6 +131,14 @@ static int __dfs_path_neg(ScfEfunction* f, ScfEline* el) continue; p->vflag = 1; + if (c->f) { + assert(p->id < c->f->n_elines); + + if (__dfs_path_pos(c->f, c->f->elines[p->id], LP, LN)) + return 1; + continue; + } + if (SCF_EDA_Diode == c->type) { if (SCF_EDA_Diode_NEG == p->id || SCF_EDA_Status_OFF == c->status) @@ -105,20 +157,20 @@ static int __dfs_path_neg(ScfEfunction* f, ScfEline* el) continue; p2->vflag = 1; - if (__dfs_path_neg(f, f->elines[p2->lid])) + if (__dfs_path_neg2(f, p2, LP, LN)) return 1; } return 0; } -int __ses_path_pos(ScfEfunction* f, ScfEline* el) +static void __dfs_path_init(ScfEfunction* f) { ScfEcomponent* c; ScfEpin* p; - size_t i; - size_t j; + long i; + long j; for (i = 0; i < f->n_components; i++) { c = f->components[i]; @@ -127,29 +179,24 @@ int __ses_path_pos(ScfEfunction* f, ScfEline* el) p = c->pins[j]; p->vflag = 0; } - } - return __dfs_path_pos(f, el); + if (c->f) + __dfs_path_init(c->f); + } } -int __ses_path_neg(ScfEfunction* f, ScfEline* el) +int __ses_path_pos(ScfEfunction* f, ScfEline* el, ScfEline* LP, ScfEline* LN) { - ScfEcomponent* c; - ScfEpin* p; - - size_t i; - size_t j; + __dfs_path_init(f); - for (i = 0; i < f->n_components; i++) { - c = f->components[i]; + return __dfs_path_pos(f, el, LP, LN); +} - for (j = 0; j < c->n_pins; j++) { - p = c->pins[j]; - p->vflag = 0; - } - } +int __ses_path_neg(ScfEfunction* f, ScfEline* el, ScfEline* LP, ScfEline* LN) +{ + __dfs_path_init(f); - return __dfs_path_neg(f, el); + return __dfs_path_neg(f, el, LP, LN); } static int _open_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) @@ -157,9 +204,11 @@ static int _open_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ScfEcomponent* B = f->components[0]; ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; + ScfEline* LP = ses_line(f, Bp); + ScfEline* LN = ses_line(f, Bn); ScfEline* el; - int i; + long i; for (i = 0; i < f->n_elines; i++) { el = f->elines[i]; @@ -167,14 +216,14 @@ static int _open_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* if (el->flags & (SCF_EDA_PIN_IN | SCF_EDA_PIN_POS | SCF_EDA_PIN_NEG)) continue; - if (__ses_path_pos(f, el)) { + if (__ses_path_pos(f, el, LP, LN)) { - if (!__ses_path_neg(f, el)) { + if (!__ses_path_neg(f, el, LP, LN)) { el->v = Bp->v; scf_logw("e%ld->v: %lg\n", el->id, el->v); } - } else if (__ses_path_neg(f, el)) { + } else if (__ses_path_neg(f, el, LP, LN)) { el->v = Bn->v; scf_logw("e%ld->v: %lg\n", el->id, el->v); diff --git a/ses_step_topo.c b/ses_step_topo.c index fbc0f7e..f986517 100644 --- a/ses_step_topo.c +++ b/ses_step_topo.c @@ -24,20 +24,179 @@ static int __ses_dfs_add_ppath(scf_vector_t* paths, ses_path_t** ppath) return 0; } +static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __paths, ses_path_t** ppath, int flags); + +static int __ses_dfs_line(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* np, scf_vector_t* __paths, ses_path_t** ppath, int flags) +{ + ScfEcomponent* c; + ScfEline* el = f->elines[np->lid]; + ScfEpin* p; + + int ret = 0; + long j; + + for (j = 0; j + 1 < el->n_pins; j += 2) { + + c = f->components[el->pins[j]]; + p = c->pins [el->pins[j + 1]]; + + if (p->pflag) { + if (p != np) { + scf_logd("branch: c%ld_p%ld, l%ld\n\n", c->id, p->id, el->id); + + ret = __ses_dfs_add_ppath(__paths, ppath); + if (ret < 0) + return ret; + + *ppath = NULL; + } + continue; + } + + if (p->vflag) + continue; + + if ((SCF_EDA_Capacitor == rc->type || SCF_EDA_Inductor == rc->type) + && SCF_EDA_Capacitor != c->type && SCF_EDA_Inductor != c->type) { + + ret = __ses_dfs_add_ppath(__paths, ppath); + if (ret < 0) + return ret; + + *ppath = NULL; + } + + if (!c->ops || !c->ops->shared || !c->ops->shared(p)) + p->vflag = 1; + + ses_path_t* tmp = NULL; + + if ((SCF_EDA_Capacitor == c->type || SCF_EDA_Inductor == c->type) + && SCF_EDA_Capacitor != rc->type && SCF_EDA_Inductor != rc->type) { + tmp = *ppath; + *ppath = NULL; + } + + ret = __ses_dfs_path(f, c, p, __paths, ppath, flags); + if (ret < 0) + return ret; + + if (SCF_EDA_Path_OFF == ret) + p->vflag = 0; + + if (tmp) { + *ppath = tmp; + + if (j + 2 >= el->n_pins) { + + ret = __ses_dfs_add_ppath(__paths, ppath); + if (ret < 0) + return ret; + *ppath = NULL; + } + } + } + + return ret; +} + +static int __ses_dfs_IC(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __paths, ses_path_t** ppath, int flags) +{ + ses_path_t* path; + + ScfEcomponent* c; + ScfEline* el = rc->f->elines[rp->id]; + ScfEpin* np; + ScfEpin* p; + + scf_logd("*** rc->f->elines: %p, rc->f->n_elines: %ld, rc: %ld, rp->id: %ld, el: %p\n", rc->f->elines, rc->f->n_elines, rc->id, rp->id, el); + + int size = __paths->size; + + long j; + for (j = 0; j + 1 < el->n_pins; j += 2) { + + c = rc->f->components[el->pins[j]]; + p = c->pins [el->pins[j + 1]]; + + if (p->vflag) + continue; + + scf_logd("--- c%ldp%ld->IC: %p, l%ld, vflag: %d, pflag: %d, f: %p, rc->f: %p, c%ldp%ld\n", + rp->cid, rp->id, rp->IC, rp->lid, rp->vflag, rp->pflag, f, rc->f, c->id, p->id); + + int ret = __ses_dfs_path(rc->f, c, p, __paths, ppath, 0); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + } + + scf_logd("------size: %d, %d\n\n", size, __paths->size); + + int i; + int k; + + for (i = __paths->size - 1; i >= size; i--) { + path = __paths->data[i]; + + for (k = path->pins->size - 1; k > 0; k -= 2) { + p = path->pins->data[k]; + + if (p->IC != rc) + break; + + if (p->lid >= rc->n_pins) + continue; + + np = rc->pins[p->lid]; + el = f->elines[np->lid]; + + scf_logd("i: %d, np: c%ldp%ld\n", i, np->cid, np->id); + + if (SCF_EDA_PIN_NEG & el->flags) { + scf_logd("neg l%ld\n\n", el->id); + continue; + } + + if (path->pins->size - 1 == k) { + assert(0 == scf_vector_del(__paths, path)); + *ppath = path; + } else + *ppath = NULL; + + int ret = __ses_dfs_line(f, rc, np, __paths, ppath, flags); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + } + } + + scf_logd("*** rc->f->elines: %p, rc->f->n_elines: %ld, rc: %ld, rp->id: %ld, size: %d, %d\n\n", + rc->f->elines, rc->f->n_elines, rc->id, rp->id, size, __paths->size); + return 0; +} + static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __paths, ses_path_t** ppath, int flags) { - ScfEcomponent* c; - ScfEline* el; - ScfEpin* np; - ScfEpin* p; + ScfEcomponent* c; + ScfEline* el; + ScfEpin* np; + ScfEpin* p; - int64_t i; - int64_t j; + long i; + long j; if (rc->ops && rc->ops->off && rc->ops->off(rp, NULL)) return SCF_EDA_Path_OFF; if (SCF_EDA_Status_OFF != rc->status) { +#if 1 + if (flags && rc->f) + return __ses_dfs_IC(f, rc, rp, __paths, ppath, flags); +#endif + if (!*ppath) { *ppath = ses_path_alloc(); if (!*ppath) @@ -51,7 +210,10 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v if (!rc->ops || !rc->ops->shared || !rc->ops->shared(rp)) rp->vflag = 1; - scf_logd("c%ldp%ld, l%ld, vflag: %d, pflag: %d\n", rp->cid, rp->id, rp->lid, rp->vflag, rp->pflag); + if (rp->IC) + scf_logd("IC%ld_c%ldp%ld, l%ld, vflag: %d, pflag: %d\n", rp->IC->id, rp->cid, rp->id, rp->lid, rp->vflag, rp->pflag); + else + scf_logd("c%ldp%ld, l%ld, vflag: %d, pflag: %d\n", rp->cid, rp->id, rp->lid, rp->vflag, rp->pflag); int ret = 0; @@ -64,7 +226,10 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v if (rc->ops && rc->ops->off && rc->ops->off(rp, np)) continue; - scf_logd("c%ldp%ld, l%ld, vflag: %d, pflag: %d\n", np->cid, np->id, np->lid, np->vflag, np->pflag); + if (np->IC) + scf_logd("IC%ld_c%ldp%ld, l%ld, vflag: %d, pflag: %d\n", np->IC->id, np->cid, np->id, np->lid, np->vflag, np->pflag); + else + scf_logd("c%ldp%ld, l%ld, vflag: %d, pflag: %d\n", np->cid, np->id, np->lid, np->vflag, np->pflag); el = f->elines[np->lid]; @@ -115,69 +280,9 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v *ppath = NULL; } - ret = 0; - - for (j = 0; j + 1 < el->n_pins; j += 2) { - - c = f->components[el->pins[j]]; - p = c->pins [el->pins[j + 1]]; - - if (p->pflag) { - if (p != np) { - scf_logd("branch: c%ld_p%ld, l%ld\n\n", c->id, p->id, el->id); - - ret = __ses_dfs_add_ppath(__paths, ppath); - if (ret < 0) - return ret; - - *ppath = NULL; - } - continue; - } - - if (p->vflag) - continue; - - if ((SCF_EDA_Capacitor == rc->type || SCF_EDA_Inductor == rc->type) - && SCF_EDA_Capacitor != c->type && SCF_EDA_Inductor != c->type) { - - ret = __ses_dfs_add_ppath(__paths, ppath); - if (ret < 0) - return ret; - - *ppath = NULL; - } - - if (!c->ops || !c->ops->shared || !c->ops->shared(p)) - p->vflag = 1; - - ses_path_t* tmp = NULL; - - if ((SCF_EDA_Capacitor == c->type || SCF_EDA_Inductor == c->type) - && SCF_EDA_Capacitor != rc->type && SCF_EDA_Inductor != rc->type) { - tmp = *ppath; - *ppath = NULL; - } - - ret = __ses_dfs_path(f, c, p, __paths, ppath, flags); - if (ret < 0) - return ret; - - if (SCF_EDA_Path_OFF == ret) - p->vflag = 0; - - if (tmp) { - *ppath = tmp; - - if (j + 2 >= el->n_pins) { - - ret = __ses_dfs_add_ppath(__paths, ppath); - if (ret < 0) - return ret; - *ppath = NULL; - } - } - } + ret = __ses_dfs_line(f, rc, np, __paths, ppath, flags); + if (ret < 0) + return ret; if (off) *ppath = off; @@ -207,19 +312,52 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v return ret; } -static int ses_pin_to_npn(const ScfEfunction* f, const ScfEpin* vip, int pid) +static int ses_line_to_pin(const ScfEfunction* f, const ScfEpin* vip, const ScfEline* el, int ctype, int pid) { - const ScfEcomponent* c; - const ScfEline* el = f->elines[vip->lid]; - const ScfEpin* p; + ScfEcomponent* c; + ScfEpin* p; - int i; + long 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) + if (p == vip) + continue; + + if (ctype == c->type && pid == p->id) + return 1; + + if (c->f) { + if (ses_line_to_pin(c->f, vip, c->f->elines[p->id], ctype, pid)) + return 1; + } + } + + return 0; +} + +static int ses_pin_to_npn(const ScfEfunction* f, const ScfEpin* vip, int pid) +{ + const ScfEcomponent* c; + const ScfEline* el; + const ScfEpin* p; + + if (!vip->IC) { + el = f->elines[vip->lid]; + return ses_line_to_pin(f, vip, el, SCF_EDA_NPN, pid); + } + + el = vip->IC->f->elines[vip->lid]; + if (ses_line_to_pin(vip->IC->f, vip, el, SCF_EDA_NPN, pid)) + return 1; + + if (vip->lid < vip->IC->n_pins) { + p = vip->IC->pins[vip->lid]; + + el = f->elines[p->lid]; + if (ses_line_to_pin(f, p, el, SCF_EDA_NPN, pid)) return 1; } @@ -229,16 +367,23 @@ static int ses_pin_to_npn(const ScfEfunction* f, const ScfEpin* vip, int pid) static int ses_pin_to_pnp(const ScfEfunction* f, const ScfEpin* vip, int pid) { const ScfEcomponent* c; - const ScfEline* el = f->elines[vip->lid]; + const ScfEline* el; const ScfEpin* p; - int i; - for (i = 0; i < el->n_pins; i += 2) { + if (!vip->IC) { + el = f->elines[vip->lid]; + return ses_line_to_pin(f, vip, el, SCF_EDA_PNP, pid); + } - c = f->components[el->pins[i]]; - p = c->pins [el->pins[i + 1]]; + el = vip->IC->f->elines[vip->lid]; + if (ses_line_to_pin(vip->IC->f, vip, el, SCF_EDA_PNP, pid)) + return 1; + + if (vip->lid < vip->IC->n_pins) { + p = vip->IC->pins[vip->lid]; - if (p != vip && SCF_EDA_PNP == c->type && pid == p->id) + el = f->elines[p->lid]; + if (ses_line_to_pin(f, p, el, SCF_EDA_PNP, pid)) return 1; } @@ -341,8 +486,8 @@ static int __topo_path_bridges(ScfEfunction* f, ses_path_t* path) if (SCF_EDA_PIN_IN & p1->flags) goto bridge_sp0; - c0 = f->components[p0->cid]; - c1 = f->components[p1->cid]; + c0 = ses_component(f, p0); + c1 = ses_component(f, p1); if ((SCF_EDA_NPN == c0->type && SCF_EDA_NPN_C == p0->id) || (SCF_EDA_PNP == c0->type && SCF_EDA_PNP_C == p0->id)) @@ -533,7 +678,7 @@ static int _topo_path_connect(ScfEfunction* f, scf_vector_t* paths) p0 = path0->pins->data[0]; p1 = path0->pins->data[path0->pins->size - 1]; - if (p0->lid == Bp->lid || p1->lid == Bn->lid) { + if (ses_same_line(f, p0, Bp) || ses_same_line(f, p1, Bn)) { i++; continue; } @@ -547,7 +692,7 @@ static int _topo_path_connect(ScfEfunction* f, scf_vector_t* paths) p2 = path1->pins->data[0]; p3 = path1->pins->data[path1->pins->size - 1]; - if (p3->lid == p0->lid) { + if (ses_same_line(f, p3, p0)) { for (k = 0; k < path0->pins->size; k++) { p = path0->pins->data[k]; @@ -556,7 +701,7 @@ static int _topo_path_connect(ScfEfunction* f, scf_vector_t* paths) } goto connected; - } else if (p3->lid == p1->lid) { + } else if (ses_same_line(f, p3, p1)) { if (path0->n_diodes + path0->n_NPNs > 0 || path0->n_transistors > 0) continue; @@ -569,7 +714,7 @@ static int _topo_path_connect(ScfEfunction* f, scf_vector_t* paths) } goto connected; - } else if (p2->lid == p1->lid) { + } else if (ses_same_line(f, p2, p1)) { for (k = 0; k < path1->pins->size; k++) { p = path1->pins->data[k]; @@ -580,7 +725,7 @@ static int _topo_path_connect(ScfEfunction* f, scf_vector_t* paths) SCF_XCHG(path0->pins, path1->pins); goto connected; - } else if (p2->lid == p0->lid) { + } else if (ses_same_line(f, p2, p0)) { if (path0->n_diodes + path0->n_NPNs > 0 || path0->n_transistors > 0) continue; @@ -625,7 +770,7 @@ error: return -ENOMEM; } -static int _topo_fix_complete(scf_vector_t* paths, ses_path_t* parent) +static int _topo_fix_complete(ScfEfunction* f, scf_vector_t* paths, ses_path_t* parent) { ses_path_t* child; @@ -636,7 +781,7 @@ static int _topo_fix_complete(scf_vector_t* paths, ses_path_t* parent) for (i = 0; i < parent->childs->size; ) { child = parent->childs->data[i]; - if (ses_path_is_child(parent, child)) + if (ses_path_is_child(f, parent, child)) i++; else { int ret = scf_vector_add(paths, child); @@ -654,7 +799,7 @@ static int _topo_fix_complete(scf_vector_t* paths, ses_path_t* parent) for (i = 0; i < parent->bridges->size; ) { child = parent->bridges->data[i]; - if (ses_path_is_child(parent, child)) + if (ses_path_is_child(f, parent, child)) i++; else { int ret = scf_vector_add(paths, child); @@ -699,12 +844,12 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths) p0 = path0->pins->data[0]; p1 = path0->pins->data[path0->pins->size - 1]; - if (p1->lid != Bn->lid) { + if (!ses_same_line(f, p1, Bn)) { i++; continue; } - if (p0->lid == Bp->lid) { + if (ses_same_line(f, p0, Bp)) { i++; continue; } @@ -718,16 +863,16 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths) p2 = path1->pins->data[0]; p3 = path1->pins->data[path1->pins->size - 1]; - if (p2->lid != Bp->lid) + if (!ses_same_line(f, p2, Bp)) continue; - if (p3->lid == Bn->lid) + if (ses_same_line(f, p3, Bn)) continue; for (k = path1->pins->size - 1; k >= 0; k -= 2) { p = path1->pins->data[k]; - if (p->lid == p0->lid) + if (ses_same_line(f, p, p0)) break; } @@ -740,11 +885,11 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths) if (ret < 0) return ret; - ret = _topo_fix_complete(paths, path1); + ret = _topo_fix_complete(f, paths, path1); if (ret < 0) return ret; - ret = _topo_fix_complete(paths, path0); + ret = _topo_fix_complete(f, paths, path0); if (ret < 0) return ret; @@ -761,7 +906,7 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths) for (k = 0; k < path0->pins->size; k += 2) { p = path0->pins->data[k]; - if (p->lid == p3->lid) + if (ses_same_line(f, p, p3)) break; } @@ -774,11 +919,11 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths) if (ret < 0) return ret; - ret = _topo_fix_complete(paths, path1); + ret = _topo_fix_complete(f, paths, path1); if (ret < 0) return ret; - ret = _topo_fix_complete(paths, path0); + ret = _topo_fix_complete(f, paths, path0); if (ret < 0) return ret; @@ -800,193 +945,6 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths) return 0; } -static int __ses_branch_exist(ses_path_t* path, int i) -{ - if (!path->childs) - return 0; - - ses_path_t* child; - ScfEpin* cp; - ScfEpin* p = path->pins->data[i]; - - int j; - int k; - - for (j = 0; j < path->childs->size; j++) { - child = path->childs->data[j]; - - for (k = 0; k < child->pins->size; k++) { - cp = child->pins->data[k]; - - if (cp->lid == p->lid) - return 1; - } - } - - return 0; -} - -static int __topo_path_key_infos(ScfEfunction* f, ses_path_t* path) -{ - ses_info_t* info = NULL; - ScfEcomponent* c; - ScfEpin* p; - - int i; - int j; - - scf_vector_clear(path->infos, ( void (*)(void*) )free); - path->n_diodes = 0; - path->n_NPNs = 0; - path->n_PNPs = 0; - - for (i = 0; i < path->pins->size; i++) { - p = path->pins->data[i]; - - c = f->components[p->cid]; - - if (SCF_EDA_Diode == c->type) { - - if (!info) { - info = calloc(1, sizeof(ses_info_t)); - if (!info) - return -ENOMEM; - - info->i = i; - } - - if (SCF_EDA_Diode_NEG == p->id) { - info->n_diodes++; - path->n_diodes++; - - if (__ses_branch_exist(path, i)) { - j = i; - goto _add; - } - } - continue; - } - - if (SCF_EDA_NPN == c->type) { - - if (SCF_EDA_NPN_B == p->id) { - if (!info) { - info = calloc(1, sizeof(ses_info_t)); - if (!info) - return -ENOMEM; - - info->i = i; - } - - info->n_NPNs++; - path->n_NPNs++; - continue; - - } else if (SCF_EDA_NPN_E == p->id) { - - if (__ses_branch_exist(path, i)) { - j = i; - goto _add; - } - continue; - } - } - - if (SCF_EDA_PNP == c->type) { - - if (SCF_EDA_PNP_B == p->id) { - if (!info) { - info = calloc(1, sizeof(ses_info_t)); - if (!info) - return -ENOMEM; - - info->i = i - 1; - } - - info->n_PNPs++; - path->n_PNPs++; - - if (__ses_branch_exist(path, i)) { - j = i; - goto _add; - } - - } else if (SCF_EDA_PNP_C == p->id) { - if (info) { - if (info->n_diodes + info->n_NPNs + info->n_PNPs > 0) { - j = i - 2; - goto _add; - } - - free(info); - info = NULL; - } - } - continue; - } - - j = i - 1; -_add: - if (info) { - info->j = j; - - if (scf_vector_add(path->infos, info) < 0) { - free(info); - return -ENOMEM; - } - - info = NULL; - } - } - - if (info) { - info->j = i - 1; - - if (scf_vector_add(path->infos, info) < 0) { - free(info); - return -ENOMEM; - } - - info = NULL; - } - - return 0; -} - -static int _topo_path_key_infos(ScfEfunction* f, ses_path_t* path) -{ - ses_path_t* child; - - int ret; - int i; - - ret = __topo_path_key_infos(f, path); - if (ret < 0) - return ret; - - if (path->childs) { - for (i = 0; i < path->childs->size; i++) { - child = path->childs->data[i]; - - ret = _topo_path_key_infos(f, child); - if (ret < 0) - return ret; - } - } - - if (path->bridges) { - for (i = 0; i < path->bridges->size; i++) { - child = path->bridges->data[i]; - - ret = _topo_path_key_infos(f, child); - if (ret < 0) - return ret; - } - } - - return 0; -} - static int _topo_layers(ScfEfunction* f, scf_vector_t* paths) { ScfEcomponent* B; @@ -1013,10 +971,10 @@ static int _topo_layers(ScfEfunction* f, scf_vector_t* paths) assert(child->pins->size >= 2); - p0 = child->pins->data[0]; - p1 = child->pins->data[child->pins->size - 1]; + p0 = child->pins->data[0]; + p1 = child->pins->data[child->pins->size - 1]; - if (p0->lid == Bp->lid && p1->lid == Bn->lid) + if (ses_same_line(f, p0, Bp) && ses_same_line(f, p1, Bn)) continue; for (j = paths->size - 1; j >= 0; j--) { @@ -1028,9 +986,9 @@ static int _topo_layers(ScfEfunction* f, scf_vector_t* paths) p2 = parent->pins->data[0]; p3 = parent->pins->data[parent->pins->size - 1]; - if (p2->lid == p0->lid && p3->lid == p1->lid) + if (ses_same_line(f, p2, p0) && ses_same_line(f, p3, p1)) continue; - if (p3->lid == p0->lid && p2->lid == p1->lid) + if (ses_same_line(f, p3, p0) && ses_same_line(f, p2, p1)) continue; int n = 0; @@ -1038,10 +996,10 @@ static int _topo_layers(ScfEfunction* f, scf_vector_t* paths) for (k = 0; k < parent->pins->size; k++) { p = parent->pins->data[k]; - if (p->lid == p0->lid) + if (ses_same_line(f, p, p0)) n |= 0x1; - if (p->lid == p1->lid) + if (ses_same_line(f, p, p1)) n |= 0x2; if (0x3 == n) @@ -1055,7 +1013,7 @@ branch: if (scf_vector_del(paths, child) < 0) return -1; - if (ses_path_add(parent, child) < 0) { + if (ses_path_add(f, parent, child) < 0) { ses_path_free(child); return -ENOMEM; } @@ -1113,12 +1071,16 @@ static void _topo_key_components(ScfEfunction* f, ses_path_t* path) path->n_NPNs = 0; path->n_PNPs = 0; path->n_diodes = 0; - path->n_capacitors = 0; + path->n_capacitors = 0; + path->n_transistors = 0; for (i = 0; i < path->pins->size; i++) { p = path->pins->data[i]; - c = f->components[p->cid]; + if (p->IC) + c = p->IC->f->components[p->cid]; + else + c = f->components[p->cid]; if (SCF_EDA_Diode == c->type) { @@ -1183,6 +1145,9 @@ static void _topo_clear(ScfEfunction* f) p->dr = 0; p->a = 0; } + + if (c->f) + _topo_clear(c->f); } } @@ -1193,12 +1158,10 @@ static int _topo_paths(ScfEfunction* f, ScfEline* el, scf_vector_t* paths, int f ses_path_t* path; ScfEcomponent* c; - ScfEcomponent* B; ScfEpin* p; - size_t i; + long i; - B = f->components[0]; path = NULL; for (i = 0; i + 1 < el->n_pins; i += 2) { @@ -1206,7 +1169,7 @@ static int _topo_paths(ScfEfunction* f, ScfEline* el, scf_vector_t* paths, int f c = f->components[el->pins[i]]; p = c->pins [el->pins[i + 1]]; - if (c == B) + if (SCF_EDA_Battery == c->type) continue; int ret = __ses_dfs_path(f, c, p, paths, &path, flags); @@ -1222,6 +1185,8 @@ static int _topo_paths(ScfEfunction* f, ScfEline* el, scf_vector_t* paths, int f continue; } + scf_logi("path: %p\n\n", path); + if (scf_vector_add(paths, path) < 0) { ses_path_free(path); return -ENOMEM; @@ -1244,7 +1209,7 @@ static int _topo_paths(ScfEfunction* f, ScfEline* el, scf_vector_t* paths, int f return 0; } -static int __topo_bridge_connection(scf_vector_t* paths, ses_path_t* bridge, ScfEpin* vip, ses_path_t** ppath) +static int __topo_bridge_connection(ScfEfunction* f, scf_vector_t* paths, ses_path_t* bridge, ScfEpin* vip, ses_path_t** ppath) { ses_path_t* path; ses_path_t* conn; @@ -1265,28 +1230,28 @@ static int __topo_bridge_connection(scf_vector_t* paths, ses_path_t* bridge, Scf p2 = path->pins->data[0]; p3 = path->pins->data[path->pins->size - 1]; - if (p2->lid == p0->lid && p3->lid == p1->lid) + if (ses_same_line(f, p2, p0) && ses_same_line(f, p3, p1)) continue; - if (p3->lid == p0->lid && p2->lid == p1->lid) + if (ses_same_line(f, p3, p0) && ses_same_line(f, p2, p1)) continue; for (k = 0; k < path->pins->size; k++) { p2 = path->pins->data[k]; - if (p2->lid == vip->lid) { + if (ses_same_line(f, p2, vip)) { *ppath = path; return k; } } if (path->childs) { - k = __topo_bridge_connection(path->childs, bridge, vip, ppath); + k = __topo_bridge_connection(f, path->childs, bridge, vip, ppath); if (k >= 0) return k; } if (path->bridges) { - k = __topo_bridge_connection(path->bridges, bridge, vip, ppath); + k = __topo_bridge_connection(f, path->bridges, bridge, vip, ppath); if (k >= 0) return k; } @@ -1310,28 +1275,28 @@ static int _topo_bridge_piers(ScfEfunction* f, scf_vector_t* paths) int j; int k; - for (i = paths->size - 1; i >= 0; i--) { - pier = paths->data[i]; + for (i = paths->size - 1; i >= 0; i--) { + pier = paths->data[i]; p0 = pier->pins->data[0]; p1 = pier->pins->data[pier->pins->size - 1]; bridge = NULL; - if (p0->lid == Bp->lid) { - if (p1->lid == Bn->lid) + if (ses_same_line(f, p0, Bp)) { + if (ses_same_line(f, p1, Bn)) continue; - k = __topo_bridge_connection(paths, pier, p1, &bridge); + k = __topo_bridge_connection(f, paths, pier, p1, &bridge); if (k < 0) continue; pier->parent_p0 = -2; pier->parent_p1 = k; - } else if (p1->lid == Bn->lid) { + } else if (ses_same_line(f, p1, Bn)) { - k = __topo_bridge_connection(paths, pier, p0, &bridge); + k = __topo_bridge_connection(f, paths, pier, p0, &bridge); if (k < 0) continue; @@ -1390,14 +1355,14 @@ static int _topo_bridge_connections(ScfEfunction* f, scf_vector_t* paths) p0 = path->pins->data[0]; p1 = path->pins->data[path->pins->size - 1]; - if (p0->lid == Bp->lid && p1->lid == Bn->lid) + if (ses_same_line(f, p0, Bp) && ses_same_line(f, p1, Bn)) continue; - int k0 = __topo_bridge_connection(paths, path, p0, &path->conn0); + int k0 = __topo_bridge_connection(f, paths, path, p0, &path->conn0); if (k0 < 0) continue; - int k1 = __topo_bridge_connection(paths, path, p1, &path->conn1); + int k1 = __topo_bridge_connection(f, paths, path, p1, &path->conn1); if (k1 < 0) continue; @@ -1419,11 +1384,11 @@ static int _topo_bridge_connections(ScfEfunction* f, scf_vector_t* paths) return 0; } -static int _topo_paths_mov_top(scf_vector_t* paths, ses_path_t* parent, ses_path_t* child) +static int _topo_paths_mov_top(ScfEfunction* f, scf_vector_t* paths, ses_path_t* parent, ses_path_t* child) { - ses_path_t* path; - ScfEpin* p0 = parent->pins->data[0]; - ScfEpin* p; + ses_path_t* path; + ScfEpin* p0 = parent->pins->data[0]; + ScfEpin* p; int k; @@ -1431,7 +1396,7 @@ static int _topo_paths_mov_top(scf_vector_t* paths, ses_path_t* parent, ses_path path = paths->data[k]; p = path->pins->data[0]; - if (p->lid != p0->lid) + if (!ses_same_line(f, p, p0)) continue; path->parent_p0 = 0; @@ -1478,22 +1443,22 @@ static int _topo_path_parallel(ScfEfunction* f, scf_vector_t* paths) p2 = child->pins->data[0]; p3 = child->pins->data[child->pins->size - 1]; - if (p0->lid == p2->lid && p1->lid == p3->lid) { + if (ses_same_line(f, p0, p2) && ses_same_line(f, p1, p3)) { - int ret = ses_path_add(parent, child); + int ret = ses_path_add(f, parent, child); if (ret < 0) return ret; assert(0 == scf_vector_del(paths, child)); if (child->childs) { - ret = _topo_paths_mov_top(child->childs, parent, child); + ret = _topo_paths_mov_top(f, child->childs, parent, child); if (ret < 0) return ret; } if (child->bridges) { - ret = _topo_paths_mov_top(child->bridges, parent, child); + ret = _topo_paths_mov_top(f, child->bridges, parent, child); if (ret < 0) return ret; } @@ -1549,20 +1514,29 @@ int ses_layout_paths(ScfEfunction* f, scf_vector_t* paths) scf_vector_clear(paths, ( void (*)(void*) )ses_path_free); - B = f->components[0]; - el = f->elines[B->pins[SCF_EDA_Battery_POS]->lid]; + long i; + for (i = 0; i < f->n_elines; i++) { + el = f->elines[i]; - int ret = _topo_paths(f, el, paths, 0); - if (ret < 0) - return ret; + scf_logi("e%ld->flags: %#lx\n", el->id, el->flags); + + if (el->flags & SCF_EDA_PIN_POS) { + + scf_loge("e%ld->flags: %#lx\n", el->id, el->flags); + + int ret = _topo_paths(f, el, paths, 0); + if (ret < 0) + return ret; + break; + } + } - int i; for (i = 0; i < f->n_elines; i++) { el = f->elines[i]; if (el->flags & SCF_EDA_PIN_IN) { - ret = _topo_paths(f, el, paths, 0); + int ret = _topo_paths(f, el, paths, 0); if (ret < 0) return ret; } @@ -1577,7 +1551,6 @@ static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* { ses_path_t* path; ScfEcomponent* B; - ScfEcomponent* R; ScfEline* el; _topo_clear(f); @@ -1591,6 +1564,10 @@ static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* if (ret < 0) return ret; + scf_logi("\n"); + ses_paths_print(ctx->paths); + scf_logi("\n\n"); + ret = __ses_topo_layers(f, ctx->paths); if (ret < 0) return ret; @@ -1608,10 +1585,6 @@ static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* path = ctx->paths->data[i]; _topo_key_components(f, path); - - ret = _topo_path_key_infos(f, path); - if (ret < 0) - return ret; } ses_paths_print(ctx->paths); diff --git a/ses_step_va.c b/ses_step_va.c index 7610a28..11fa9a0 100644 --- a/ses_step_va.c +++ b/ses_step_va.c @@ -1,203 +1,10 @@ #include"ses_core.h" -int __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe, int vinit) -{ - ScfEcomponent* c2; - ScfEline* el; - ScfEpin* p2; - - ScfEcomponent* B = f->components[0]; - ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; - ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; - - size_t i; - double Voff = SCF_EDA_Diode == c->type ? SCF_EDA_V_Diode_OFF : SCF_EDA_V_NPN_OFF; - double Von = SCF_EDA_Diode == c->type ? SCF_EDA_V_Diode_ON : SCF_EDA_V_NPN_ON; - - pb->v = f->elines[pb->lid]->v; - pe->v = f->elines[pe->lid]->v; - - if (pb->v < SCF_EDA_V_MIN) { - - if (pe->v < SCF_EDA_V_MIN) - return 0; - - pb->v = pe->v + Von; - - if (pb->v > Bp->v) { - pb->v = Bp->v; - if (!c->lock) - c->status = SCF_EDA_Status_OFF; - } else - c->status = SCF_EDA_Status_ON; - goto _changed; - - } else if (pe->v < SCF_EDA_V_MIN) { - pe->v = pb->v - Von; - - if (pe->v < Bn->v) { - pe->v = Bn->v; - if (!c->lock) - c->status = SCF_EDA_Status_OFF; - } else - c->status = SCF_EDA_Status_ON; - goto _changed; - - } else if (pb->v - pe->v < Voff) { - - if (c->status != SCF_EDA_Status_OFF) { - if (!c->lock) - c->status = SCF_EDA_Status_OFF; - goto _changed; - } - } else if (SCF_EDA_Status_ON != c->status) { - c->status = SCF_EDA_Status_ON; - goto _changed; - } - - return 0; - -_changed: - if (SCF_EDA_NPN == c->type || SCF_EDA_PNP == c->type) { - - p2 = c->pins [SCF_EDA_NPN_C]; - el = f->elines[p2->lid]; - el->vinit = vinit; - - for (i = 0; i + 1 < el->n_pins; i += 2) { - - c2 = f->components[el->pins[i]]; - p2 = c->pins [el->pins[i + 1]]; - - if ((SCF_EDA_NPN == c2->type || SCF_EDA_PNP == c2->type) && SCF_EDA_NPN_B == p2->id) { - c2->status = SCF_EDA_Status_ON; - c2->lock = 1; - - scf_loge("\033[35mc%ld, status: %d\033[0m\n", c2->id, c2->status); - } - } - } - - scf_loge("\033[34mc%ld, status: %d, pb->v: %lg, pe->v: %lg, diff: %lg, Von: %lg, Voff: %lg\033[0m\n", - c->id, c->status, pb->v, pe->v, pb->v - pe->v, Von, Voff); - return 1; -} - -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; - - ScfEcomponent* c; - ScfEline* el; - ScfEpin* p0; - ScfEpin* p1; - ScfEpin* cp0; - ScfEpin* cp1; - - int j; - int k; - int n_childs = 0; - - p0 = 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 (p0->lid != cp0->lid) - continue; - - for (k = i + 1; k <= n; k++) { - p1 = path->pins->data[k]; - - if (p1->lid == cp1->lid) - break; - } - - if (k > n) - continue; - - double sr = 0; - double cv = 0; - double lv = 0; - double dv = 0; - double da = 0; - double pr; - double v; - - __ses_path_pr(f, path, i, k, child, &pr); - - ses_ir_u(&v, NULL, *a, 0, pr, 0); - - ses_ur_i(&child->a0, NULL, v, 0, child->pr, 0); - - __ses_path_lc(f, path, i, k, &cv, &lv, NULL, NULL, NULL); - v += cv + lv; - - ses_ur_i(&child->a, NULL, v, 0, child->pr, 0); - - scf_logw("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d, n_NPNs: %d), v: %lg, cv: %lg, lv: %lg, dv: %lg, a: %lg, pr: %lg, sr: %lg\n", - child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id, - child->n_diodes, child->n_NPNs, v, cv, lv, dv, *a, pr, sr); - - *a -= child->a0; - - el = f->elines[p1->lid]; - el->v = p0->v - v; - - double _pr0 = p0->pr; - double _sr0 = p0->sr; - double _pr1 = p1->pr; - double _sr1 = p1->sr; - - double _cpr0 = cp0->pr; - double _csr0 = cp0->sr; - double _cpr1 = cp1->pr; - double _csr1 = cp1->sr; - - cp0->pr = 0; - cp0->sr = 0; - cp1->pr = child->pr; - cp1->sr = child->sr; - - if (child->n_diodes + child->n_NPNs > 0) { - __ses_path_va_diode(f, child); - __ses_path_jr (f, child); - } - - int ret = __ses_path_va(f, child, changed, ns, count); - if (ret < 0) - return ret; - - cp0->pr = _cpr0; - cp0->sr = _csr0; - cp1->pr = _cpr1; - cp1->sr = _csr1; - - p0->pr = _pr0; - p0->sr = _sr0; - p1->pr = _pr1; - p1->sr = _sr1; - - scf_loge("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d), p->v: %lg, v: %lg, child->a0: %lg, child->a: %lg, cv: %lg, lv: %lg\n\n", - child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id, - child->n_diodes + child->n_NPNs, p0->v, v, child->a0, child->a, cv, lv); - - n_childs++; - } - - scf_logw("*****************\n"); - return n_childs; -} - static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i, double a) { ScfEpin* p0 = path->pins->data[i0]; ScfEpin* p = path->pins->data[i]; - ScfEcomponent* c = f->components[p->cid]; + ScfEcomponent* c = ses_component(f, p); double v; double r; @@ -242,7 +49,7 @@ void __ses_path_lc(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv, for (i = m; i <= n; i++) { p = path->pins->data[i]; - c = f->components[p->cid]; + c = ses_component(f, p); if (i & 0x1) { int sign = !p->id - p->id; @@ -329,8 +136,8 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double for (i = m; i <= n; i++) { p = path->pins->data[i]; - c = f->components[p->cid]; - el = f->elines[p->lid]; + c = ses_component(f, p); + el = ses_line(f, p); 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); @@ -378,44 +185,7 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, r: %lg, p->a: %lg, a: %lg, p->pr: %lg, e%ld->v: %lg\n\n", path->index, i, p->cid, p->id, p->v, dv, r, p->a, a, p->pr, el->id, el->v); - switch (c->type) { - case SCF_EDA_Diode: - - assert(SCF_EDA_Diode_NEG == p->id); - p2 = path->pins->data[i - 1]; - - *changed += __ses_status_check(f, c, p2, p, 1); - break; - - case SCF_EDA_NPN: - - assert(SCF_EDA_PNP_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); - - c->pins[SCF_EDA_NPN_C]->aconst = 1; - } - break; - - case SCF_EDA_PNP: - - if (SCF_EDA_PNP_B == p->id) { - p2 = path->pins->data[i - 1]; - - assert(SCF_EDA_PNP_E == p2->id); - - *changed += __ses_status_check(f, c, p2, p, 1); - - c->pins[SCF_EDA_PNP_C]->aconst = 1; - } - break; - default: - break; - }; - - r = 0; + 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, e%ld->v: %lg\n", @@ -437,325 +207,3 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double path->vflag = 1; return 0; } - -int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count) -{ - if (!path) - return -EINVAL; - - if (path->pins->size < 2) { - scf_loge("\n"); - return -EINVAL; - } - - if (n - m < 1) - return 0; - - ses_path_t* child; - ScfEcomponent* c; - ScfEline* el; - ScfEpin* p; - ScfEpin* p2; - ScfEpin* p0 = path->pins->data[m]; - ScfEpin* p1 = path->pins->data[n]; - ScfEpin* cp0; - ScfEpin* cp1; - - double cv = 0; - double lv = 0; - double a = 0; - double v = p0->v - p1->v; - - __ses_path_lc(f, path, m, n, &cv, &lv, NULL, NULL, NULL); - v -= cv + lv; - - 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, lv: %lg, pr: %lg, path->pr: %lg, a: %lg\n\n", - path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, lv, pr, path->pr, a); - - double r = 0; - double dv = 0; - double dv0 = 0; - double dvc = 0; - - int i0 = m; - int i; - int j; - - for (i = m; i <= n; i++) { - p = path->pins->data[i]; - - c = f->components[p->cid]; - - scf_logd("c%ldp%ld, p->r: %lg, dr: %lg, sr: %lg, pr: %lg\n", p->cid, p->id, p->r, p->dr, p->sr, p->pr); - - __ses_path_split_v(f, path, i0, i, a); - - p->v -= dv0 + dvc; - - double tmp = p->v; - - el = f->elines[p->lid]; - el->v = p->v; - - if (!(i & 0x1) && path->childs) { - int ret = __ses_path_split_a(f, path, i, n, &a, changed, ns, count); - if (ret < 0) - return ret; - - if (ret > 0) { - p0 = p; - i0 = i; - dv0 = p->v - tmp - dvc; - - scf_logi("-------i: %d, p0: c%ldp%ld, dvc: %lg\n", i, p0->cid, p0->id, dvc); - } - } - - el->v = p->v; - - r += p->r + p->dr; - - if (i & 0x1) { - p2 = path->pins->data[i - 1]; - dv -= p->v; - r += c->r + c->dr; - - ses_ur_i(&p->a, NULL, dv, 0, r, 0); - - int sign = !p->id - p->id; - - if (SCF_EDA_Capacitor == c->type) { - cv = c->v * sign; - dv -= cv; - ses_ur_i(&p->a, NULL, dv, 0, r, 0); - - c->a = p->a * sign; - dvc += cv; - - scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uf: %lg\n", - c->id, c->v, p->v, p2->v, dv, p->a, c->a, ns, c->uf); - - } else if (SCF_EDA_Inductor == c->type) { - lv = c->v * sign; - dv -= lv; - ses_ur_i(&p->a, NULL, dv, 0, r, 0); - - dvc += lv; - - } else if (p->a > a) { - p->a = a; - c->a = p->a * sign; - } else - c->a = p->a * sign; - c->count = count; - - 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; - - 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) - continue; - - int k; - for (k = m; k <= n; k++) { - p2 = path->pins->data[k]; - - if (p2->lid == cp0->lid) { - a += child->a0; - break; - } - } - - if (k > n) { - p0 = p; - i0 = i; - dv0 = 0; - scf_logi("----------------------i: %d, p0: c%ldp%ld\n", i, p0->cid, p0->id); - } - } - } - - scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, r: %lg, p->a: %lg, a: %lg, p->pr: %lg, e%ld->v: %lg\n\n", - path->index, i, p->cid, p->id, p->v, dv, r, p->a, a, p->pr, el->id, el->v); - - switch (c->type) { - case SCF_EDA_Diode: - - assert(SCF_EDA_Diode_NEG == p->id); - p2 = path->pins->data[i - 1]; - - *changed += __ses_status_check(f, c, p2, p, 1); - break; - - case SCF_EDA_NPN: - - assert(SCF_EDA_PNP_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); - - c->pins[SCF_EDA_NPN_C]->aconst = 1; - } - break; - - case SCF_EDA_PNP: - - if (SCF_EDA_PNP_B == p->id) { - p2 = path->pins->data[i - 1]; - - assert(SCF_EDA_PNP_E == p2->id); - - *changed += __ses_status_check(f, c, p2, p, 1); - - c->pins[SCF_EDA_PNP_C]->aconst = 1; - } - break; - default: - break; - }; - - r = 0; - } else { - dv = p->v; - scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, a: %lg, p->pr: %lg, dv0: %lg, e%ld->v: %lg\n", - path->index, i, p->cid, p->id, p->v, dv, a, p->pr, dv0, el->id, el->v); - } - } - printf("\n"); - - return 0; -} - -int __ses_path_va2(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count) -{ - if (!path) - return -EINVAL; - - if (path->pins->size < 2) { - scf_loge("\n"); - return -EINVAL; - } - - if (n - m < 1) - return 0; - - ScfEline* el; - ScfEpin* p0 = path->pins->data[m]; - ScfEpin* p1 = path->pins->data[n]; - - el = f->elines[p0->lid]; - p0->v = el->v; - - el = f->elines[p1->lid]; - p1->v = el->v; - - return __ses_path_va3(f, path, m, n, pr, changed, ns, count); -} - -int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed, int64_t ns, int64_t count) -{ - if (!path) - return -EINVAL; - - if (path->pins->size < 2) { - scf_loge("\n"); - return -EINVAL; - } - - ScfEpin* p0 = path->pins->data[0]; - ScfEpin* p1 = path->pins->data[path->pins->size - 1]; - - double _sr0 = p0->sr; - double _pr0 = p0->pr; - double _sr1 = p1->sr; - double _pr1 = p1->pr; - - p0->sr = 0; - p0->pr = 0; - p1->sr = path->sr; - p1->pr = path->pr; - - int ret = __ses_path_va2(f, path, 0, path->pins->size - 1, path->pr, changed, ns, count); - if (ret < 0) { - scf_loge("\n"); - return ret; - } - - p0->sr = _sr0; - p0->pr = _pr0; - p1->sr = _sr1; - p1->pr = _pr1; - return 0; -} - -static int _va_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) -{ - ses_path_t* path; - ScfEcomponent* B; - ScfEline* el; - ScfEpin* p0; - ScfEpin* p1; - ScfEpin* Bp; - ScfEpin* Bn; - - B = f->components[0]; - Bp = B->pins[SCF_EDA_Battery_POS]; - Bn = B->pins[SCF_EDA_Battery_NEG]; - - printf("\n*******************\n"); - - int changed = 0; - int i; - - for (i = 0; i < f->n_elines; i++) { - el = f->elines[i]; - el->ain = 0; - el->aout = 0; - } - - for (i = 0; i < ctx->paths->size; i++) { - path = ctx->paths->data[i]; - - if (path->pins->size < 2) { - scf_loge("\n"); - return -EINVAL; - } - - p0 = path->pins->data[0]; - p1 = path->pins->data[path->pins->size - 1]; - - if (p0->lid != Bp->lid || p1->lid != Bn->lid) - continue; - - scf_logi("i: %d, path->index: %d\n", i, path->index); - - __ses_path_jr(f, path); - - int ret = __ses_path_va(f, path, &changed, ns, count); - if (ret < 0) - return ret; - } - - ctx->changed += changed; - return 0; -} - -ses_step_t ses_step_va = -{ - .name = "va", - - .handler = _va_handler, -}; diff --git a/ses_steps.c b/ses_steps.c index 9801475..822c235 100644 --- a/ses_steps.c +++ b/ses_steps.c @@ -11,9 +11,7 @@ extern ses_step_t ses_step_dc_pnp; extern ses_step_t ses_step_topo; extern ses_step_t ses_step_jr; -extern ses_step_t ses_step_va_diode; extern ses_step_t ses_step_va; -extern ses_step_t ses_step_status; extern ses_step_t ses_step_open; extern ses_step_t ses_step_va_nodes; @@ -36,11 +34,6 @@ static ses_step_t* ses_steps_1[] = &ses_step_dc_pnp, &ses_step_topo, - -// &ses_step_va_diode, - -// &ses_step_va, -// &ses_step_status, }; static ses_step_t* ses_steps_2[] = @@ -48,7 +41,7 @@ static ses_step_t* ses_steps_2[] = &ses_step_open, &ses_step_va_nodes, - &ses_step_output, +// &ses_step_output, &ses_step_draw, }; diff --git a/test/main.c b/test/main.c index ea6a110..1300be5 100644 --- a/test/main.c +++ b/test/main.c @@ -88,7 +88,7 @@ int main(int argc, char* argv[]) scf_eboard__add_function(b, f); - int len = 0; + long len = 0; uint8_t* buf = NULL; ScfEboard_pack(b, &buf, &len); -- 2.25.1