a sin oscillator with F007 OP-Amplifier ok, update some *.cpk
authoryu.dongliang <18588496441@163.com>
Sat, 17 May 2025 14:23:06 +0000 (22:23 +0800)
committeryu.dongliang <18588496441@163.com>
Sat, 17 May 2025 14:23:06 +0000 (22:23 +0800)
44 files changed:
Makefile
cpk/9012.txt
cpk/9013.txt
cpk/Makefile
cpk/op_amp_f007.c [new file with mode: 0644]
cpk/op_amp_f007.cpk [new file with mode: 0644]
cpk/ttl_adc.cpk
cpk/ttl_add.cpk
cpk/ttl_and.cpk
cpk/ttl_and2_or.cpk
cpk/ttl_dff.cpk
cpk/ttl_if.cpk
cpk/ttl_mla.cpk
cpk/ttl_nand.cpk
cpk/ttl_nand4.cpk
cpk/ttl_nand_gate.c [deleted file]
cpk/ttl_nand_gate2.c [deleted file]
cpk/ttl_nor.cpk
cpk/ttl_not.cpk
cpk/ttl_not_delay.cpk
cpk/ttl_or.cpk
cpk/ttl_xor.cpk
examples/astable_multivibrator.cpk
examples/colpitts_oscillator.cpk
examples/pnp_oscillator.cpk
examples/sin_oscillator.cpk
main.c
scf_eda_pack.c
scf_eda_pack.h
ses_core.h
ses_node_analysis.c
ses_step_battery.c
ses_step_dc_diode.c
ses_step_dc_input.c
ses_step_dc_npn.c
ses_step_dc_pnp.c
ses_step_draw.c
ses_step_jr.c
ses_step_open.c
ses_step_topo.c
ses_step_va.c [deleted file]
ses_utils.c
test/Makefile
test/opa_rc.c [new file with mode: 0644]

index 0f2861dd48d65a500b19f35c97894edff49d0d33..d7d682186f2f130474385aef6b6351e86d1c9196 100644 (file)
--- 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
index 849920af130ea6847ac0daf874caa9d5894826ce..e8b206aa06910193f50b9bc73807b33a8e7ac080 100644 (file)
@@ -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
index 849920af130ea6847ac0daf874caa9d5894826ce..e8b206aa06910193f50b9bc73807b33a8e7ac080 100644 (file)
@@ -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
index 8bf77372dac0a6634d8988e05b216a885e1fe95a..8807f056995bc2981d9946cbac7ea1018b5cba36 100644 (file)
 #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 (file)
index 0000000..4130ade
--- /dev/null
@@ -0,0 +1,219 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#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 (file)
index 0000000..b22a55d
Binary files /dev/null and b/cpk/op_amp_f007.cpk differ
index 5a9309fe2daa98ca9d45d07a5f42bcc4e1f5dd43..763b3b55041dd562260091d9b96fe1d32e91a884 100644 (file)
Binary files a/cpk/ttl_adc.cpk and b/cpk/ttl_adc.cpk differ
index a7d9303e2f4d9a935809fe6af87cf47e5a0d1312..f51d3525c88f8568a4de6061964c62808e68a671 100644 (file)
Binary files a/cpk/ttl_add.cpk and b/cpk/ttl_add.cpk differ
index 79e34d1f4374789b1e14c8e9b36c3505e19cb8a4..e64b1828f2ca1ecaef084f287bc5569c8848ce68 100644 (file)
Binary files a/cpk/ttl_and.cpk and b/cpk/ttl_and.cpk differ
index c47586dee92c4e8ff408ba7459392bb32c9df56f..d13df3d3e2ca5a17cc0cb6bf3792a47f61ccb932 100644 (file)
Binary files a/cpk/ttl_and2_or.cpk and b/cpk/ttl_and2_or.cpk differ
index 7bbdaafaf20129cc46d635392ad7607e52ea215b..b2d9cdebd2e261b68aa98f6df093c149e2b2f275 100644 (file)
Binary files a/cpk/ttl_dff.cpk and b/cpk/ttl_dff.cpk differ
index 3702fea7d523110eacec509f59e7f4b094d39c5e..0f7da1735e4689c1df984f0b49a1564a03439901 100644 (file)
Binary files a/cpk/ttl_if.cpk and b/cpk/ttl_if.cpk differ
index 6a52c057e238374612a245efdfca2b616a958118..7ea1d6a3cd91ab7599c60882309cbc90d9178db0 100644 (file)
Binary files a/cpk/ttl_mla.cpk and b/cpk/ttl_mla.cpk differ
index 7d2b4e54e125c67e5226fc124d135f4143471914..9bfc9987c5ff2715114477af01c4495713c321bf 100644 (file)
Binary files a/cpk/ttl_nand.cpk and b/cpk/ttl_nand.cpk differ
index d39157778d4e35ae33d32ec9f8fa2cb1adec6137..e6f60fc0836f5bef67c533e89d370bd9762c971c 100644 (file)
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 (file)
index d21b936..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#include<stdio.h>
-#include<stdlib.h>
-#include<string.h>
-#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 (file)
index 8c13a20..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-#include<stdio.h>
-#include<stdlib.h>
-#include<string.h>
-#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;
-}
index 8bda7ad71a0902dda061fdbd5f5137726c64b390..cd7c79351ba6d97cc5baabf352677711e8117ee9 100644 (file)
Binary files a/cpk/ttl_nor.cpk and b/cpk/ttl_nor.cpk differ
index df325888971097d9c4dc88da1f9c15318b190ff6..12595132196e70e77547b84a1ec8cd4ee9a31481 100644 (file)
Binary files a/cpk/ttl_not.cpk and b/cpk/ttl_not.cpk differ
index ec34e092baebc59abd8c02106ef1e6970726956c..4f52ff93f38771c7341fd40c39cc95072fbc7bc1 100644 (file)
Binary files a/cpk/ttl_not_delay.cpk and b/cpk/ttl_not_delay.cpk differ
index e5a48442619ad1501c3227d8b5ac0ba0f531352f..d3f4e4250e74406b098f13e8c2f9bd6bf22ef7e2 100644 (file)
Binary files a/cpk/ttl_or.cpk and b/cpk/ttl_or.cpk differ
index 77836ea882838aba9820a9031552f1d1d309136b..fe1f6b95c7cd0b6cb2ac21d67db1114cc8ceea27 100644 (file)
Binary files a/cpk/ttl_xor.cpk and b/cpk/ttl_xor.cpk differ
index 94e41bd95efea1e50edab6f2cdffb017e130d115..c47628b08b1bf4bd69e95b3bf82b89eaf89af98e 100644 (file)
Binary files a/examples/astable_multivibrator.cpk and b/examples/astable_multivibrator.cpk differ
index 54f244d5b436274bd824d7785534741f44fc413e..9025e897fdcbef52840f5e7ae6e85b1995410449 100644 (file)
Binary files a/examples/colpitts_oscillator.cpk and b/examples/colpitts_oscillator.cpk differ
index 6fac79752c2b23e312c6cd15df452366b38c7f92..68f5366210c5dccaaab81499a6ed92f681511a39 100644 (file)
Binary files a/examples/pnp_oscillator.cpk and b/examples/pnp_oscillator.cpk differ
index 68a1061aee49ed491d2f6ffa0153555ee392e992..8b028b9d79f48916697e149f558f29d1076a3caa 100644 (file)
Binary files a/examples/sin_oscillator.cpk and b/examples/sin_oscillator.cpk differ
diff --git a/main.c b/main.c
index 1af12ec68cb7758e063658697c301f91419d819d..fad0988b8f0eb297268ee072bf8c6b7f94344c89 100644 (file)
--- 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    = 0.0;
+       double    = 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);
index 35294628952b823f32ea22bbe8cc8074d3eb3367..98938475afc0e76018cb2130a81255720ec60953 100644 (file)
@@ -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) {
index f4d158183cdca6b00b927d4ae2c31dbf11be1d49..689c3d8f5e75a1cc9ec7343fe766259b34444272 100644 (file)
@@ -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] =
 {
index ec5a8e4e1f8407409fbbc25a3b090dac885fa0c9..bc587d30c3dd6362a6c1f0f1075dce7ee2ea9148 100644 (file)
@@ -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
index d0d231089b1f4203b905b43da3d5ec2ca983798b..86c913be33a691905816ec5dad06f0a445cfc371 100644 (file)
@@ -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);
+                                       }
                                }
                        }
                }
index ddf5a828d5120a2d9412ccd927c2593eb07e576b..e6388b7c29fa30a6df83a7e30119adf150fe8465 100644 (file)
@@ -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);
index 79df91eb89de3a30077519053a26ea96a63d1b57..10531424413caef9bf00454cb8bbf6467c4702e3 100644 (file)
@@ -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);
 }
 
index 0bea3842b0c9815db9d77c0366367b93dd8c598c..ea43f57e7c3169d5521abf50809b2fa1f5d5098a 100644 (file)
@@ -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];
index 5974f392fa11647d7840b89f69414923b7b32ce2..3663ee85d31ccbe249099caffd8bd7bc445bb8c2 100644 (file)
@@ -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);
index a4e5186d114a4d2d81a0690b114ea86336be9ccc..305d42ffff73416ffa328ad8a2f44762d9b010e6 100644 (file)
@@ -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);
index 94d85be8f162a469fc5a60f370449f66d90c3d9b..4869b185a582d2a8c8c34a8cfff46f3de23c4b12 100644 (file)
@@ -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++;
        }
 
index 3f44782db55b835511c948b8ff298cb657b17027..2770755c3378e32bb338836d4fe1e91f3d0d796e 100644 (file)
@@ -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;
+                       }
+               }
+       }
+}
index 55a72a4c67b6015ea155fbff78847b969b89b624..5afc4b03b67e449607148dc757521607c04e7cce 100644 (file)
@@ -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);
index 192643e56a73475903b5a8f7e3985b48dbd91c19..d4e31af713fed6edaa7d62b0a473c4995cdc6859 100644 (file)
@@ -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 (file)
index 595cf2b..0000000
+++ /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;
-}
index a882aff650f3343341090fe5c9eda5478b4f07a1..9dd7bdf796a1cc88735092503cfe7117faa311fa 100644 (file)
@@ -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("; ");
 }
 
index c27bb31759f2f8f3427b68c29fe9fe0c2251c066..4b02ef6ad1e9ca8ab59561e3641d2089037dd786 100644 (file)
@@ -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 (file)
index 0000000..25c09e4
--- /dev/null
@@ -0,0 +1,101 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#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;
+}