From: yu.dongliang <18588496441@163.com> Date: Sat, 17 May 2025 14:23:06 +0000 (+0800) Subject: a sin oscillator with F007 OP-Amplifier ok, update some *.cpk X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=1374570017514fd8d55d8253b391f48d69de7b14;p=ses.git a sin oscillator with F007 OP-Amplifier ok, update some *.cpk --- diff --git a/Makefile b/Makefile index 0f2861d..d7d6821 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,6 @@ CFILES += ses_step_dc_pnp.c CFILES += ses_step_topo.c CFILES += ses_step_jr.c -CFILES += ses_step_va.c CFILES += ses_step_open.c CFILES += ses_step_va_nodes.c @@ -37,7 +36,7 @@ CFLAGS += -I./pack LDFLAGS += -lm LDFLAGS += -lcairo -LDFLAGS += -lgsl -lgslcblas +LDFLAGS += -lgsl #-lgslcblas all: gcc $(CFLAGS) $(CFILES) $(LDFLAGS) -o ses diff --git a/cpk/9012.txt b/cpk/9012.txt index 849920a..e8b206a 100644 --- a/cpk/9012.txt +++ b/cpk/9012.txt @@ -1,8 +1,8 @@ - 20uA, 20mV, 150 - 60uA, 60mV, 150 -120uA, 120mV, 150 -160uA, 160mV, 150 -220uA, 220mV, 150 -380uA, 380mV, 150 -0.5mA, 500mV, 150 -1.2mA, 700mV, 150 + 20uA, 20mV, 0.03V + 60uA, 60mV, 0.09V +120uA, 120mV, 0.18V +160uA, 160mV, 0.24V +220uA, 220mV, 0.33V +380uA, 380mV, 0.5V +0.5mA, 500mV, 0.85V +1.2mA, 700mV, 2.01V diff --git a/cpk/9013.txt b/cpk/9013.txt index 849920a..e8b206a 100644 --- a/cpk/9013.txt +++ b/cpk/9013.txt @@ -1,8 +1,8 @@ - 20uA, 20mV, 150 - 60uA, 60mV, 150 -120uA, 120mV, 150 -160uA, 160mV, 150 -220uA, 220mV, 150 -380uA, 380mV, 150 -0.5mA, 500mV, 150 -1.2mA, 700mV, 150 + 20uA, 20mV, 0.03V + 60uA, 60mV, 0.09V +120uA, 120mV, 0.18V +160uA, 160mV, 0.24V +220uA, 220mV, 0.33V +380uA, 380mV, 0.5V +0.5mA, 500mV, 0.85V +1.2mA, 700mV, 2.01V diff --git a/cpk/Makefile b/cpk/Makefile index 8bf7737..8807f05 100644 --- a/cpk/Makefile +++ b/cpk/Makefile @@ -29,10 +29,11 @@ #CFILES += jk_gate2.c #CFILES += rs_gate.c #CFILES += ttl_dff_test.c -CFILES += for_test.c +#CFILES += for_test.c #CFILES += add_gate.c #CFILES += adc_gate.c #CFILES += op_amp_741.c +CFILES += op_amp_f007.c #CFILES += op_amp_test.c CFILES += ../scf_eda_pack.c CFILES += ../pack/scf_pack.c diff --git a/cpk/op_amp_f007.c b/cpk/op_amp_f007.c new file mode 100644 index 0000000..4130ade --- /dev/null +++ b/cpk/op_amp_f007.c @@ -0,0 +1,219 @@ +#include +#include +#include +#include"ses_core.h" + +int main(int argc, char* argv[]) +{ + ScfEcomponent* T1; + ScfEcomponent* T2; + ScfEcomponent* T3; + ScfEcomponent* T4; + + ScfEcomponent* T5; + ScfEcomponent* T6; + ScfEcomponent* T7; + ScfEcomponent* R1; + ScfEcomponent* R2; + ScfEcomponent* R3; + + ScfEcomponent* T8; + ScfEcomponent* T9; + + ScfEcomponent* T10; + ScfEcomponent* T11; + ScfEcomponent* R4; + + ScfEcomponent* T12; + ScfEcomponent* T13; + ScfEcomponent* R5; + + ScfEcomponent* T14; + + ScfEcomponent* T15; + ScfEcomponent* R7; + ScfEcomponent* R8; + + ScfEcomponent* T16; + ScfEcomponent* T17; + + ScfEcomponent* T18; + ScfEcomponent* T19; + ScfEcomponent* R9; + ScfEcomponent* R10; + + ScfEcomponent* D1; + ScfEcomponent* D2; + ScfEcomponent* C1; + + ScfEfunction* f = scf_efunction__alloc("op_amp_f007.cpk"); + + EDA_INST_ADD_COMPONENT(f, R1, SCF_EDA_Resistor); + EDA_INST_ADD_COMPONENT(f, R2, SCF_EDA_Resistor); + EDA_INST_ADD_COMPONENT(f, R3, SCF_EDA_Resistor); + EDA_INST_ADD_COMPONENT(f, R4, SCF_EDA_Resistor); + EDA_INST_ADD_COMPONENT(f, R5, SCF_EDA_Resistor); + + EDA_INST_ADD_COMPONENT(f, R7, SCF_EDA_Resistor); + EDA_INST_ADD_COMPONENT(f, R8, SCF_EDA_Resistor); + EDA_INST_ADD_COMPONENT(f, R9, SCF_EDA_Resistor); + EDA_INST_ADD_COMPONENT(f, R10, SCF_EDA_Resistor); + + EDA_INST_ADD_COMPONENT(f, C1, SCF_EDA_Capacitor); + EDA_INST_ADD_COMPONENT(f, D1, SCF_EDA_Diode); + EDA_INST_ADD_COMPONENT(f, D2, SCF_EDA_Diode); + + EDA_INST_ADD_COMPONENT(f, T1, SCF_EDA_NPN); + EDA_INST_ADD_COMPONENT(f, T2, SCF_EDA_NPN); + EDA_INST_ADD_COMPONENT(f, T3, SCF_EDA_PNP); + EDA_INST_ADD_COMPONENT(f, T4, SCF_EDA_PNP); + + EDA_INST_ADD_COMPONENT(f, T5, SCF_EDA_NPN); + EDA_INST_ADD_COMPONENT(f, T6, SCF_EDA_NPN); + EDA_INST_ADD_COMPONENT(f, T7, SCF_EDA_NPN); + + EDA_INST_ADD_COMPONENT(f, T8, SCF_EDA_PNP); + EDA_INST_ADD_COMPONENT(f, T9, SCF_EDA_PNP); + + EDA_INST_ADD_COMPONENT(f, T10, SCF_EDA_NPN); + EDA_INST_ADD_COMPONENT(f, T11, SCF_EDA_NPN); + + EDA_INST_ADD_COMPONENT(f, T12, SCF_EDA_PNP); + EDA_INST_ADD_COMPONENT(f, T13, SCF_EDA_PNP); + + EDA_INST_ADD_COMPONENT(f, T14, SCF_EDA_NPN); + EDA_INST_ADD_COMPONENT(f, T15, SCF_EDA_NPN); + + EDA_INST_ADD_COMPONENT(f, T16, SCF_EDA_NPN); + EDA_INST_ADD_COMPONENT(f, T17, SCF_EDA_NPN); + + EDA_INST_ADD_COMPONENT(f, T18, SCF_EDA_PNP); + EDA_INST_ADD_COMPONENT(f, T19, SCF_EDA_NPN); + + EDA_PIN_ADD_PIN(T8, SCF_EDA_PNP_E, T9, SCF_EDA_PNP_E); + EDA_PIN_ADD_PIN(T8, SCF_EDA_PNP_B, T9, SCF_EDA_PNP_B); + EDA_PIN_ADD_PIN(T8, SCF_EDA_PNP_C, T8, SCF_EDA_PNP_B); + + EDA_PIN_ADD_PIN(T1, SCF_EDA_NPN_C, T2, SCF_EDA_NPN_C); + EDA_PIN_ADD_PIN(T1, SCF_EDA_NPN_E, T3, SCF_EDA_PNP_E); + EDA_PIN_ADD_PIN(T2, SCF_EDA_NPN_E, T4, SCF_EDA_PNP_E); + EDA_PIN_ADD_PIN(T3, SCF_EDA_PNP_B, T4, SCF_EDA_PNP_B); + + EDA_PIN_ADD_PIN(T8, SCF_EDA_PNP_C, T1, SCF_EDA_NPN_C); + EDA_PIN_ADD_PIN(T9, SCF_EDA_PNP_C, T3, SCF_EDA_NPN_B); + + EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_B, T6, SCF_EDA_NPN_B); + EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_E, R1, 1); + EDA_PIN_ADD_PIN(T6, SCF_EDA_NPN_E, R3, 1); + EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_B, R2, 1); + EDA_PIN_ADD_PIN(R1, 0, R2, 0); + EDA_PIN_ADD_PIN(R1, 0, R3, 0); + EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_C, T3, SCF_EDA_PNP_C); + EDA_PIN_ADD_PIN(T6, SCF_EDA_NPN_C, T4, SCF_EDA_PNP_C); + + EDA_PIN_ADD_PIN(T7, SCF_EDA_NPN_C, T8, SCF_EDA_PNP_E); + EDA_PIN_ADD_PIN(T7, SCF_EDA_NPN_B, T3, SCF_EDA_PNP_C); + EDA_PIN_ADD_PIN(T7, SCF_EDA_NPN_E, T5, SCF_EDA_NPN_B); + + EDA_PIN_ADD_PIN(T10, SCF_EDA_NPN_C, T9, SCF_EDA_PNP_C); + EDA_PIN_ADD_PIN(T10, SCF_EDA_NPN_B, T11, SCF_EDA_NPN_B); + EDA_PIN_ADD_PIN(T10, SCF_EDA_NPN_B, T11, SCF_EDA_NPN_C); + EDA_PIN_ADD_PIN(T10, SCF_EDA_NPN_E, R4, 1); + EDA_PIN_ADD_PIN(R4, 0, R1, 0); + EDA_PIN_ADD_PIN(T11, SCF_EDA_NPN_E, R1, 0); + + EDA_PIN_ADD_PIN(T12, SCF_EDA_PNP_E, T8, SCF_EDA_PNP_E); + EDA_PIN_ADD_PIN(T12, SCF_EDA_PNP_E, T13, SCF_EDA_PNP_E); + EDA_PIN_ADD_PIN(T12, SCF_EDA_PNP_B, T13, SCF_EDA_PNP_B); + EDA_PIN_ADD_PIN(T12, SCF_EDA_PNP_C, T12, SCF_EDA_PNP_B); + EDA_PIN_ADD_PIN(T12, SCF_EDA_PNP_C, R5, 1); + EDA_PIN_ADD_PIN(R5, 0, T11, SCF_EDA_NPN_C); + + EDA_PIN_ADD_PIN(T16, SCF_EDA_NPN_B, T6, SCF_EDA_NPN_C); + EDA_PIN_ADD_PIN(T16, SCF_EDA_NPN_C, T17, SCF_EDA_NPN_C); + EDA_PIN_ADD_PIN(T16, SCF_EDA_NPN_E, T17, SCF_EDA_NPN_B); + EDA_PIN_ADD_PIN(T17, SCF_EDA_NPN_E, R1, 0); + + EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_C, R7, 1); + EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_B, R7, 0); + EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_B, R8, 1); + EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_E, R8, 0); + + EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_E, T16, SCF_EDA_NPN_C); + EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_C, T13, SCF_EDA_PNP_C); + + EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_C, C1, 1); + EDA_PIN_ADD_PIN(T16, SCF_EDA_NPN_B, C1, 0); + + EDA_PIN_ADD_PIN(T14, SCF_EDA_NPN_B, T15, SCF_EDA_NPN_C); + EDA_PIN_ADD_PIN(T14, SCF_EDA_NPN_C, T8, SCF_EDA_PNP_E); + EDA_PIN_ADD_PIN(T14, SCF_EDA_NPN_E, R9, 1); + EDA_PIN_ADD_PIN(R9, 0, R10, 1); + EDA_PIN_ADD_PIN(R10, 0, T18, SCF_EDA_PNP_E); + EDA_PIN_ADD_PIN(R10, 0, T19, SCF_EDA_NPN_C); + EDA_PIN_ADD_PIN(T19, SCF_EDA_NPN_E, R1, 0); + + EDA_PIN_ADD_PIN(T18, SCF_EDA_PNP_C, T19, SCF_EDA_NPN_B); + EDA_PIN_ADD_PIN(T18, SCF_EDA_PNP_B, T16, SCF_EDA_NPN_C); + + EDA_PIN_ADD_PIN(D1, SCF_EDA_Diode_POS, D2, SCF_EDA_Diode_NEG); + EDA_PIN_ADD_PIN(D1, SCF_EDA_Diode_NEG, D2, SCF_EDA_Diode_POS); + EDA_PIN_ADD_PIN(D1, SCF_EDA_Diode_POS, R7, 0); + EDA_PIN_ADD_PIN(D1, SCF_EDA_Diode_NEG, R9, 0); + + EDA_SET_MIRROR(T1, T2); + EDA_SET_MIRROR(T3, T4); + EDA_SET_MIRROR(T5, T6); + EDA_SET_MIRROR(T8, T9); + EDA_SET_MIRROR(T12, T13); + EDA_SET_MIRROR(T16, T17); + EDA_SET_MIRROR(T18, T19); + + C1->uf = 30e-6; + R1->r = 1000; + R2->r = 1000 * 50; + R3->r = 1000; + R4->r = 3000; + R5->r = 1000 * 39; + R7->r = 4500; + R8->r = 7500; + R9->r = 25; + R10->r = 50; + + T8->pins[SCF_EDA_PNP_E]->flags = SCF_EDA_PIN_POS; + R1->pins[0]->flags = SCF_EDA_PIN_NEG; + + T8->pins[SCF_EDA_PNP_E]->ic_lid = SCF_EDA_OP_AMP_POS; + R1->pins[0]->ic_lid = SCF_EDA_OP_AMP_NEG; + + T1->pins[SCF_EDA_NPN_B]->flags = SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0; + T2->pins[SCF_EDA_NPN_B]->flags = SCF_EDA_PIN_IN; + R9->pins[0]->flags = SCF_EDA_PIN_OUT; + R1->pins[1]->flags = SCF_EDA_PIN_CF; + R2->pins[1]->flags = SCF_EDA_PIN_CF; + + T1->pins[SCF_EDA_NPN_B]->ic_lid = SCF_EDA_OP_AMP_IN; + T2->pins[SCF_EDA_NPN_B]->ic_lid = SCF_EDA_OP_AMP_INVERT; + R9->pins[0]->ic_lid = SCF_EDA_OP_AMP_OUT; + + int ret = ses_layout_function(f, 100); + if (ret < 0) + return ret; + + ses_draw(f, "op_amp_f007.png", f->x, f->y, f->w, f->h, 0, -1); + + long len = 0; + uint8_t* buf = NULL; + + ScfEfunction_pack(f, &buf, &len); + ScfEfunction_free(f); + f = NULL; + + FILE* fp = fopen("./op_amp_f007.cpk", "wb"); + if (!fp) + return -EINVAL; + + fwrite(buf, len, 1, fp); + fclose(fp); + return 0; +} diff --git a/cpk/op_amp_f007.cpk b/cpk/op_amp_f007.cpk new file mode 100644 index 0000000..b22a55d Binary files /dev/null and b/cpk/op_amp_f007.cpk differ diff --git a/cpk/ttl_adc.cpk b/cpk/ttl_adc.cpk index 5a9309f..763b3b5 100644 Binary files a/cpk/ttl_adc.cpk and b/cpk/ttl_adc.cpk differ diff --git a/cpk/ttl_add.cpk b/cpk/ttl_add.cpk index a7d9303..f51d352 100644 Binary files a/cpk/ttl_add.cpk and b/cpk/ttl_add.cpk differ diff --git a/cpk/ttl_and.cpk b/cpk/ttl_and.cpk index 79e34d1..e64b182 100644 Binary files a/cpk/ttl_and.cpk and b/cpk/ttl_and.cpk differ diff --git a/cpk/ttl_and2_or.cpk b/cpk/ttl_and2_or.cpk index c47586d..d13df3d 100644 Binary files a/cpk/ttl_and2_or.cpk and b/cpk/ttl_and2_or.cpk differ diff --git a/cpk/ttl_dff.cpk b/cpk/ttl_dff.cpk index 7bbdaaf..b2d9cde 100644 Binary files a/cpk/ttl_dff.cpk and b/cpk/ttl_dff.cpk differ diff --git a/cpk/ttl_if.cpk b/cpk/ttl_if.cpk index 3702fea..0f7da17 100644 Binary files a/cpk/ttl_if.cpk and b/cpk/ttl_if.cpk differ diff --git a/cpk/ttl_mla.cpk b/cpk/ttl_mla.cpk index 6a52c05..7ea1d6a 100644 Binary files a/cpk/ttl_mla.cpk and b/cpk/ttl_mla.cpk differ diff --git a/cpk/ttl_nand.cpk b/cpk/ttl_nand.cpk index 7d2b4e5..9bfc998 100644 Binary files a/cpk/ttl_nand.cpk and b/cpk/ttl_nand.cpk differ diff --git a/cpk/ttl_nand4.cpk b/cpk/ttl_nand4.cpk index d391577..e6f60fc 100644 Binary files a/cpk/ttl_nand4.cpk and b/cpk/ttl_nand4.cpk differ diff --git a/cpk/ttl_nand_gate.c b/cpk/ttl_nand_gate.c deleted file mode 100644 index d21b936..0000000 --- a/cpk/ttl_nand_gate.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include -#include"ses_core.h" - -int main(int argc, char* argv[]) -{ - ScfEcomponent* B; - - ScfEcomponent* NAND; - ScfEcomponent* R; - ScfEfunction* f; - ScfEboard* b; - - b = scf_eboard__alloc(); - f = scf_efunction__alloc("ttl_nand_gate"); - - EDA_INST_ADD_COMPONENT(f, B, SCF_EDA_Battery); - EDA_INST_ADD_COMPONENT(f, R, SCF_EDA_Resistor); - EDA_INST_ADD_COMPONENT(f, NAND, SCF_EDA_NAND); - - NAND->model = SCF_EDA_NAND_TTL; - - B->pins[SCF_EDA_Battery_NEG]->flags = SCF_EDA_PIN_NEG; - B->pins[SCF_EDA_Battery_POS]->flags = SCF_EDA_PIN_POS; - - EDA_PIN_ADD_PIN(B, SCF_EDA_Battery_POS, NAND, SCF_EDA_NAND_POS); - EDA_PIN_ADD_PIN(B, SCF_EDA_Battery_NEG, NAND, SCF_EDA_NAND_NEG); - EDA_PIN_ADD_PIN(R, 1, NAND, SCF_EDA_NAND_OUT); - EDA_PIN_ADD_PIN(R, 0, B, SCF_EDA_Battery_NEG); - - NAND->pins[SCF_EDA_NAND_IN0]->flags = SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0; - NAND->pins[SCF_EDA_NAND_IN1]->flags = SCF_EDA_PIN_IN; - - NAND->pins[SCF_EDA_NAND_OUT]->flags = SCF_EDA_PIN_OUT; - - scf_eboard__add_function(b, f); - - long len = 0; - uint8_t* buf = NULL; - - ScfEboard_pack(b, &buf, &len); - ScfEboard_free(b); - b = NULL; - - FILE* fp = fopen("./ttl_nand_gate.cpk", "wb"); - if (!fp) - return -EINVAL; - - fwrite(buf, len, 1, fp); - fclose(fp); - return 0; -} diff --git a/cpk/ttl_nand_gate2.c b/cpk/ttl_nand_gate2.c deleted file mode 100644 index 8c13a20..0000000 --- a/cpk/ttl_nand_gate2.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#include -#include"ses_core.h" - -int main(int argc, char* argv[]) -{ - ScfEcomponent* R1; - ScfEcomponent* R2; - ScfEcomponent* R3; - ScfEcomponent* R4; - - ScfEcomponent* D10; - ScfEcomponent* D11; - ScfEcomponent* D12; - ScfEcomponent* T2; - ScfEcomponent* D3; - ScfEcomponent* T4; - ScfEcomponent* T5; - ScfEcomponent* C5; - - ScfEboard* b = scf_eboard__alloc(); - ScfEfunction* f = scf_efunction__alloc("ttl_nand.cpk"); - ScfEcomponent* B; - ScfEcomponent* RL; - - EDA_INST_ADD_COMPONENT(f, B, SCF_EDA_Battery); - EDA_INST_ADD_COMPONENT(f, RL, SCF_EDA_Resistor); - - EDA_INST_ADD_COMPONENT(f, R1, SCF_EDA_Resistor); - EDA_INST_ADD_COMPONENT(f, R2, SCF_EDA_Resistor); - EDA_INST_ADD_COMPONENT(f, R3, SCF_EDA_Resistor); - EDA_INST_ADD_COMPONENT(f, R4, SCF_EDA_Resistor); - - EDA_INST_ADD_COMPONENT(f, D10, SCF_EDA_Diode); - EDA_INST_ADD_COMPONENT(f, D11, SCF_EDA_Diode); - EDA_INST_ADD_COMPONENT(f, D12, SCF_EDA_Diode); - EDA_INST_ADD_COMPONENT(f, D3, SCF_EDA_Diode); - - EDA_INST_ADD_COMPONENT(f, T2, SCF_EDA_NPN); - EDA_INST_ADD_COMPONENT(f, T4, SCF_EDA_NPN); - EDA_INST_ADD_COMPONENT(f, T5, SCF_EDA_NPN); - EDA_INST_ADD_COMPONENT(f, C5, SCF_EDA_Capacitor); - - EDA_PIN_ADD_PIN(R1, 1, R2, 1); - EDA_PIN_ADD_PIN(R1, 1, R4, 1); - - EDA_PIN_ADD_PIN(R1, 0, D10, SCF_EDA_Diode_POS); - EDA_PIN_ADD_PIN(R1, 0, D11, SCF_EDA_Diode_POS); - EDA_PIN_ADD_PIN(R1, 0, D12, SCF_EDA_Diode_POS); - - EDA_PIN_ADD_PIN(D12, SCF_EDA_Diode_NEG, T2, SCF_EDA_NPN_B); - EDA_PIN_ADD_PIN(R2, 0, T2, SCF_EDA_NPN_C); - EDA_PIN_ADD_PIN(R3, 1, T2, SCF_EDA_NPN_E); - EDA_PIN_ADD_PIN(R3, 0, T5, SCF_EDA_NPN_E); - - EDA_PIN_ADD_PIN(R4, 0, T4, SCF_EDA_NPN_C); - EDA_PIN_ADD_PIN(T4, SCF_EDA_NPN_E, D3, SCF_EDA_Diode_POS); - EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_C, D3, SCF_EDA_Diode_NEG); - EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_B, R3, 1); - EDA_PIN_ADD_PIN(T4, SCF_EDA_NPN_B, R2, 0); - - EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_B, C5, 1); - EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_E, C5, 0); - - R1->r = 4000; - R2->r = 1600; - R3->r = 10 * 1000; - R4->r = 130; - C5->uf = 5e-6; - - EDA_PIN_ADD_PIN(R1, 1, B, SCF_EDA_Battery_POS); - EDA_PIN_ADD_PIN(R3, 0, B, SCF_EDA_Battery_NEG); - - EDA_PIN_ADD_PIN(RL, 1, D3, SCF_EDA_Diode_NEG); - EDA_PIN_ADD_PIN(RL, 0, B, SCF_EDA_Battery_NEG); - - D10->pins[SCF_EDA_Diode_NEG]->flags = SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0; - D11->pins[SCF_EDA_Diode_NEG]->flags = SCF_EDA_PIN_IN; - D3 ->pins[SCF_EDA_Diode_NEG]->flags = SCF_EDA_PIN_OUT; - - B->pins[SCF_EDA_Battery_NEG]->flags = SCF_EDA_PIN_NEG; - B->pins[SCF_EDA_Battery_POS]->flags = SCF_EDA_PIN_POS; - - scf_eboard__add_function(b, f); - - long len = 0; - uint8_t* buf = NULL; - - ScfEboard_pack(b, &buf, &len); - ScfEboard_free(b); - b = NULL; - - FILE* fp = fopen("./ttl_nand_gate2.cpk", "wb"); - if (!fp) - return -EINVAL; - - fwrite(buf, len, 1, fp); - fclose(fp); - return 0; -} diff --git a/cpk/ttl_nor.cpk b/cpk/ttl_nor.cpk index 8bda7ad..cd7c793 100644 Binary files a/cpk/ttl_nor.cpk and b/cpk/ttl_nor.cpk differ diff --git a/cpk/ttl_not.cpk b/cpk/ttl_not.cpk index df32588..1259513 100644 Binary files a/cpk/ttl_not.cpk and b/cpk/ttl_not.cpk differ diff --git a/cpk/ttl_not_delay.cpk b/cpk/ttl_not_delay.cpk index ec34e09..4f52ff9 100644 Binary files a/cpk/ttl_not_delay.cpk and b/cpk/ttl_not_delay.cpk differ diff --git a/cpk/ttl_or.cpk b/cpk/ttl_or.cpk index e5a4844..d3f4e42 100644 Binary files a/cpk/ttl_or.cpk and b/cpk/ttl_or.cpk differ diff --git a/cpk/ttl_xor.cpk b/cpk/ttl_xor.cpk index 77836ea..fe1f6b9 100644 Binary files a/cpk/ttl_xor.cpk and b/cpk/ttl_xor.cpk differ diff --git a/examples/astable_multivibrator.cpk b/examples/astable_multivibrator.cpk index 94e41bd..c47628b 100644 Binary files a/examples/astable_multivibrator.cpk and b/examples/astable_multivibrator.cpk differ diff --git a/examples/colpitts_oscillator.cpk b/examples/colpitts_oscillator.cpk index 54f244d..9025e89 100644 Binary files a/examples/colpitts_oscillator.cpk and b/examples/colpitts_oscillator.cpk differ diff --git a/examples/pnp_oscillator.cpk b/examples/pnp_oscillator.cpk index 6fac797..68f5366 100644 Binary files a/examples/pnp_oscillator.cpk and b/examples/pnp_oscillator.cpk differ diff --git a/examples/sin_oscillator.cpk b/examples/sin_oscillator.cpk index 68a1061..8b028b9 100644 Binary files a/examples/sin_oscillator.cpk and b/examples/sin_oscillator.cpk differ diff --git a/main.c b/main.c index 1af12ec..fad0988 100644 --- a/main.c +++ b/main.c @@ -43,11 +43,12 @@ int ses_va_curve(ScfEcomponent* c, const char* txt) if (!fp) return -EINVAL; - double d = 0.0; - double v = 0.0; - double a = 0.0; + double v[2] = {0.0}; + double a = 0.0; + double d = 0.0; double base = 0.1; - int dot = 0; + int dot = 0; + int i = 0; while (1) { int ch = fgetc(fp); @@ -88,12 +89,13 @@ int ses_va_curve(ScfEcomponent* c, const char* txt) return ret; } - curve->v = v; - curve->a = a; - curve->hfe = d; + curve->Vb = v[0]; + curve->Ib = a; + curve->Vc = v[1]; - scf_logd("curve v: %lg, a: %lg, hfe: %lg, R: %lg\n", v, a, d, v / a); + scf_logd("curve Vb: %lg, Ia: %lg, Vc: %lg, R: %lg\n", v[0], a, v[1], v[0] / a); + i = 0; d = 0.0; dot = 0; base = 0.1; @@ -123,8 +125,9 @@ int ses_va_curve(ScfEcomponent* c, const char* txt) break; case 'V': - v = d; + v[i] = d; d = 0.0; + i = (i + 1) & 0x1; break; case 'A': @@ -292,7 +295,7 @@ int main(int argc, char* argv[]) f = b->functions[i]; printf("f: %s\n", f->name); - ses_steps_analyse(f, 100LL, 1); + ses_steps_analyse(f, 1000LL * 1000LL, 1); } ScfEboard_free(b); diff --git a/scf_eda_pack.c b/scf_eda_pack.c index 3529462..9893847 100644 --- a/scf_eda_pack.c +++ b/scf_eda_pack.c @@ -446,7 +446,7 @@ static ScfEdata component_datas[] = {SCF_EDA_NOT, SCF_EDA_TTL_DELAY, 0, 0, 0, 0, 0, 0, 0, &__ttl_not_ops, "./cpk/ttl_not_delay.cpk", NULL}, - {SCF_EDA_OP_AMP, 0, 0, 0, 0, 0, 0, 0, 0, &__741_op_amp_ops, "./cpk/op_amp_741.cpk", NULL}, + {SCF_EDA_OP_AMP, 0, 0, 0, 0, 0, 0, 0, 0, &__741_op_amp_ops, "./cpk/op_amp_f007.cpk", NULL}, }; static ScfEdata pin_datas[] = @@ -456,10 +456,10 @@ static ScfEdata pin_datas[] = {SCF_EDA_Diode, 0, SCF_EDA_Diode_NEG, 0, 0, 750, 0, 0, 0, NULL, NULL, NULL}, {SCF_EDA_NPN, 0, SCF_EDA_NPN_B, 0, 0, 750, 0, 0, 0, NULL, NULL, NULL}, - {SCF_EDA_NPN, 0, SCF_EDA_NPN_C, 0, 0, 3, 0, 0, 150, NULL, NULL, NULL}, + {SCF_EDA_NPN, 0, SCF_EDA_NPN_C, 0, 0, 3, 0, 0, 200, NULL, NULL, NULL}, {SCF_EDA_PNP, 0, SCF_EDA_PNP_B, 0, 0, 750, 0, 0, 0, NULL, NULL, NULL}, - {SCF_EDA_PNP, 0, SCF_EDA_PNP_C, 0, 0, 3, 0, 0, 150, NULL, NULL, NULL}, + {SCF_EDA_PNP, 0, SCF_EDA_PNP_C, 0, 0, 3, 0, 0, 200, NULL, NULL, NULL}, }; static ScfEdata* _pin_find_data(const uint64_t type, const uint64_t model, const uint64_t pid) @@ -786,7 +786,8 @@ ScfEcomponent* scf_ecomponent__alloc(uint64_t type) if (!c) return NULL; - c->type = type; + c->type = type; + c->mirror_id = -1; ed = scf_ecomponent__find_data(c->type, c->model); if (ed) { diff --git a/scf_eda_pack.h b/scf_eda_pack.h index f4d1581..689c3d8 100644 --- a/scf_eda_pack.h +++ b/scf_eda_pack.h @@ -309,15 +309,15 @@ SCF_PACK_INFO_VAR(ScfLine, y1), SCF_PACK_END(ScfLine) typedef struct { - SCF_PACK_DEF_VAR(double, v); - SCF_PACK_DEF_VAR(double, a); - SCF_PACK_DEF_VAR(double, hfe); + SCF_PACK_DEF_VAR(double, Vb); + SCF_PACK_DEF_VAR(double, Ib); + SCF_PACK_DEF_VAR(double, Vc); } ScfEcurve; SCF_PACK_TYPE(ScfEcurve) -SCF_PACK_INFO_VAR(ScfEcurve, v), -SCF_PACK_INFO_VAR(ScfEcurve, a), -SCF_PACK_INFO_VAR(ScfEcurve, hfe), +SCF_PACK_INFO_VAR(ScfEcurve, Vb), +SCF_PACK_INFO_VAR(ScfEcurve, Ib), +SCF_PACK_INFO_VAR(ScfEcurve, Vc), SCF_PACK_END(ScfEcurve) typedef struct scf_eops_s ScfEops; @@ -480,6 +480,7 @@ struct scf_ecomponent_s SCF_PACK_DEF_VAR(double, uf); SCF_PACK_DEF_VAR(double, uh); + SCF_PACK_DEF_VAR(int64_t, mirror_id); SCF_PACK_DEF_VAR(int64_t, count); SCF_PACK_DEF_VAR(int64_t, color); @@ -508,6 +509,8 @@ SCF_PACK_INFO_VAR(ScfEcomponent, r), SCF_PACK_INFO_VAR(ScfEcomponent, uf), SCF_PACK_INFO_VAR(ScfEcomponent, uh), +SCF_PACK_INFO_VAR(ScfEcomponent, mirror_id), + SCF_PACK_INFO_VAR(ScfEcomponent, count), SCF_PACK_INFO_VAR(ScfEcomponent, color), SCF_PACK_INFO_VAR(ScfEcomponent, status), @@ -629,6 +632,11 @@ int scf_pins_same_line(ScfEfunction* f); #define EDA_PIN_ADD_PIN_EF(_ef, _p0, _p1) \ EDA_PIN_ADD_PIN((_ef)->components[(_p0)->cid], (_p0)->id, (_ef)->components[(_p1)->cid], (_p1)->id) +#define EDA_SET_MIRROR(_c0, _c1) \ + do { \ + (_c0)->mirror_id = (_c1)->id; \ + (_c1)->mirror_id = (_c0)->id; \ + } while (0) static char* component_types[SCF_EDA_Components_NB] = { diff --git a/ses_core.h b/ses_core.h index ec5a8e4..bc587d3 100644 --- a/ses_core.h +++ b/ses_core.h @@ -68,6 +68,8 @@ struct ses_edge_s ses_node_t* node1; ses_edge_t* edge_b; + ses_edge_t* edge_c; + ses_edge_t* mirror; double hfe; double cv; @@ -80,8 +82,11 @@ struct ses_edge_s int index; uint8_t bflag:1; + uint8_t vflag:1; + uint8_t cut_off_flag:1; uint8_t amplify_flag:1; + uint8_t update_flag:1; }; struct ses_node_s diff --git a/ses_node_analysis.c b/ses_node_analysis.c index d0d2310..86c913b 100644 --- a/ses_node_analysis.c +++ b/ses_node_analysis.c @@ -39,8 +39,9 @@ ses_edge_t* ses_edges_find_edge_by_pin(scf_vector_t* edges, ScfEpin* vip) static int __ses_edges_path(ses_path_t* path, int vip_m, int vip_n, scf_vector_t* edges) { - ses_edge_t* edge = NULL; - ses_edge_t* edge2 = NULL; + ses_edge_t* edge = NULL; + ses_edge_t* edge2 = NULL; + ses_edge_t* mirror = NULL; ScfEcomponent* c; ScfEcomponent* c2; @@ -73,9 +74,15 @@ static int __ses_edges_path(ses_path_t* path, int vip_m, int vip_n, scf_vector_t bflag = 1; edge2 = ses_edges_find_edge_by_pin(edges, c->pins[SCF_EDA_NPN_C]); - } else if (SCF_EDA_NPN_C == p->id) + } else if (SCF_EDA_NPN_C == p->id) { edge2 = ses_edges_find_edge_by_pin(edges, c->pins[SCF_EDA_NPN_B]); + if (c->mirror_id >= 0) { + c2 = c->pf->components[c->mirror_id]; + + mirror = ses_edges_find_edge_by_pin(edges, c2->pins[SCF_EDA_NPN_C]); + } + } case SCF_EDA_Diode: if (SCF_EDA_Diode == c->type) bflag = 1; @@ -85,20 +92,8 @@ static int __ses_edges_path(ses_path_t* path, int vip_m, int vip_n, scf_vector_t node_flag = 1; break; default: - if (i - 1 >= vip_m) { - p2 = path->pins->data[i - 1]; - c2 = p2->c; - - switch (c2->type) { - case SCF_EDA_Diode: - case SCF_EDA_Capacitor: - case SCF_EDA_Inductor: - node_flag = 1; - break; - default: - break; - }; - } + if (i - 1 >= vip_m) + node_flag = 1; break; }; @@ -125,16 +120,24 @@ static int __ses_edges_path(ses_path_t* path, int vip_m, int vip_n, scf_vector_t if (edge2) { if (edge ->bflag) { + edge ->edge_c = edge2; edge2->edge_b = edge; edge2->hfe = c->pins[SCF_EDA_NPN_C]->hfe; } else { assert(edge2->bflag); - edge->edge_b = edge2; - edge->hfe = c->pins[SCF_EDA_NPN_C]->hfe; + edge2->edge_c = edge; + edge ->edge_b = edge2; + edge ->hfe = c->pins[SCF_EDA_NPN_C]->hfe; } edge2 = NULL; } + if (mirror) { + edge ->mirror = mirror; + mirror->mirror = edge; + mirror = NULL; + } + node_flag = 0; j = i - 1; @@ -402,7 +405,7 @@ static void __ses_Vb_by_curve(ScfEcomponent* c, double Ib, double* V) { int i; for (i = 0; i < c->n_curves; i++) { - if (Ib < c->curves[i]->a) + if (Ib < c->curves[i]->Ib) break; } @@ -413,23 +416,23 @@ static void __ses_Vb_by_curve(ScfEcomponent* c, double Ib, double* V) double R; if (0 == i) { - V1 = c->curves[i]->v; - A1 = c->curves[i]->a; + V1 = c->curves[i]->Vb; + A1 = c->curves[i]->Ib; R = V1 / Ib; *V = V1; } else if (i >= c->n_curves) { assert(2 <= c->n_curves); - V1 = c->curves[c->n_curves - 1]->v; - A1 = c->curves[c->n_curves - 1]->a; + V1 = c->curves[c->n_curves - 1]->Vb; + A1 = c->curves[c->n_curves - 1]->Ib; R = V1 / Ib; *V = V1; } else { - V0 = c->curves[i - 1]->v; - A0 = c->curves[i - 1]->a; - V1 = c->curves[i]->v; - A1 = c->curves[i]->a; + V0 = c->curves[i - 1]->Vb; + A0 = c->curves[i - 1]->Ib; + V1 = c->curves[i]->Vb; + A1 = c->curves[i]->Ib; R = (V1 - V0) / (A1 - A0); *V = V0 + R * (Ib - A0); } @@ -437,13 +440,105 @@ static void __ses_Vb_by_curve(ScfEcomponent* c, double Ib, double* V) scf_logd("i: %d, n_curves: %ld, Ib: %lg, R: %lg, V: %lg\n", i, c->n_curves, Ib, R, *V); } +static int __ses_edges_inverse_off(ScfEfunction* f, scf_vector_t* edges, double* A, double* b, double* X, int N) +{ + ses_edge_t* edge; + + ScfEcomponent* c; + ScfEpin* p0; + ScfEpin* p1; + + int n = N - edges->size; + int k = 0; + int i; + int j; + + for (j = 0; j < edges->size; j++) { + edge = edges->data[j]; + + if (!edge->bflag) + continue; + + p0 = edge->path->pins->data[edge->vip_m]; + p1 = edge->path->pins->data[edge->vip_n]; + c = p0->c; + + if (SCF_EDA_Diode != c->type) + continue; + + double Vb; + double Ve; + if (edge->node1 && !edge->node1->el->vconst) + Vb = X[edge->node1->index]; + else + Vb = ses_top_pline(p0)->v; + + if (edge->node0 && !edge->node0->el->vconst) + Ve = X[edge->node0->index]; + else + Ve = ses_top_pline(p1)->v; + + double dV = Vb - Ve; + double Ib = X[n + edge->index]; + + if (dV < -SCF_EDA_V_Diode_OFF / 2) { + if (!edge->cut_off_flag) { + edge->cut_off_flag = 1; + + c->status = SCF_EDA_Status_OFF; + + for (i = 0; i < N; i++) + A[(n + edge->index) * N + i] = 0; + + A[(n + edge->index) * N + n + edge->index] = -1; + b[ n + edge->index] = 0; + k++; +#if 1 + scf_logi("\033[31medge: [%d], ", edge->index); + ses_pin_print(p0); + printf("status: %d, dV: %lg, Vb: %lg, Ve: %lg, Ib: %lg\033[0m\n", c->status, dV, Vb, Ve, Ib); +#endif + } + } else if (dV > SCF_EDA_V_Diode_OFF) { + if (edge->cut_off_flag) { + edge->cut_off_flag = 0; + + c->status = SCF_EDA_Status_ON; + + b[ n + edge->index] = 0; + A[(n + edge->index) * N + n + edge->index] = -edge->r; + + if (edge->node0 && !edge->node0->el->vconst) + A[(n + edge->index) * N + edge->node0->index] = -1; + else + b[n + edge->index] += ses_top_pline(p1)->v; + + if (edge->node1 && !edge->node1->el->vconst) + A[(n + edge->index) * N + edge->node1->index] = 1; + else + b[n + edge->index] -= ses_top_pline(p0)->v; +#if 1 + scf_logi("\033[32medge: [%d], ", edge->index); + ses_pin_print(p0); + printf("status: %d, dV: %lg, Vb: %lg, Ve: %lg, Ib: %lg\033[0m\n", c->status, dV, Vb, Ve, Ib); +#endif + k++; + } + } + } + + return k; +} + static int __ses_edges_update_Ab(ScfEfunction* f, scf_vector_t* edges, double* A, double* b, double* X, int N, int* n_offs) { ses_edge_t* edge; ScfEcomponent* c; - ScfEcomponent* B = f->components[0]; - ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; + ScfEline* LP = ses_find_line_by_flag(f, SCF_EDA_PIN_POS); + ScfEline* LN = ses_find_line_by_flag(f, SCF_EDA_PIN_NEG); + ScfEline* L0 = ses_find_line_by_flag(f, SCF_EDA_PIN_GND); + ScfEline* el; ScfEpin* p0; ScfEpin* p1; ScfEpin* p; @@ -485,8 +580,8 @@ static int __ses_edges_update_Ab(ScfEfunction* f, scf_vector_t* edges, double* A } #endif if (-1e8 < Rb && Rb < 1e8) { - if (dV < V * 0.99 || dV > V * 1.01) { -#if 0 + if ((dV < V * 0.98 || dV > V * 1.02) && SCF_EDA_Status_ON == c->status) { +#if 1 scf_logi("edge: [%d], ", edge->index); ses_pin_print(p0); printf("status: %d, dV: %lg, Vb: %lg, Ve: %lg, V: %lg, Ib: %lg, Rb: %lg\n", c->status, dV, Vb, Ve, V, Ib, Rb); @@ -502,12 +597,14 @@ static int __ses_edges_update_Ab(ScfEfunction* f, scf_vector_t* edges, double* A #endif } } else { - if (dV < SCF_EDA_V_NPN_OFF && Ve < Bp->v - SCF_EDA_V_NPN_OFF) { + if (dV < SCF_EDA_V_NPN_OFF + && (!c->pf->IC || SCF_EDA_OP_AMP != c->pf->IC->type) + && (Ve < LP->v - SCF_EDA_V_NPN_OFF && Vb > LN->v + SCF_EDA_V_NPN_OFF)) { c->status = SCF_EDA_Status_OFF; c->lock = 2; (*n_offs)++; } -#if 1 +#if 0 scf_logi("\033[34medge: [%d], ", edge->index); ses_pin_print(p0); printf("status: %d, dV: %lg, Vb: %lg, Ve: %lg, V: %lg, Ib: %lg, Rb: %lg\033[0m\n", c->status, dV, Vb, Ve, V, Ib, Rb); @@ -539,12 +636,7 @@ static int __ses_edges_update_Ab(ScfEfunction* f, scf_vector_t* edges, double* A if (dI < -1e-10 && -1e8 < Rb && Rb < 1e8) { if (!edge->amplify_flag) { edge->amplify_flag = 1; -#if 0 - scf_logi("edge: [%d], ", edge->index); - ses_pin_print(p0); - ses_pin_print(p1); - printf("[b%d], Ic: %lg, Ib: %lg, dI: %lg, Vbe: %lg, Vce: %lg, Vc: %lg, Ve: %lg, Rb: %lg\n", edge->edge_b->index, Ic, Ib, dI, Vb - Ve, Vc - Ve, Vc, Ve, Rb); -#endif + for (i = 0; i < N; i++) A[(n + edge->index) * N + i] = 0; @@ -560,28 +652,193 @@ static int __ses_edges_update_Ab(ScfEfunction* f, scf_vector_t* edges, double* A return k; } -static int __ses_nodes_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* edges, int* changed, int64_t ps, int64_t count) +static void ses_edge_hfe_print(ses_edge_t* edge, double hfe, double* X, int n, double alpha) +{ + ScfEpin* p0 = edge->path->pins->data[edge->vip_m]; + ScfEpin* p1 = edge->path->pins->data[edge->vip_n]; + + double Ic = X[n + edge->index]; + double Vc; + double Ve; + if (edge->node1 && !edge->node1->el->vconst) + Vc = X[edge->node1->index]; + else + Vc = ses_top_pline(p0)->v; + + if (edge->node0 && !edge->node0->el->vconst) + Ve = X[edge->node0->index]; + else + Ve = ses_top_pline(p1)->v; + + scf_logi("\033[33medge: [%d], ", edge->index); + ses_pin_print(p0); + ses_pin_print(p1); + printf("Vc: %lg, Ve: %lg, Vce: %lg, Ic: %lg, hfe: %lg, alpha: %lg\033[0m\n", Vc, Ve, Vc - Ve, Ic, hfe, alpha); +} + +static int __edge_update_hfe(ses_edge_t* edge, double* A, double* X, int N, int n, double alpha) +{ + assert(edge->edge_b); + + int k = 0; + double hfe = A[(n + edge->index) * N + n + edge->edge_b->index] * alpha; + + if (hfe > 1e-4 && hfe < 250) { + if (!edge->update_flag) { + edge ->update_flag = 1; + + A[(n + edge->index) * N + n + edge->edge_b->index] = hfe; + + ses_edge_hfe_print(edge, hfe, X, n, alpha); + k++; + } + + if (edge->mirror && edge->mirror->amplify_flag && !edge->mirror->update_flag) { + edge->mirror->update_flag = 1; + + A[(n + edge->mirror->index) * N + n + edge->mirror->edge_b->index] = hfe; + + ses_edge_hfe_print(edge->mirror, hfe, X, n, alpha); + k++; + } + + if (k > 0) + printf("\n"); + } + return k; +} + +static int __edge_update_hfe_in(ses_edge_t* edge, double* A, double* X, int N, int n) +{ + if (!edge->node1) + return 0; + + ses_edge_t* in; + int i; + int k = 0; + + for (i = 0; i < edge->node1->edges->size; i++) { + in = edge->node1->edges->data[i]; + + if (in->node0 != edge->node1) + continue; + + if (in->vflag) + continue; + in->vflag = 1; + + if (in->edge_b && in->amplify_flag && !in->update_flag) + k += __edge_update_hfe(in, A, X, N, n, 0.95); + + if (in->node1) + k += __edge_update_hfe_in(in, A, X, N, n); + } + return k; +} + +static int __edge_update_hfe_out(ses_edge_t* edge, double* A, double* X, int N, int n) +{ + if (!edge->node0) + return 0; + + ses_edge_t* out; + int i; + int k = 0; + + for (i = 0; i < edge->node0->edges->size; i++) { + out = edge->node0->edges->data[i]; + + if (out->node1 != edge->node0) + continue; + + if (out->vflag) + continue; + out->vflag = 1; + + if (out->edge_b && out->amplify_flag && !out->update_flag) + k += __edge_update_hfe(out, A, X, N, n, 0.95); + + if (out->node0) + k += __edge_update_hfe_out(out, A, X, N, n); + } + return k; +} + +static int __ses_edges_update_hfe(ScfEfunction* f, scf_vector_t* edges, double* A, double* b, double* X, int N) { - ses_node_t* node; ses_edge_t* edge; ScfEcomponent* c; + ScfEline* LP = ses_find_line_by_flag(f, SCF_EDA_PIN_POS); + ScfEline* LN = ses_find_line_by_flag(f, SCF_EDA_PIN_NEG); + ScfEline* L0 = ses_find_line_by_flag(f, SCF_EDA_PIN_GND); ScfEpin* p0; ScfEpin* p1; - ScfEline* el; - int ret = 0; - int i; + int n = N - edges->size; + int k = 0; int j; - int m = edges->size; - int n = nodes->size; - int N = n + m; + for (j = 0; j < edges->size; j++) { + edge = edges->data[j]; - double* A = calloc(N * N + N + N + (N + N + N * N + N * N), sizeof(double)); - if (!A) - return -ENOMEM; + edge->update_flag = 0; + edge->vflag = 0; + } + + for (j = 0; j < edges->size; j++) { + edge = edges->data[j]; + + if (!edge->edge_b) + continue; + + p0 = edge->path->pins->data[edge->vip_m]; + p1 = edge->path->pins->data[edge->vip_n]; + c = p0->c; + + double Ib = X[n + edge->edge_b->index]; + double Ic = X[n + edge->index]; + double Vc; + double Ve; + if (edge->node1 && !edge->node1->el->vconst) + Vc = X[edge->node1->index]; + else + Vc = ses_top_pline(p0)->v; + + if (edge->node0 && !edge->node0->el->vconst) + Ve = X[edge->node0->index]; + else + Ve = ses_top_pline(p1)->v; + + if (edge->amplify_flag) { + if (Vc < Ve) + k += __edge_update_hfe(edge, A, X, N, n, 0.95); + if (Vc > LP->v || Vc < LN->v) + k += __edge_update_hfe(edge, A, X, N, n, 0.95); + + if (Ve > LP->v || Ve < LN->v) + k += __edge_update_hfe(edge, A, X, N, n, 1.02); + + } else if (Ic > Ib * edge->hfe) { + edge->amplify_flag = 1; + + int i; + for (i = 0; i < N; i++) + A[(n + edge->index) * N + i] = 0; + + A[(n + edge->index) * N + n + edge->index] = -1; + A[(n + edge->index) * N + n + edge->edge_b->index] = edge->hfe; + b[ n + edge->index] = 0; + k++; + } + } + + return k; +} + +static int __ses_try_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* edges, int* changed, double* A, int N, int n) +{ double* b = A + N * N; double* X = b + N; double* W = X + N; @@ -589,8 +846,6 @@ static int __ses_nodes_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* double* V = S + N; double* U = V + N * N; - __ses_nodes_set_Ab(f, nodes, edges, ps, A, b, N); - gsl_matrix_view _A = gsl_matrix_view_array(U, N, N); gsl_vector_view _b = gsl_vector_view_array(b, N); gsl_vector_view _X = gsl_vector_view_array(X, N); @@ -599,12 +854,11 @@ static int __ses_nodes_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* gsl_vector_view _S = gsl_vector_view_array(S, N); gsl_matrix_view _V = gsl_matrix_view_array(V, N, N); - int n_offs = 0; + int ret = 0; + int j; -#define MAX_TRYS 10000 - int try = 0; - do { - n_offs = 0; + for (j = 0; j < 20; j++) { + int n_offs = 0; memcpy(U, A, sizeof(double) * N * N); @@ -612,10 +866,13 @@ static int __ses_nodes_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* gsl_linalg_SV_solve (&_A.matrix, &_V.matrix, &_S.vector, &_b.vector, &_X.vector); ret = __ses_edges_update_Ab(f, edges, A, b, X, N, &n_offs); - try++; - scf_logi("ret: %d, try: %d, n_offs: %d\n\n", ret, try, n_offs); + scf_logi("j: %d, ret: %d, n_offs: %d\n\n", j, ret, n_offs); + ses_node_t* node; + ScfEline* el; + + int i; for (i = 0; i < n; i++) { node = nodes->data[i]; el = node->el; @@ -626,15 +883,68 @@ static int __ses_nodes_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* if (n_offs > 0) { *changed += n_offs; - break; +// break; } - } while (ret > 0 && try < MAX_TRYS); - if (try >= MAX_TRYS) { - free(A); - return -1; + if (0 == ret) + break; } + return ret; +} + +static int __ses_nodes_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* edges, int* changed, int64_t ps, int64_t count) +{ + ses_node_t* node; + ses_edge_t* edge; + + ScfEcomponent* c; + ScfEline* LP = ses_find_line_by_flag(f, SCF_EDA_PIN_POS); + ScfEline* LN = ses_find_line_by_flag(f, SCF_EDA_PIN_NEG); + ScfEline* L0 = ses_find_line_by_flag(f, SCF_EDA_PIN_GND); + ScfEline* el; + ScfEpin* p0; + ScfEpin* p1; + + int ret = 0; + int i; + int j; + + int m = edges->size; + int n = nodes->size; + int N = n + m; + + double* A = calloc(N * N + N + N + (N + N + N * N + N * N), sizeof(double)); + if (!A) + return -ENOMEM; + + double* b = A + N * N; + double* X = b + N; + + __ses_nodes_set_Ab(f, nodes, edges, ps, A, b, N); + +#define MAX_TRYS 500 + int try = 0; + do { + ret = __ses_try_solve(f, nodes, edges, changed, A, N, n); + + i = __ses_edges_update_hfe(f, edges, A, b, X, N); + + if (0 == i) + j = __ses_edges_inverse_off(f, edges, A, b, X, N); + + scf_logi("try: %d, ret: %d, i: %d, j: %d\n", try, ret, i, j); + + ret += i; + ret += j; + try++; + + } while (ret > 0 && try < MAX_TRYS); + + if (try >= MAX_TRYS) + scf_loge("try: %d\n", try); + else + scf_logi("try: %d\n", try); // ses_AbX_print(A, b, X, N); for (j = 0; j < edges->size; j++) { @@ -666,7 +976,10 @@ static int __ses_nodes_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* printf(", v: %lg, %lg, a: %lg, edge->index: %d\n", p0->v, p1->v, edge->a, edge->index); #endif if (SCF_EDA_NPN == c->type) { - if (SCF_EDA_NPN_B == p0->id && edge->a < -1e-4) { + if (SCF_EDA_NPN_B == p0->id + && edge->a < -1e-4 + && ses_top_pline(p0) != L0 + && (!c->pf->IC || SCF_EDA_OP_AMP != c->pf->IC->type)) { c->status = SCF_EDA_Status_OFF; c->lock = 2; (*changed)++; @@ -677,7 +990,10 @@ static int __ses_nodes_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* continue; } else if (SCF_EDA_PNP == c->type) { - if (SCF_EDA_PNP_B == p1->id && edge->a < -1e-4) { + if (SCF_EDA_PNP_B == p1->id + && edge->a < -1e-4 + && ses_top_pline(p1) != L0 + && (!c->pf->IC || SCF_EDA_OP_AMP != c->pf->IC->type)) { c->status = SCF_EDA_Status_OFF; c->lock = 2; (*changed)++; @@ -688,7 +1004,8 @@ static int __ses_nodes_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* continue; } else if (SCF_EDA_Diode == c->type) { - if (edge->a < -1e-4) { + if (edge->a < -1e-4 + && (!c->pf->IC || SCF_EDA_OP_AMP != c->pf->IC->type)) { c->status = SCF_EDA_Status_OFF; c->lock = 2; (*changed)++; @@ -696,32 +1013,25 @@ static int __ses_nodes_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* c->a = edge->a; continue; + } - } else if (SCF_EDA_Inductor == c->type) { - int sign = p0->id - !p0->id; + int sign = p0->id - !p0->id; + + if (SCF_EDA_Inductor == c->type) { c->v = (edge->a * sign - c->a) * c->uh * 1000000.0 / ps; - c->a = edge->a * sign; - p0->a = edge->a; - p1->a = edge->a; - continue; } else if (SCF_EDA_Capacitor == c->type) { - int sign = p0->id - !p0->id; - c->v += edge->a * sign * ps / 1000000.0 / c->uf; - c->a = edge->a * sign; - p0->a = edge->a; - p1->a = edge->a; - continue; + if (!c->pf->IC || SCF_EDA_OP_AMP != c->pf->IC->type) + c->v += edge->a * sign * ps / 1000000.0 / c->uf; } - ret = __ses_path_va_branch(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ps, count); - if (ret < 0) - goto error; + c->a = edge->a * sign; + p0->a = edge->a; + p1->a = edge->a; } -error: free(A); return ret; } @@ -755,30 +1065,22 @@ static int __ses_nodes_split(scf_vector_t* groups, scf_vector_t* nodes, scf_vect for (j = 0; j < node->edges->size; j++) { edge = node->edges->data[j]; - - if (edge->node1 && !scf_vector_find(g->nodes, edge->node1)) { - edge->node1->index = g->nodes->size; - - ret = scf_vector_add(g->nodes, edge->node1); - if (ret < 0) { - ses_group_free(g); - return ret; - } - - assert(0 == scf_vector_del(nodes, edge->node1)); - } - - if (edge->node0 && !scf_vector_find(g->nodes, edge->node0)) { - edge->node0->index = g->nodes->size; - - ret = scf_vector_add_unique(g->nodes, edge->node0); - if (ret < 0) { - ses_group_free(g); - return ret; - } - - assert(0 == scf_vector_del(nodes, edge->node0)); - } +#define SPLIT_ADD_NODE(_node) \ + do { \ + if ((_node) && !scf_vector_find(g->nodes, (_node))) { \ + (_node)->index = g->nodes->size; \ + \ + ret = scf_vector_add(g->nodes, (_node)); \ + if (ret < 0) { \ + ses_group_free(g); \ + return ret; \ + } \ + assert(0 == scf_vector_del(nodes, (_node))); \ + } \ + } while (0) + + SPLIT_ADD_NODE(edge->node1); + SPLIT_ADD_NODE(edge->node0); if (!scf_vector_find(g->edges, edge)) { edge->index = g->edges->size; @@ -790,6 +1092,15 @@ static int __ses_nodes_split(scf_vector_t* groups, scf_vector_t* nodes, scf_vect } assert(0 == scf_vector_del(edges, edge)); + + if (edge->edge_b) { + SPLIT_ADD_NODE(edge->edge_b->node1); + SPLIT_ADD_NODE(edge->edge_b->node0); + + } else if (edge->edge_c) { + SPLIT_ADD_NODE(edge->edge_c->node1); + SPLIT_ADD_NODE(edge->edge_c->node0); + } } } } diff --git a/ses_step_battery.c b/ses_step_battery.c index ddf5a82..e6388b7 100644 --- a/ses_step_battery.c +++ b/ses_step_battery.c @@ -20,7 +20,9 @@ static int _battery_handler(ScfEfunction* f, int64_t ps, int64_t count, ses_ctx_ if (SCF_EDA_Battery != c->type) continue; - c->v = 5; + + if (c->v <= 0) + c->v = 5; Bp = c->pins[SCF_EDA_Battery_POS]; Bn = c->pins[SCF_EDA_Battery_NEG]; @@ -53,6 +55,8 @@ static int _battery_handler(ScfEfunction* f, int64_t ps, int64_t count, ses_ctx_ LN->vconst = 1; + LP->flags |= SCF_EDA_PIN_GND; + } else if (LP->v - LN->v != c->v) { scf_loge("Battery '%lgV' connected between line '%lgV' and '%lgV', diff: %lgV\n", c->v, LP->v, LN->v, LP->v - LN->v); diff --git a/ses_step_dc_diode.c b/ses_step_dc_diode.c index 79df91e..1053142 100644 --- a/ses_step_dc_diode.c +++ b/ses_step_dc_diode.c @@ -1,35 +1,5 @@ #include"ses_core.h" -static void __dc_dfs_init(ScfEfunction* f, ScfEcomponent* IC) -{ - ScfEcomponent* c; - ScfEline* el; - ScfEline* parent; - ScfEpin* p; - - long i; - for (i = 0; i < f->n_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]; - continue; - } - } - - 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, ScfEline* LP, ScfEline* LN) { ScfEcomponent* c; @@ -71,28 +41,14 @@ static int __dc_diode_status(ScfEfunction* root, ScfEfunction* f, ScfEline* LP, if (neg && !pos) { c->status = SCF_EDA_Status_OFF; - - scf_logi("\033[34m status: %d, lock: %d, \033[0m", c->status, c->lock); - ses_pin_print(pb); - printf("\n"); - continue; + goto check; } - if (!neg && pos && SCF_EDA_Status_ON == c->status) { - // c->status = SCF_EDA_Status_OFF; - - scf_logi("\033[34m status: %d, lock: %d, \033[0m", c->status, c->lock); - ses_pin_print(pb); - printf("\n"); - continue; - } + if (!neg && pos && SCF_EDA_Status_ON == c->status) + goto check; - if (c->lock) { - scf_logi("\033[34m status: %d, lock: %d, \033[0m", c->status, c->lock); - ses_pin_print(pb); - printf("pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n", pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_Diode_OFF); - continue; - } + if (c->lock) + goto check; if (lb->v < SCF_EDA_V_MIN) { if (le->v < SCF_EDA_V_MIN) @@ -131,6 +87,14 @@ static int __dc_diode_status(ScfEfunction* root, ScfEfunction* f, ScfEline* LP, // c->status = SCF_EDA_Status_OFF; } +check: + if ((c->pf->IC && SCF_EDA_OP_AMP == c->pf->IC->type) + || pe->v >= LP->v - SCF_EDA_V_NPN_OFF + || pb->v <= LN->v + SCF_EDA_V_NPN_OFF) { + c->lock = 0; + c->status = SCF_EDA_Status_ON; + } + scf_logi("\033[34m status: %d, lock: %d, ", c->status, c->lock); ses_pin_print(pb); printf("pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_Diode_OFF); @@ -144,8 +108,6 @@ static int _dc_diode_handler(ScfEfunction* f, int64_t ps, int64_t count, ses_ctx ScfEline* LP = ses_find_line_by_flag(f, SCF_EDA_PIN_POS); ScfEline* LN = ses_find_line_by_flag(f, SCF_EDA_PIN_NEG); - __dc_dfs_init(f, NULL); - return __dc_diode_status(f, f, LP, LN); } diff --git a/ses_step_dc_input.c b/ses_step_dc_input.c index 0bea384..ea43f57 100644 --- a/ses_step_dc_input.c +++ b/ses_step_dc_input.c @@ -12,7 +12,7 @@ static int _dc_input_handler(ScfEfunction* f, int64_t ps, int64_t count, ses_ctx long j; int k; - int x[] = {0, 0, 0, 0, 0}; + int x[] = {1, 1, 0, 0, 0}; int y[] = {0, 1, 0, 1, 0}; B = f->components[0]; diff --git a/ses_step_dc_npn.c b/ses_step_dc_npn.c index 5974f39..3663ee8 100644 --- a/ses_step_dc_npn.c +++ b/ses_step_dc_npn.c @@ -59,12 +59,8 @@ static int __dc_npn_status(ScfEfunction* root, ScfEfunction* f, ScfEline* LP, Sc continue; } #endif - if (c->lock) { - scf_logi("\033[34m status: %d, lock: %d, \033[0m", c->status, c->lock); - ses_pin_print(pb); - printf("pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n", pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF); - continue; - } + if (c->lock) + goto check; if (lb->v < SCF_EDA_V_MIN) { if (le->v < SCF_EDA_V_MIN) @@ -103,6 +99,14 @@ static int __dc_npn_status(ScfEfunction* root, ScfEfunction* f, ScfEline* LP, Sc // c->status = SCF_EDA_Status_OFF; } +check: + if ((c->pf->IC && SCF_EDA_OP_AMP == c->pf->IC->type) + || pe->v >= LP->v - SCF_EDA_V_NPN_OFF + || pb->v <= LN->v + SCF_EDA_V_NPN_OFF) { + c->lock = 0; + c->status = SCF_EDA_Status_ON; + } + scf_logi("\033[34m status: %d, lock: %d, ", c->status, c->lock); ses_pin_print(pb); printf("pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF); diff --git a/ses_step_dc_pnp.c b/ses_step_dc_pnp.c index a4e5186..305d42f 100644 --- a/ses_step_dc_pnp.c +++ b/ses_step_dc_pnp.c @@ -41,12 +41,8 @@ static int __dc_pnp_status(ScfEfunction* root, ScfEfunction* f, ScfEline* LP, Sc int neg = __ses_path_neg(root, lb, LP, LN); int pos = __ses_path_pos(root, lb, LP, LN); - if (c->lock) { - scf_logi("\033[34m status: %d, lock: %d, \033[0m", c->status, c->lock); - ses_pin_print(pb); - printf("pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n", pb->v, pe->v, pe->v - pb->v, SCF_EDA_V_PNP_OFF); - continue; - } + if (c->lock) + goto check; if (lb->v < SCF_EDA_V_MIN) { if (le->v < SCF_EDA_V_MIN) @@ -85,6 +81,14 @@ static int __dc_pnp_status(ScfEfunction* root, ScfEfunction* f, ScfEline* LP, Sc // c->status = SCF_EDA_Status_OFF; } +check: + if ((c->pf->IC && SCF_EDA_OP_AMP == c->pf->IC->type) + || pb->v >= LP->v - SCF_EDA_V_NPN_OFF + || pe->v <= LN->v + SCF_EDA_V_NPN_OFF) { + c->lock = 0; + c->status = SCF_EDA_Status_ON; + } + scf_logi("\033[34m status: %d, lock: %d, ", c->status, c->lock); ses_pin_print(pb); printf("pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", pb->v, pe->v, pe->v - pb->v, SCF_EDA_V_PNP_OFF); diff --git a/ses_step_draw.c b/ses_step_draw.c index 94d85be..4869b18 100644 --- a/ses_step_draw.c +++ b/ses_step_draw.c @@ -27,6 +27,12 @@ static void ses_text_a(cairo_t* cr, int x, int y, double a) } else if (a > 1e-9 || a < -1e-9) { snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000.0 * SHOW_BITS) / SHOW_BITS); + cairo_move_to (cr, x, y); + cairo_show_text(cr, text); + + } else if (a > 1e-13 || a < -1e-13) { + snprintf(text, sizeof(text) - 1, "%lgnA", (int64_t)(a * 1e9 * SHOW_BITS) / SHOW_BITS); + cairo_move_to (cr, x, y); cairo_show_text(cr, text); } @@ -393,7 +399,7 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) SHOW_COLOR(cr, 0.0, 0.0, 0.0); if (c->r + c->dr > 1e6) - snprintf(text, sizeof(text) - 1, "%lgMΩ", (int64_t)(c->r + c->dr) / 1000.0); + snprintf(text, sizeof(text) - 1, "%lgMΩ", (int64_t)(c->r + c->dr) / 1000000.0); else if (c->r + c->dr > 999) snprintf(text, sizeof(text) - 1, "%lgkΩ", (int64_t)((c->r + c->dr) * 1000.0) / 1000000.0); else @@ -1553,21 +1559,23 @@ static int _draw_handler(ScfEfunction* f, int64_t ps, int64_t count, ses_ctx_t* #endif if (1 || count % 10 == 0) { -#if 0 +#if 1 static FILE* fp = NULL; if (!fp) fp = fopen("v.txt", "w"); - if (fp) - fprintf(fp, "%ld, %lg, %lg, %lg\n", i, f->elines[2]->v, f->elines[9]->v, f->elines[8]->v); + if (fp) { + fprintf(fp, "%ld, %lg\n", i, f->elines[4]->v); + fflush(fp); + } #endif int j = count % 400; - if (j > 396 || j < 20) { +// if (j > 396 || j < 20) { ses_draw(f, file, f->x, f->y, f->w, f->h, ps, count); -// __draw_IC(f, ps, count, i); - } + __draw_IC(f, ps, count, i); +// } i++; } diff --git a/ses_step_jr.c b/ses_step_jr.c index 3f44782..2770755 100644 --- a/ses_step_jr.c +++ b/ses_step_jr.c @@ -198,3 +198,53 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) scf_logd("path: %d, pr: %lg, sr: %lg\n\n", path->index, path->pr, path->sr); return 0; } + +void __ses_path_lc(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv, double* lv, double* uf, double* uh, double* la) +{ + ScfEcomponent* c; + ScfEpin* p; + + int i; + + if (cv) + *cv = 0; + + if (lv) + *lv = 0; + + if (uf) + *uf = 0; + + if (uh) + *uh = 0; + + if (la) + *la = 0; + + for (i = m; i <= n; i++) { + p = path->pins->data[i]; + c = p->c; + + if (i & 0x1) { + int sign = !p->id - p->id; + + if (SCF_EDA_Capacitor == c->type) { + if (cv) + *cv += c->v * sign; + + if (uf) + *uf += c->uf; + + } else if (SCF_EDA_Inductor == c->type) { + if (la) + *la = c->a * sign; + + if (lv) + *lv += c->v * sign; + + if (uh) + *uh += c->uh; + } + } + } +} diff --git a/ses_step_open.c b/ses_step_open.c index 55a72a4..5afc4b0 100644 --- a/ses_step_open.c +++ b/ses_step_open.c @@ -204,12 +204,18 @@ static void __open_status_line(ScfEfunction* f, ScfEline* el, ScfEline* LP, ScfE if (__ses_path_pos(f, el, LP, LN)) { if (__ses_path_neg(f, el, LP, LN)) return; - el->v = LP->v; - } else if (__ses_path_neg(f, el, LP, LN)) - el->v = LN->v; - else - el->v = SCF_EDA_V_NPN_ON / 2; + if (!ses_top_line(el)->vconst) + el->v = LP->v; + + } else if (__ses_path_neg(f, el, LP, LN)) { + if (!ses_top_line(el)->vconst) + el->v = LN->v; + + } else { + if (!ses_top_line(el)->vconst) + el->v = SCF_EDA_V_NPN_ON / 2; + } // scf_logw(""); // ses_eline_print(el); @@ -239,18 +245,15 @@ static void __open_status_IC(ScfEfunction* f, ScfEcomponent* IC, ScfEline* LP, S static int _open_handler(ScfEfunction* f, int64_t ps, int64_t count, ses_ctx_t* ctx) { ScfEcomponent* c; - ScfEcomponent* B = f->components[0]; - ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; - ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; - ScfEline* LP = ses_top_pline(Bp); - ScfEline* LN = ses_top_pline(Bn); + ScfEline* LP = ses_find_line_by_flag(f, SCF_EDA_PIN_POS); + ScfEline* LN = ses_find_line_by_flag(f, SCF_EDA_PIN_NEG); ScfEline* el; long i; for (i = 0; i < f->n_elines; i++) { el = f->elines[i]; - if (el->flags & (SCF_EDA_PIN_IN | SCF_EDA_PIN_POS | SCF_EDA_PIN_NEG)) + if (el->flags & (SCF_EDA_PIN_IN | SCF_EDA_PIN_POS | SCF_EDA_PIN_NEG | SCF_EDA_PIN_GND)) continue; __open_status_line(f, el, LP, LN); diff --git a/ses_step_topo.c b/ses_step_topo.c index 192643e..d4e31af 100644 --- a/ses_step_topo.c +++ b/ses_step_topo.c @@ -361,7 +361,7 @@ static int __ses_dfs_path(ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __paths, #if 0 scf_loge("off: "); ses_pin_print(rp); - printf("l%ld, vflag: %d, pflag: %d\n", rp->lid, rp->vflag, rp->pflag); + printf("l%ld, vflag: %d, pflag: %d\n\n", rp->lid, rp->vflag, rp->pflag); #endif } } @@ -1354,6 +1354,10 @@ static int topo_epin_cmp(const void* v0, const void* v1, void* arg) if (SCF_EDA_Capacitor == c1->type) return 1; + if (SCF_EDA_Resistor == c0->type) + return 1; + if (SCF_EDA_Resistor == c1->type) + return -1; return 0; } @@ -1916,33 +1920,30 @@ static int _topo_paths_lc(ScfEfunction* root, ScfEfunction* f, scf_vector_t* pat static int _topo_handler(ScfEfunction* f, int64_t ps, int64_t count, ses_ctx_t* ctx) { ses_path_t* path; - ScfEcomponent* B; + ScfEcomponent* c; ScfEline* el; _topo_clear(f); scf_vector_clear(ctx->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_components; i++) { + c = f->components[i]; - int ret = _topo_paths(el, ctx->paths, 1); - if (ret < 0) - return ret; + if (SCF_EDA_Battery == c->type) { + el = f->elines[c->pins[SCF_EDA_Battery_POS]->lid]; + int ret = _topo_paths(el, ctx->paths, 1); + if (ret < 0) + return ret; + } + } // scf_logi("\n"); // ses_paths_print(ctx->paths); // scf_logi("\n\n"); - el = f->elines[B->pins[SCF_EDA_Battery_NEG]->lid]; - - if (el->flags & SCF_EDA_PIN_GND) { - ret = _topo_paths(el, ctx->paths, 1); - if (ret < 0) - return ret; - } - - ret = _topo_paths_lc(f, f, ctx->paths); + int ret = _topo_paths_lc(f, f, ctx->paths); if (ret < 0) return ret; #if 0 diff --git a/ses_step_va.c b/ses_step_va.c deleted file mode 100644 index 595cf2b..0000000 --- a/ses_step_va.c +++ /dev/null @@ -1,184 +0,0 @@ -#include"ses_core.h" - -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 = p->c; - - double v; - double r; - - __ses_path_sr(f, path, i0, i, &r); - - ses_ir_u(&v, NULL, a, 0, r, 0); - - p->v = p0->v - v; - - if ((SCF_EDA_Capacitor == c->type || SCF_EDA_Inductor == c->type) && (i & 0x1)) { - int sign = !p->id - p->id; - - p->v -= c->v * sign; - } - - scf_logd("c%ldp%ld, c%ldp%ld, a: %lg, r: %lg, v: %lg, p0->v: %lg, p->v: %lg\n", p0->cid, p0->id, p->cid, p->id, a, r, v, p0->v, p->v); -} - -void __ses_path_lc(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv, double* lv, double* uf, double* uh, double* la) -{ - ScfEcomponent* c; - ScfEpin* p; - - int i; - - if (cv) - *cv = 0; - - if (lv) - *lv = 0; - - if (uf) - *uf = 0; - - if (uh) - *uh = 0; - - if (la) - *la = 0; - - for (i = m; i <= n; i++) { - p = path->pins->data[i]; - c = p->c; - - if (i & 0x1) { - int sign = !p->id - p->id; - - if (SCF_EDA_Capacitor == c->type) { - if (cv) - *cv += c->v * sign; - - if (uf) - *uf += c->uf; - - } else if (SCF_EDA_Inductor == c->type) { - if (la) - *la = c->a * sign; - - if (lv) - *lv += c->v * sign; - - if (uh) - *uh += c->uh; - } - } - } -} - -int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ps, int64_t count) -{ - if (!path) - return -EINVAL; - if (path->pins->size < 2) - return -EINVAL; - - if (n - m < 1) - return 0; - - ScfEcomponent* c; - ScfEpin* p0 = path->pins->data[m]; - ScfEpin* p1 = path->pins->data[n]; - ScfEline* el; - ScfEpin* p; - ScfEpin* p2; - - double _sr0 = p0->sr; - double _pr0 = p0->pr; - double _sr1 = p1->sr; - double _pr1 = p1->pr; - - if (0 == m) { - p0->sr = 0; - p0->pr = 0; - } - - if (path->pins->size - 1 == n) { - p1->sr = path->sr; - p1->pr = path->pr; - } - - 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_logd("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; - - int i0 = m; - int i; - - for (i = m; i <= n; i++) { - p = path->pins->data[i]; - c = p->c; - el = ses_top_pline(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); - - __ses_path_split_v(f, path, i0, i, a); - - p->a = a; - - if (!el->vconst) { - el->v = p->v; - ses_line_set_v(c->pf->elines[p->lid], p->v); - } - - r += p->r + p->dr; - - if (i & 0x1) { - p2 = path->pins->data[i - 1]; - dv -= p->v; - r += c->r + c->dr; - - int sign = !p->id - p->id; - - p2->a = a; - c->a = a * sign; - c->count = count; - - scf_logd("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); - - r = 0; - } else { - dv = p->v; - scf_logd("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, a: %lg, p->pr: %lg, e%ld->v: %lg\n", - path->index, i, p->cid, p->id, p->v, dv, a, p->pr, el->id, el->v); - } - } -// printf("\n"); - - if (0 == m) { - p0->sr = _sr0; - p0->pr = _pr0; - } - - if (path->pins->size - 1 == n) { - p1->sr = _sr1; - p1->pr = _pr1; - } - - path->vflag = 1; - return 0; -} diff --git a/ses_utils.c b/ses_utils.c index a882aff..9dd7bdf 100644 --- a/ses_utils.c +++ b/ses_utils.c @@ -88,6 +88,9 @@ void ses_edge_print(ses_edge_t* edge) if (edge->edge_b) printf(" b[%d]", edge->edge_b->index); + + if (edge->mirror) + printf(" m[%d]", edge->mirror->index); printf("; "); } diff --git a/test/Makefile b/test/Makefile index c27bb31..4b02ef6 100644 --- a/test/Makefile +++ b/test/Makefile @@ -5,7 +5,8 @@ #CFILES += pnp.c #CFILES += colpitts.c #CFILES += astable_multivibrator.c -CFILES += two_battery.c +#CFILES += two_battery.c +CFILES += opa_rc.c #CFILES += draw_timing.c CFILES += ../scf_eda_pack.c diff --git a/test/opa_rc.c b/test/opa_rc.c new file mode 100644 index 0000000..25c09e4 --- /dev/null +++ b/test/opa_rc.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include"ses_core.h" + +int main(int argc, char* argv[]) +{ + ScfEcomponent* B0; + ScfEcomponent* B1; + + ScfEcomponent* R0; + ScfEcomponent* R1; + ScfEcomponent* R2; + ScfEcomponent* C0; + ScfEcomponent* C1; + ScfEcomponent* C2; + + ScfEcomponent* R3; + ScfEcomponent* R4; + ScfEcomponent* OP_AMP; + + ScfEfunction* f; + ScfEboard* b; + + b = scf_eboard__alloc(); + f = scf_efunction__alloc("opa_rc"); + + EDA_INST_ADD_COMPONENT(f, B0, SCF_EDA_Battery); + EDA_INST_ADD_COMPONENT(f, B1, SCF_EDA_Battery); + + EDA_INST_ADD_COMPONENT(f, R0, SCF_EDA_Resistor); + EDA_INST_ADD_COMPONENT(f, R1, SCF_EDA_Resistor); + EDA_INST_ADD_COMPONENT(f, R2, SCF_EDA_Resistor); + EDA_INST_ADD_COMPONENT(f, C0, SCF_EDA_Capacitor); + EDA_INST_ADD_COMPONENT(f, C1, SCF_EDA_Capacitor); + EDA_INST_ADD_COMPONENT(f, C2, SCF_EDA_Capacitor); + + EDA_INST_ADD_COMPONENT(f, R3, SCF_EDA_Resistor); + EDA_INST_ADD_COMPONENT(f, R4, SCF_EDA_Resistor); + + EDA_INST_ADD_COMPONENT(f, OP_AMP, SCF_EDA_OP_AMP); + +// B1->pins[SCF_EDA_Battery_NEG]->flags = SCF_EDA_PIN_NEG; + B0->pins[SCF_EDA_Battery_POS]->flags = SCF_EDA_PIN_POS; + B0->pins[SCF_EDA_Battery_NEG]->flags = SCF_EDA_PIN_NEG; + + EDA_PIN_ADD_PIN(B0, SCF_EDA_Battery_NEG, B1, SCF_EDA_Battery_NEG); + + EDA_PIN_ADD_PIN(OP_AMP, SCF_EDA_OP_AMP_POS, B0, SCF_EDA_Battery_POS); + EDA_PIN_ADD_PIN(OP_AMP, SCF_EDA_OP_AMP_NEG, B0, SCF_EDA_Battery_NEG); + + EDA_PIN_ADD_PIN(R0, 0, R1, 1); + EDA_PIN_ADD_PIN(R1, 0, R2, 1); + + EDA_PIN_ADD_PIN(C0, 1, R0, 0); + EDA_PIN_ADD_PIN(C1, 1, R1, 0); + EDA_PIN_ADD_PIN(C2, 1, R2, 0); + EDA_PIN_ADD_PIN(C0, 0, B0, SCF_EDA_Battery_NEG); + EDA_PIN_ADD_PIN(C1, 0, B0, SCF_EDA_Battery_NEG); + EDA_PIN_ADD_PIN(C2, 0, B0, SCF_EDA_Battery_NEG); + + EDA_PIN_ADD_PIN(R3, 0, R4, 1); + EDA_PIN_ADD_PIN(R2, 0, R4, 0); + + EDA_PIN_ADD_PIN(OP_AMP, SCF_EDA_OP_AMP_IN, B1, SCF_EDA_Battery_POS); + EDA_PIN_ADD_PIN(OP_AMP, SCF_EDA_OP_AMP_INVERT, R3, 0); + EDA_PIN_ADD_PIN(OP_AMP, SCF_EDA_OP_AMP_OUT, R3, 1); + EDA_PIN_ADD_PIN(OP_AMP, SCF_EDA_OP_AMP_OUT, R0, 1); + + OP_AMP->pins[SCF_EDA_OP_AMP_OUT]->flags = SCF_EDA_PIN_OUT; + + B0->v = 5; + B1->v = 2.5; + + R0->r = 10 * 1000; + R1->r = 10 * 1000; + R2->r = 10 * 1000; + C0->uf = 0.01; + C1->uf = 0.01; + C2->uf = 0.01; + + R3->r = 1500 * 1000; + R4->r = 55.2 * 1000; + + scf_eboard__add_function(b, f); + + long len = 0; + uint8_t* buf = NULL; + + ScfEboard_pack(b, &buf, &len); + ScfEboard_free(b); + b = NULL; + + FILE* fp = fopen("./opa_rc.cpk", "wb"); + if (!fp) + return -EINVAL; + + fwrite(buf, len, 1, fp); + fclose(fp); + return 0; +}