CFILES += ses_step_battery.c
CFILES += ses_step_dc_input.c
CFILES += ses_step_dc_diode.c
-CFILES += ses_step_dc_transistor.c
+CFILES += ses_step_dc_npn.c
+CFILES += ses_step_dc_pnp.c
CFILES += ses_step_topo.c
CFILES += ses_step_jr.c
CFILES += ses_step_va_diode.c
-CFILES += ses_step_va_transistor.c
CFILES += ses_step_va.c
CFILES += ses_step_status.c
printf("f: %s\n", f->name);
- ses_steps_analyse(f, 1000, 60 * 1000 + 10501);
+ ses_steps_analyse(f, 1000, 1);
}
#endif
#define SCF_EDA_V_NPN_ON 0.70
#define SCF_EDA_V_NPN_OFF 0.61
+#define SCF_EDA_V_PNP_ON SCF_EDA_V_NPN_ON
+#define SCF_EDA_V_PNP_OFF SCF_EDA_V_NPN_OFF
+
enum {
SCF_EDA_Battery_NEG,
SCF_EDA_Battery_POS,
};
enum {
- SCF_EDA_PNP_B,
- SCF_EDA_PNP_E,
- SCF_EDA_PNP_C,
- SCF_EDA_PNP_NB,
+ SCF_EDA_PNP_B = SCF_EDA_NPN_B,
+ SCF_EDA_PNP_E = SCF_EDA_NPN_E,
+ SCF_EDA_PNP_C = SCF_EDA_NPN_C,
+ SCF_EDA_PNP_NB = SCF_EDA_NPN_NB,
};
typedef struct {
SCF_PACK_END(ScfEboard)
-ScfEconn* scf_econn__alloc();
+ScfEconn* scf_econn__alloc();
int scf_econn__add_cid(ScfEconn* ec, uint64_t cid);
int scf_econn__del_cid(ScfEconn* ec, uint64_t cid);
int j;
int n_diodes;
int n_NPNs;
+ int n_PNPs;
int n_capacitors;
};
int n_capacitors;
int n_diodes;
int n_NPNs;
+ int n_PNPs;
int n_transistors;
int n_layers;
int vip_m;
int vip_n;
- int n_diodes;
- int n_NPNs;
-
ses_node_t* node0;
ses_node_t* node1;
- ses_edge_t* npn_b;
- int npn_index;
- double npn_hfe;
+ ses_edge_t* edge_b;
+ double hfe;
double cv;
double r;
double a0;
uint8_t vflag:1;
+ uint8_t bflag:1;
};
struct ses_node_s
p = base->pins->data[j - 1];
n = __ses_find_eline_index(f, p->lid);
- SCF_XCHG(f->elines[n], f->elines[j / 2 + 1]);
+ SCF_XCHG(f->elines[n], f->elines[j / 2]);
for (i = 0; i < f->n_elines; i++)
f->elines[i]->vflag = 0;
ScfEpin* pe;
ScfEpin* pc;
- size_t i;
- size_t j;
+ int64_t i;
+ int64_t j;
+
+ assert(SCF_EDA_NPN_B == SCF_EDA_PNP_B);
+ assert(SCF_EDA_NPN_C == SCF_EDA_PNP_C);
+ assert(SCF_EDA_NPN_E == SCF_EDA_PNP_E);
for (i = 0; i < f->n_components; i++) {
c = f->components[i];
- if (SCF_EDA_NPN != c->type)
+ if (SCF_EDA_NPN != c->type && SCF_EDA_PNP != c->type)
continue;
j = 0;
return NULL;
}
-int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* nodes, int* n_edges, int* n_NPNs)
+int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* nodes, int* n_edges)
{
ses_path_t* child;
ses_path_t* bridge;
ses_path_t* conn;
- ses_edge_t* edge = NULL;
- ses_edge_t* npn_c = NULL;
- ses_node_t* prev = NULL;
- ses_node_t* node = NULL;
+ ses_edge_t* edge = NULL;
+ ses_edge_t* edge_c = NULL;
+ ses_node_t* prev = NULL;
+ ses_node_t* node = NULL;
ScfEcomponent* c;
ScfEpin* p;
if (conn->vflag)
continue;
- ret = __ses_nodes_path2(f, conn, 0, conn->pins->size - 1, nodes, n_edges, n_NPNs);
+ ret = __ses_nodes_path2(f, conn, 0, conn->pins->size - 1, nodes, n_edges);
if (ret < 0)
return ret;
}
if (child->vflag)
continue;
- ret = __ses_nodes_path2(f, child, 0, child->pins->size - 1, nodes, n_edges, n_NPNs);
+ ret = __ses_nodes_path2(f, child, 0, child->pins->size - 1, nodes, n_edges);
if (ret < 0)
return ret;
}
if (bridge->vflag)
continue;
- ret = __ses_nodes_path2(f, bridge, 0, bridge->pins->size - 1, nodes, n_edges, n_NPNs);
+ ret = __ses_nodes_path2(f, bridge, 0, bridge->pins->size - 1, nodes, n_edges);
if (ret < 0)
return ret;
}
scf_logd("path: %d, vflag: %d, vip_m: %d, vip_n: %d\n", path->index, path->vflag, vip_m, vip_n);
- int n = 0;
+ int bflag = 0;
for (i = vip_n - 1; i > vip_m; i -= 2) {
p = path->pins->data[i];
c = f->components[p->cid];
- if (SCF_EDA_NPN == c->type) {
+ switch (c->type) {
- if (SCF_EDA_NPN_B == p->id) {
- npn_c = ses_nodes_find_edge_by_pin(nodes, c->pins[SCF_EDA_NPN_C]);
- if (!npn_c) {
- scf_loge("\n");
- return -EINVAL;
- }
+ case SCF_EDA_PNP:
+ p = path->pins->data[i + 1];
+ case SCF_EDA_NPN:
- n++;
- npn_c->npn_hfe = c->pins[SCF_EDA_NPN_C]->hfe;
- }
+ if (SCF_EDA_NPN_B == p->id) {
+ edge_c = ses_nodes_find_edge_by_pin(nodes, c->pins[SCF_EDA_NPN_C]);
+ if (!edge_c) {
+ scf_loge("\n");
+ return -EINVAL;
+ }
- if (!node) {
- node = ses_node_alloc();
- if (!node)
- return -ENOMEM;
- }
- }
+ bflag = 1;
+ edge_c->hfe = c->pins[SCF_EDA_NPN_C]->hfe;
+ }
+
+ if (!node) {
+ node = ses_node_alloc();
+ if (!node)
+ return -ENOMEM;
+ }
+ break;
+ default:
+ break;
+ };
if (path->childs) {
for (k = 0; k < path->childs->size; k++) {
}
edge->index = (*n_edges)++;
edge->node1 = node;
- edge->n_NPNs= n;
- n = 0;
+ edge->bflag = bflag;
+ bflag = 0;
if (prev) {
ret = ses_node_ref_edge(prev, edge);
edge->node0 = prev;
}
- if (npn_c) {
- npn_c->npn_b = edge;
- npn_c->npn_index = (*n_NPNs)++;
- npn_c = NULL;
+ if (edge_c) {
+ edge_c->edge_b = edge;
+ edge_c = NULL;
}
ret = scf_vector_add(nodes, node);
return ret;
edge->index = (*n_edges)++;
edge->node0 = prev;
- edge->n_NPNs= n;
- n = 0;
+ edge->bflag = bflag;
+ bflag = 0;
- if (npn_c) {
- npn_c->npn_b = edge;
- npn_c->npn_index = (*n_NPNs)++;
- npn_c = NULL;
+ if (edge_c) {
+ edge_c->edge_b = edge;
+ edge_c = NULL;
}
}
if (!vec)
return -ENOMEM;
+ ses_node_t* node;
+ ses_edge_t* edge;
+
int n_edges = 0;
- int n_NPNs = 0;
+ int i;
+ int j;
- int ret = __ses_nodes_path2(f, path, vip_m, vip_n, vec, &n_edges, &n_NPNs);
+ int ret = __ses_nodes_path2(f, path, vip_m, vip_n, vec, &n_edges);
if (ret < 0) {
scf_vector_clear(vec, (void (*)(void*) )ses_node_free);
scf_vector_free(vec);
return ret;
}
- ses_node_t* node;
- ses_edge_t* edge;
- int i;
- int j;
-
for (i = 0; i < vec->size; ) {
node = vec->data[i];
m++;
edge->vflag = 1;
- if (edge->npn_b)
+ if (edge->edge_b)
t++;
}
}
scf_logd("c%ldp%ld-c%ldp%ld, r: %lg, cv: %lg, edge->index: %d\n", p0->cid, p0->id, p1->cid, p1->id, r, cv, edge->index);
- if (edge->n_NPNs > 0) {
- b[n + edge->index] = cv + edge->n_NPNs * SCF_EDA_V_NPN_ON;
-#if 0
- } else if (edge->npn_b) {
- A[(n + edge->index) * N + n + edge->index] = 1;
- A[(n + edge->index) * N + n + edge->npn_b->index] = -edge->npn_hfe;
- b[n + edge->index] = 0;
- continue;
-#endif
- } else {
+ if (edge->bflag)
+ b[n + edge->index] = cv + SCF_EDA_V_NPN_ON;
+ else {
b[n + edge->index] = cv;
A[(n + edge->index) * N + n + edge->index] = -r;
}
for (j = 0; j < node->edges->size; j++) {
edge = node->edges->data[j];
- if (edge->npn_b) {
+ if (edge->edge_b) {
double Ic = X[n + edge->index];
- double Ib = X[n + edge->npn_b->index];
+ double Ib = X[n + edge->edge_b->index];
- double dI = Ib * edge->npn_hfe - Ic;
+ double dI = Ib * edge->hfe - Ic;
if (dI < -1e-10) {
scf_logi("Ic: %lg, Ib: %lg, dI: %lg\n", Ic, Ib, dI);
for (k = 0; k < N; k++)
A[(n + edge->index) * N + k] = 0;
- A[(n + edge->index) * N + n + edge->index] = -1;
- A[(n + edge->index) * N + n + edge->npn_b->index] = edge->npn_hfe;
- b[n + edge->index] = 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;
n_amplifiers++;
}
p0->a = edge->a;
p1->a = c->pins[SCF_EDA_NPN_B]->a + c->pins[SCF_EDA_NPN_C]->a;
continue;
+
+ } else if (SCF_EDA_PNP == c->type) {
+ ses_ui_r(&edge->r, 0, p0->v - p1->v, 0, edge->a, 0);
+
+ p1->dr = edge->r - p1->r;
+ p1->a = edge->a;
+ p0->a = c->pins[SCF_EDA_PNP_B]->a + c->pins[SCF_EDA_PNP_C]->a;
+ continue;
}
ret = __ses_path_va_branch(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ns, count);
if (!path)
return;
- ses_path_t* path2;
+ ses_path_t* child;
ScfEpin* p;
int i;
int j;
if (!path->parent)
- printf("\033[31mpath : %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, \033[0m",
- path->index, path->n_diodes, path->n_NPNs, path->n_capacitors, path->infos->size);
+ printf("\033[31mpath : %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, \033[0m",
+ path->index, path->n_diodes, path->n_NPNs, path->n_PNPs, path->n_capacitors);
for (i = 0; i < path->pins->size; i++) {
p = path->pins->data[i];
if (path->connections) {
for (i = 0; i < path->connections->size; i++) {
- path2 = path->connections->data[i];
+ child = path->connections->data[i];
- if (path2->parent == path) {
- printf("\033[34mconnection: %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, parent: %d, \033[0m",
- path2->index, path2->n_diodes, path2->n_NPNs, path2->n_capacitors, path2->infos->size, path->index);
+ if (child->parent == path) {
+ printf("\033[34mconnection: %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, parent: %d, \033[0m",
+ child->index, child->n_diodes, child->n_NPNs, child->n_PNPs, child->n_capacitors, path->index);
- ses_path_print(path2);
+ ses_path_print(child);
} else
- printf("connection: %d\n", path2->index);
+ printf("\033[34mconnection: %d\033[0m\n", child->index);
}
}
if (path->childs) {
for (i = 0; i < path->childs->size; i++) {
- path2 = path->childs->data[i];
+ child = path->childs->data[i];
- printf("\033[32mchild : %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, parent: %d, \033[0m",
- path2->index, path2->n_diodes, path2->n_NPNs, path2->n_capacitors, path2->infos->size, path->index);
+ printf("\033[32mchild : %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, parent: %d, \033[0m",
+ child->index, child->n_diodes, child->n_NPNs, child->n_PNPs, child->n_capacitors, path->index);
- ses_path_print(path2);
+ ses_path_print(child);
}
}
if (path->bridges) {
for (i = 0; i < path->bridges->size; i++) {
- path2 = path->bridges->data[i];
+ child = path->bridges->data[i];
- printf("\033[33mbridge: %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, parent: %d, \033[0m",
- path2->index, path2->n_diodes, path2->n_NPNs, path2->n_capacitors, path2->infos->size, path->index);
+ printf("\033[33mbridge: %d, n_diodes: %d, n_NPNs: %d, n_PNPs: %d, n_capacitors: %d, parent: %d, \033[0m",
+ child->index, child->n_diodes, child->n_NPNs, child->n_PNPs, child->n_capacitors, path->index);
- ses_path_print(path2);
+ ses_path_print(child);
}
}
}
#include"ses_core.h"
-static int _dc_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
+static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
{
ScfEcomponent* c;
ScfEcomponent* B;
return 0;
}
-ses_step_t ses_step_dc_transistor =
+ses_step_t ses_step_dc_npn =
{
- .name = "dc_transistor",
+ .name = "dc_npn",
- .handler = _dc_transistor_handler,
+ .handler = _dc_npn_handler,
};
--- /dev/null
+#include"ses_core.h"
+
+static int _dc_pnp_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
+{
+ ScfEcomponent* c;
+ ScfEcomponent* B;
+ ScfEline* lb;
+ ScfEline* le;
+ ScfEpin* pb;
+ ScfEpin* pc;
+ ScfEpin* pe;
+ ScfEpin* Bp;
+ ScfEpin* Bn;
+
+ size_t i;
+ size_t j;
+ size_t k;
+
+ B = f->components[0];
+ Bp = B->pins[SCF_EDA_Battery_POS];
+ Bn = B->pins[SCF_EDA_Battery_NEG];
+
+ for (i = 0; i < f->n_components; i++) {
+ c = f->components[i];
+
+ if (SCF_EDA_PNP != c->type)
+ continue;
+
+ pb = c->pins[SCF_EDA_PNP_B];
+ pc = c->pins[SCF_EDA_PNP_C];
+ pe = c->pins[SCF_EDA_PNP_E];
+
+ lb = f->elines[pb->lid];
+ le = f->elines[pe->lid];
+
+ if (pe->lid == Bp->lid && pb->lid == Bn->lid) {
+ scf_loge("PNP c%ld, short connected\n", c->id);
+ return -EINVAL;
+ }
+
+ if (__ses_path_pos(f, lb) && !__ses_path_neg(f, lb)) {
+ c->status = SCF_EDA_Status_OFF;
+
+ scf_loge("PNP c%ld, status: %d\n", c->id, c->status);
+ continue;
+ }
+
+ scf_logd("c%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n",
+ c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_PNP_OFF);
+
+ if (lb->v < SCF_EDA_V_MIN) {
+
+ if (le->v < SCF_EDA_V_MIN)
+ continue;
+
+ pe->v = le->v;
+ pb->v = le->v - SCF_EDA_V_PNP_ON;
+ lb->v = pb->v;
+
+ if (le->v == Bp->v)
+ lb->vconst = 1;
+
+ if (pb->v < Bn->v) {
+ if (!c->lock)
+ c->status = SCF_EDA_Status_OFF;
+ } else
+ c->status = SCF_EDA_Status_ON;
+
+ } else if (le->v < SCF_EDA_V_MIN) {
+
+ pb->v = lb->v;
+ pe->v = lb->v + SCF_EDA_V_PNP_ON;
+ le->v = pe->v;
+
+ if (lb->v == Bn->v)
+ le->vconst = 1;
+
+ if (pe->v > Bp->v) {
+ if (!c->lock)
+ c->status = SCF_EDA_Status_OFF;
+ } else
+ c->status = SCF_EDA_Status_ON;
+
+ } else if (lb->v <= le->v - SCF_EDA_V_PNP_OFF) {
+
+ if (le->v == Bp->v)
+ lb->vconst = 1;
+ else if (lb->v == Bn->v)
+ le->vconst = 1;
+
+ lb->v = le->v - SCF_EDA_V_PNP_ON;
+ pb->v = lb->v;
+ pe->v = le->v;
+
+ if (pb->v < Bn->v) {
+ if (!c->lock)
+ c->status = SCF_EDA_Status_OFF;
+ } else
+ c->status = SCF_EDA_Status_ON;
+ } else {
+ pb->v = lb->v;
+ pe->v = le->v;
+ if (!c->lock)
+ c->status = SCF_EDA_Status_OFF;
+ }
+
+ scf_loge("\033[34mc%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n",
+ c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_PNP_OFF);
+ }
+
+ return 0;
+}
+
+ses_step_t ses_step_dc_pnp =
+{
+ .name = "dc_pnp",
+
+ .handler = _dc_pnp_handler,
+};
for (i = 0; i < f->n_elines; i++) {
el = f->elines[i];
- printf("e%ld->vconst: %d\n", el->id, el->vconst);
+ scf_logd("e%ld->vconst: %d\n", el->id, el->vconst);
if (SCF_EDA_PIN_OUT & el->flags)
scf_logw("out el: %ld, V: %lg\n", el->id, el->v);
#include<cairo/cairo.h>
#include"ses_core.h"
-#define SHOW_BITS 1000000.0
+#define SHOW_BITS 10000.0
static void ses_text_a(cairo_t* cr, int x, int y, double a)
{
cairo_stroke(cr);
}
+ cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+ ses_text_a(cr, c->x, (pb->y + c->y) / 2, pb->a);
+ ses_text_a(cr, c->x, c->y, pc->a);
+ ses_text_a(cr, c->x, (pe->y + c->y) / 2, pe->a);
+ cairo_stroke(cr);
+ break;
+
+ case SCF_EDA_PNP:
+ pb = c->pins[SCF_EDA_PNP_B];
+ pc = c->pins[SCF_EDA_PNP_C];
+ pe = c->pins[SCF_EDA_PNP_E];
+
+ vertical(&dx0, &dy0, c->x - pb->x, c->y - pb->y, 8);
+ forward (&dx3, &dy3, c->x - pb->x, c->y - pb->y, 8);
+
+ cairo_arc(cr, c->x - dx3 / 2, c->y - dy3 / 2, 12, 0, 2 * M_PI);
+
+ cairo_move_to (cr, pb->x, pb->y);
+ cairo_line_to (cr, c->x - dx3, c->y - dy3);
+ cairo_rel_move_to(cr, dx0, dy0);
+ cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2);
+ cairo_stroke(cr);
+
+ if ((c->x + dx3 + dx0 > c->x + dx3 - dx0 && pe->x > pc->x)
+ || (c->x + dx3 + dx0 < c->x + dx3 - dx0 && pe->x < pc->x)) {
+
+ cairo_move_to(cr, c->x - dx3, c->y - dy3);
+ cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0);
+ cairo_line_to(cr, pe->x, pe->y);
+
+ vertical(&dx1, &dy1, dx3 * 2 + dx0, dy3 * 2 + dy0, 4);
+ forward (&dx4, &dy4, dx3 * 2 + dx0, dy3 * 2 + dy0, 12);
+
+ cairo_move_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1);
+ cairo_line_to(cr, c->x - dx3, c->y - dy3);
+ cairo_line_to(cr, c->x - dx3 + dx4 - dx1, c->y - dy3 + dy4 - dy1);
+ cairo_stroke(cr);
+
+ cairo_move_to(cr, c->x - dx3, c->y - dy3);
+ cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0);
+ cairo_line_to(cr, pc->x, pc->y);
+ cairo_stroke(cr);
+ } else {
+ cairo_move_to(cr, c->x - dx3, c->y - dy3);
+ cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0);
+ cairo_line_to(cr, pc->x, pc->y);
+ cairo_stroke(cr);
+
+ cairo_move_to(cr, c->x - dx3, c->y - dy3);
+ cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0);
+ cairo_line_to(cr, pe->x, pe->y);
+
+ vertical(&dx1, &dy1, dx3 * 2 - dx0, dy3 * 2 - dy0, 4);
+ forward (&dx4, &dy4, dx3 * 2 - dx0, dy3 * 2 - dy0, 12);
+
+ cairo_move_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1);
+ cairo_line_to(cr, c->x - dx3, c->y - dy3);
+ cairo_line_to(cr, c->x - dx3 + dx4 - dx1, c->y - dy3 + dy4 - dy1);
+ cairo_stroke(cr);
+ }
+
cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
ses_text_a(cr, c->x, (pb->y + c->y) / 2, pb->a);
ses_text_a(cr, c->x, c->y, pc->a);
n = snprintf(text, sizeof(text) - 1, "%lgmV", (int64_t)(el->v * 1000.0 * SHOW_BITS) / SHOW_BITS);
else
n = snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(el->v * 1000000.0 * SHOW_BITS) / SHOW_BITS);
-
+#if 0
// A of line
if (el->aout > 1e-1 || el->aout < -1e-1)
n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgA", (int64_t)(el->aout * SHOW_BITS) / SHOW_BITS);
n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgmA", (int64_t)(el->ain * 1000.0 * SHOW_BITS) / SHOW_BITS);
else
n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lguA", (int64_t)(el->ain * 1000000.0 * SHOW_BITS) / SHOW_BITS);
-
+#endif
int cx = INT_MAX;
int cy = l->y0;
char file[128];
snprintf(file, sizeof(file) - 1, "./simplify_%ld.png", i);
-#if 1
+#if 0
if (count < 60 * 1000)
return 0;
#endif
if (count % 10 == 0) {
-#if 1
+#if 0
static FILE* fp = NULL;
if (!fp)
fp = fopen("v.txt", "w");
if (fp)
fprintf(fp, "%ld, %lg\n", i, f->elines[4]->v);
#endif
-// ses_simplify_draw(f, file, f->x, f->y, f->w, f->h, ns, count);
+ ses_simplify_draw(f, file, f->x, f->y, f->w, f->h, ns, count);
i++;
}
__ses_path_jr(f, bridge);
- if (bridge->n_diodes + bridge->n_NPNs > 0) {
+ if (bridge->n_diodes + bridge->n_NPNs + bridge->n_PNPs > 0) {
__ses_path_va_diode(f, bridge);
__ses_path_jr (f, bridge);
}
- if (bridge->n_transistors > 0) {
- __ses_path_va_transistor(f, bridge);
- __ses_path_jr (f, bridge);
- }
-
int ret = __ses_path_va(f, bridge, &__changed, ns, count);
if (ret < 0)
return ret;
#include"ses_core.h"
+static int __ses_dfs_add_path(scf_vector_t* paths, ses_path_t* path)
+{
+ ScfEpin* p;
+ int j;
+
+ if (scf_vector_add(paths, path) < 0)
+ return -ENOMEM;
+
+ for (j = 0; j < path->pins->size; j++) {
+ p = path->pins->data[j];
+ p->pflag = 1;
+ p->path = (uintptr_t)path;
+ }
+
+ return 0;
+}
+
static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __paths, ses_path_t** ppath)
{
ScfEcomponent* c;
ScfEline* el;
ScfEpin* np;
ScfEpin* p;
- ScfEpin* p2;
size_t i;
size_t j;
- size_t k;
if (SCF_EDA_Status_OFF == rc->status)
return SCF_EDA_Status_OFF;
if (SCF_EDA_NPN == rc->type && SCF_EDA_NPN_E == rp->id)
return SCF_EDA_Path_OFF;
+ if (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E != rp->id)
+ return SCF_EDA_Path_OFF;
+
if (!*ppath) {
*ppath = ses_path_alloc();
if (!*ppath)
if (scf_vector_add((*ppath)->pins, rp) < 0)
return -ENOMEM;
- if (SCF_EDA_NPN != rc->type || SCF_EDA_NPN_E != rp->id)
+ if (!((SCF_EDA_NPN == rc->type && SCF_EDA_NPN_E == rp->id)
+ || (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E == rp->id)))
rp->vflag = 1;
scf_logd("c%ld_p%ld, l%ld, vflag: %d, pflag: %d\n", rp->cid, rp->id, rp->lid, rp->vflag, rp->pflag);
if (SCF_EDA_NPN == rc->type && SCF_EDA_NPN_E != np->id)
continue;
+ if (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E == np->id)
+ continue;
scf_logd("c%ld_p%ld, l%ld, vflag: %d, pflag: %d\n", np->cid, np->id, np->lid, np->vflag, np->pflag);
return -ENOMEM;
}
+ if (SCF_EDA_PNP == rc->type && 0 == (*ppath)->pins->size) {
+
+ if (scf_vector_add((*ppath)->pins, rp) < 0)
+ return -ENOMEM;
+ }
+
if (scf_vector_add((*ppath)->pins, np) < 0)
return -ENOMEM;
- if (SCF_EDA_NPN != rc->type || SCF_EDA_NPN_E != np->id)
+ if (!((SCF_EDA_NPN == rc->type && SCF_EDA_NPN_E == np->id)
+ || (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E == np->id)))
np->vflag = 1;
if (SCF_EDA_PIN_NEG & el->flags) {
- if (scf_vector_add(__paths, *ppath) < 0)
- return -ENOMEM;
-
- for (j = 0; j < (*ppath)->pins->size; j++) {
- p2 = (*ppath)->pins->data[j];
- p2->pflag = 1;
- p2->path = (uintptr_t)*ppath;
- }
+ ret = __ses_dfs_add_path(__paths, *ppath);
+ if (ret < 0)
+ return ret;
*ppath = NULL;
return 0;
if (p->pflag) {
if (p != np && *ppath) {
- scf_logd("branch: c%ld_p%ld, l%ld\n", c->id, p->id, el->id);
+ scf_logd("branch: c%ld_p%ld, l%ld\n\n", c->id, p->id, el->id);
if ((*ppath)->pins->size > 0) {
- if (scf_vector_add(__paths, *ppath) < 0)
- return -ENOMEM;
-
- for (k = 0; k < (*ppath)->pins->size; k++) {
- p2 = (*ppath)->pins->data[k];
- p2->pflag = 1;
- p2->path = (uintptr_t)*ppath;
- }
+
+ ret = __ses_dfs_add_path(__paths, *ppath);
+ if (ret < 0)
+ return ret;
} else
ses_path_free(*ppath);
if (SCF_EDA_Capacitor == rc->type && SCF_EDA_Capacitor != c->type) {
if (*ppath) {
- if (scf_vector_add(__paths, *ppath) < 0)
- return -ENOMEM;
+ if ((*ppath)->pins->size > 0) {
- for (j = 0; j < (*ppath)->pins->size; j++) {
- p2 = (*ppath)->pins->data[j];
- p2->pflag = 1;
- p2->path = (uintptr_t)*ppath;
- }
+ ret = __ses_dfs_add_path(__paths, *ppath);
+ if (ret < 0)
+ return ret;
+ } else
+ ses_path_free(*ppath);
*ppath = NULL;
}
}
- if (SCF_EDA_NPN != c->type || SCF_EDA_NPN_E != p->id)
+ if (!((SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id)
+ || (SCF_EDA_PNP == c->type && SCF_EDA_PNP_E == p->id)))
p->vflag = 1;
+ ses_path_t* tmp = NULL;
+
+ if (SCF_EDA_Capacitor != rc->type && SCF_EDA_Capacitor == c->type) {
+ tmp = *ppath;
+ *ppath = NULL;
+ }
+
ret = __ses_dfs_path(f, c, p, __paths, ppath);
if (ret < 0)
return ret;
if (SCF_EDA_Path_OFF == ret)
p->vflag = 0;
+
+ if (tmp)
+ *ppath = tmp;
}
if (*ppath) {
if (SCF_EDA_Path_OFF == ret) {
rp->vflag = 0;
- scf_logd("off: c%ld_p%ld, l%ld\n", rp->cid, rp->id, rp->lid);
+ scf_logd("off: c%ld_p%ld, l%ld\n\n", rp->cid, rp->id, rp->lid);
} else if (SCF_EDA_Status_OFF == ret)
- scf_logd("off: c%ld_p%ld, l%ld\n", rp->cid, rp->id, rp->lid);
+ scf_logd("off: c%ld_p%ld, l%ld\n\n", rp->cid, rp->id, rp->lid);
}
return ret;
return 0;
}
+static int ses_pin_to_pnp(const ScfEfunction* f, const ScfEpin* vip, int pid)
+{
+ const ScfEcomponent* c;
+ const ScfEline* el = f->elines[vip->lid];
+ const ScfEpin* p;
+
+ int i;
+ for (i = 0; i < el->n_pins; i += 2) {
+
+ c = f->components[el->pins[i]];
+ p = c->pins [el->pins[i + 1]];
+
+ if (p != vip && SCF_EDA_PNP == c->type && pid == p->id)
+ return 1;
+ }
+
+ return 0;
+}
+
static int ses_path_to_npn(const ScfEfunction* f, const ses_path_t* path, int pid)
{
const ScfEpin* p0 = path->pins->data[0];
return ses_pin_to_npn(f, p0, pid) || ses_pin_to_npn(f, p1, pid);
}
-
static int _ses_child_cmp(const void* v0, const void* v1)
{
const ses_path_t* p0 = *(const ses_path_t**)v0;
c0 = f->components[p0->cid];
c1 = f->components[p1->cid];
- if (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_C == p0->id)
+ if ((SCF_EDA_NPN == c0->type && SCF_EDA_NPN_C == p0->id)
+ || (SCF_EDA_PNP == c0->type && SCF_EDA_PNP_C == p0->id))
goto bridge_sp1;
- if (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_C == p1->id)
+ if ((SCF_EDA_NPN == c1->type && SCF_EDA_NPN_C == p1->id)
+ || (SCF_EDA_PNP == c1->type && SCF_EDA_PNP_C == p1->id))
goto bridge_sp0;
if ((SCF_EDA_Diode == c0->type && SCF_EDA_Diode_POS == p0->id)
- || (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_B == p0->id))
+ || (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_B == p0->id)
+ || (SCF_EDA_PNP == c0->type && SCF_EDA_PNP_B == p0->id))
goto bridge_sp1;
if ((SCF_EDA_Diode == c1->type && SCF_EDA_Diode_POS == p1->id)
- || (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_B == p1->id))
+ || (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_B == p1->id)
+ || (SCF_EDA_PNP == c1->type && SCF_EDA_PNP_B == p1->id))
goto bridge_sp0;
- if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_B))
+ if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_B) || ses_pin_to_pnp(f, p0, SCF_EDA_PNP_B))
goto bridge_sp1;
- if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_B))
+ if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_B) || ses_pin_to_pnp(f, p1, SCF_EDA_PNP_B))
goto bridge_sp0;
- if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_C))
+ if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_C) || ses_pin_to_pnp(f, p0, SCF_EDA_PNP_C))
goto bridge_sp1;
- if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_C))
+ if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_C) || ses_pin_to_pnp(f, p1, SCF_EDA_PNP_C))
goto bridge_sp0;
// negative pin of path
if (SCF_EDA_PIN_IN & p1->flags)
goto bridge_sp0;
- if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_B))
+ if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_B) || ses_pin_to_pnp(f, p0, SCF_EDA_PNP_B))
goto bridge_sp1;
- if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_B))
+ if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_B) || ses_pin_to_pnp(f, p1, SCF_EDA_PNP_B))
goto bridge_sp0;
- if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_C))
+ if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_C) || ses_pin_to_pnp(f, p0, SCF_EDA_PNP_C))
goto bridge_sp1;
- if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_C))
+ if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_C) || ses_pin_to_pnp(f, p1, SCF_EDA_PNP_C))
goto bridge_sp0;
c0 = f->components[p0->cid];
c1 = f->components[p1->cid];
if ((SCF_EDA_Diode == c0->type && SCF_EDA_Diode_NEG == p0->id)
- || (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_E == p0->id))
+ || (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_E == p0->id)
+ || (SCF_EDA_PNP == c0->type && SCF_EDA_PNP_E == p0->id))
goto bridge_sp1;
if ((SCF_EDA_Diode == c1->type && SCF_EDA_Diode_NEG == p1->id)
- || (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_E == p1->id))
+ || (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_E == p1->id)
+ || (SCF_EDA_PNP == c1->type && SCF_EDA_PNP_E == p1->id))
goto bridge_sp0;
bridge_sp1:
scf_vector_clear(path->infos, ( void (*)(void*) )free);
path->n_diodes = 0;
path->n_NPNs = 0;
+ path->n_PNPs = 0;
for (i = 0; i < path->pins->size; i++) {
p = path->pins->data[i];
}
}
+ if (SCF_EDA_PNP == c->type) {
+
+ if (SCF_EDA_PNP_B == p->id) {
+ if (!info) {
+ info = calloc(1, sizeof(ses_info_t));
+ if (!info)
+ return -ENOMEM;
+
+ info->i = i - 1;
+ }
+
+ info->n_PNPs++;
+ path->n_PNPs++;
+
+ if (__ses_branch_exist(path, i)) {
+ j = i;
+ goto _add;
+ }
+
+ } else if (SCF_EDA_PNP_C == p->id) {
+ if (info) {
+ if (info->n_diodes + info->n_NPNs + info->n_PNPs > 0) {
+ j = i - 2;
+ goto _add;
+ }
+
+ free(info);
+ info = NULL;
+ }
+ }
+ continue;
+ }
+
j = i - 1;
_add:
if (info) {
int i;
path->n_NPNs = 0;
+ path->n_PNPs = 0;
path->n_diodes = 0;
path->n_capacitors = 0;
else if (SCF_EDA_NPN_C == p->id)
path->n_transistors++;
+ } else if (SCF_EDA_PNP == c->type) {
+
+ if (SCF_EDA_PNP_B == p->id)
+ path->n_PNPs++;
+
+ else if (SCF_EDA_PNP_C == p->id)
+ path->n_transistors++;
+
} else if (SCF_EDA_Capacitor == c->type) {
if (0 == p->id)
ret = _topo_bridge_connections(f, ctx->paths);
if (ret < 0)
return ret;
-#if 1
-// if (count > 30000) {
- R = f->components[10];
-
- double w0 = 2 * 3.1415926 * 100;
- double w1 = 2 * 3.1415926 * 1000;
- double w2 = 2 * 3.1415926 * 5000;
- double r0 = sin(w0 * ns * (count - 30000) / 1e9);
- double r1 = sin(w1 * ns * (count - 30000) / 1e9);
- double r2 = sin(w2 * ns * (count - 30000) / 1e9);
- R->dr = 10.0 * (r0 + r1 + r2);
-
- scf_logi("### c%ld->r: %lg, r: %lg\n", R->id, R->r, R->dr);
-// }
-#endif
+
int i;
for (i = 0; i < ctx->paths->size; i++) {
path = ctx->paths->data[i];
#include"ses_core.h"
+int __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe, int vinit)
+{
+ ScfEcomponent* c2;
+ ScfEline* el;
+ ScfEpin* p2;
+
+ ScfEcomponent* B = f->components[0];
+ ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS];
+ ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG];
+
+ size_t i;
+ double Voff = SCF_EDA_Diode == c->type ? SCF_EDA_V_Diode_OFF : SCF_EDA_V_NPN_OFF;
+ double Von = SCF_EDA_Diode == c->type ? SCF_EDA_V_Diode_ON : SCF_EDA_V_NPN_ON;
+
+ pb->v = f->elines[pb->lid]->v;
+ pe->v = f->elines[pe->lid]->v;
+
+ if (pb->v < SCF_EDA_V_MIN) {
+
+ if (pe->v < SCF_EDA_V_MIN)
+ return 0;
+
+ pb->v = pe->v + Von;
+
+ if (pb->v > Bp->v) {
+ pb->v = Bp->v;
+ if (!c->lock)
+ c->status = SCF_EDA_Status_OFF;
+ } else
+ c->status = SCF_EDA_Status_ON;
+ goto _changed;
+
+ } else if (pe->v < SCF_EDA_V_MIN) {
+ pe->v = pb->v - Von;
+
+ if (pe->v < Bn->v) {
+ pe->v = Bn->v;
+ if (!c->lock)
+ c->status = SCF_EDA_Status_OFF;
+ } else
+ c->status = SCF_EDA_Status_ON;
+ goto _changed;
+
+ } else if (pb->v - pe->v < Voff) {
+
+ if (c->status != SCF_EDA_Status_OFF) {
+ if (!c->lock)
+ c->status = SCF_EDA_Status_OFF;
+ goto _changed;
+ }
+ } else if (SCF_EDA_Status_ON != c->status) {
+ c->status = SCF_EDA_Status_ON;
+ goto _changed;
+ }
+
+ return 0;
+
+_changed:
+ if (SCF_EDA_NPN == c->type || SCF_EDA_PNP == c->type) {
+
+ p2 = c->pins [SCF_EDA_NPN_C];
+ el = f->elines[p2->lid];
+ el->vinit = vinit;
+
+ for (i = 0; i + 1 < el->n_pins; i += 2) {
+
+ c2 = f->components[el->pins[i]];
+ p2 = c->pins [el->pins[i + 1]];
+
+ if ((SCF_EDA_NPN == c2->type || SCF_EDA_PNP == c2->type) && SCF_EDA_NPN_B == p2->id) {
+ c2->status = SCF_EDA_Status_ON;
+ c2->lock = 1;
+
+ scf_loge("\033[35mc%ld, status: %d\033[0m\n", c2->id, c2->status);
+ }
+ }
+ }
+
+ scf_loge("\033[34mc%ld, status: %d, pb->v: %lg, pe->v: %lg, diff: %lg, Von: %lg, Voff: %lg\033[0m\n",
+ c->id, c->status, pb->v, pe->v, pb->v - pe->v, Von, Voff);
+ return 1;
+}
+
static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, int n,
double* a, int* changed, int64_t ns, int64_t count)
{
scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, r: %lg, p->a: %lg, a: %lg, p->pr: %lg, e%ld->v: %lg\n\n",
path->index, i, p->cid, p->id, p->v, dv, r, p->a, a, p->pr, el->id, el->v);
- if (SCF_EDA_Diode == c->type) {
+ switch (c->type) {
+ case SCF_EDA_Diode:
- if (SCF_EDA_Diode_NEG == p->id) {
+ assert(SCF_EDA_Diode_NEG == p->id);
p2 = path->pins->data[i - 1];
*changed += __ses_status_check(f, c, p2, p, 1);
- }
+ break;
- } else if (SCF_EDA_NPN == c->type) {
+ case SCF_EDA_NPN:
- if (SCF_EDA_NPN_E == p->id) {
+ assert(SCF_EDA_PNP_E == p->id);
p2 = path->pins->data[i - 1];
if (SCF_EDA_NPN_B == p2->id) {
c->pins[SCF_EDA_NPN_C]->aconst = 1;
}
- }
- }
+ break;
+
+ case SCF_EDA_PNP:
+
+ if (SCF_EDA_PNP_B == p->id) {
+ p2 = path->pins->data[i - 1];
+
+ assert(SCF_EDA_PNP_E == p2->id);
+
+ *changed += __ses_status_check(f, c, p2, p, 1);
+
+ c->pins[SCF_EDA_PNP_C]->aconst = 1;
+ }
+ break;
+ default:
+ break;
+ };
r = 0;
} else {
scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, r: %lg, p->a: %lg, a: %lg, p->pr: %lg, e%ld->v: %lg\n\n",
path->index, i, p->cid, p->id, p->v, dv, r, p->a, a, p->pr, el->id, el->v);
- if (SCF_EDA_Diode == c->type) {
+ switch (c->type) {
+ case SCF_EDA_Diode:
- if (SCF_EDA_Diode_NEG == p->id) {
+ assert(SCF_EDA_Diode_NEG == p->id);
p2 = path->pins->data[i - 1];
*changed += __ses_status_check(f, c, p2, p, 1);
- }
+ break;
- } else if (SCF_EDA_NPN == c->type) {
+ case SCF_EDA_NPN:
- if (SCF_EDA_NPN_E == p->id) {
+ assert(SCF_EDA_PNP_E == p->id);
p2 = path->pins->data[i - 1];
if (SCF_EDA_NPN_B == p2->id) {
c->pins[SCF_EDA_NPN_C]->aconst = 1;
}
- }
- }
+ break;
+
+ case SCF_EDA_PNP:
+
+ if (SCF_EDA_PNP_B == p->id) {
+ p2 = path->pins->data[i - 1];
+
+ assert(SCF_EDA_PNP_E == p2->id);
+
+ *changed += __ses_status_check(f, c, p2, p, 1);
+
+ c->pins[SCF_EDA_PNP_C]->aconst = 1;
+ }
+ break;
+ default:
+ break;
+ };
r = 0;
} else {
p1->a = (1 + p1->hfe) * a;
p1->aconst = 1;
+ a = p1->a;
+
+ } else if (SCF_EDA_PNP == c->type && SCF_EDA_PNP_B == p->id) {
+
+ ses_ui_r(&p->dr, NULL, SCF_EDA_V_PNP_ON, 0, a, 0);
+
+ p->dr -= p->r;
+
+ p1 = c->pins[SCF_EDA_PNP_C];
+ p1->a = p1->hfe * a;
+ p1->aconst = 1;
+
+ scf_logw("c%ldp%ld, v: %lg, r: %lg, a: %lg, dr: %lg, c%ldp%ld->a: %lg\n",
+ p->cid, p->id, SCF_EDA_V_PNP_ON, p->r, a, p->dr, p1->cid, p1->id, p1->a);
+
+ p1 = c->pins[SCF_EDA_PNP_E];
+ p1->a = (1 + p1->hfe) * a;
+ p1->aconst = 1;
+
a = p1->a;
}
}
cp1->sr = child->sr;
cp1->pr = child->pr;
- if (child->n_diodes + child->n_NPNs > 0) {
+ if (child->n_diodes + child->n_NPNs + child->n_PNPs > 0) {
int ret = __ses_path_va_diode(f, child);
if (ret < 0)
cp0->a = ca;
- if (child->n_diodes + child->n_NPNs > 0)
+ if (child->n_diodes + child->n_NPNs + child->n_PNPs > 0)
__ses_path_dr_forward(f, child, 0, child->pins->size - 1, ca);
ok:
}
}
-void __ses_path_dr_reverse(ScfEfunction* f, ses_path_t* path, int i, int j, double a)
-{
- ScfEpin* p = path->pins->data[i];
- ScfEpin* p1 = path->pins->data[j];
-
- double r;
-
- int k;
- for (k = j; k >= i; k--) {
-
- ScfEcomponent* c;
-
- p = path->pins->data[k];
- c = f->components[p->cid];
-
- if (SCF_EDA_Diode == c->type && SCF_EDA_Diode_NEG == p->id) {
-
- ses_ui_r(&p->dr, NULL, SCF_EDA_V_Diode_ON, 0, a, 0);
-
- p->dr -= p->r;
-
- scf_logw("c%ldp%ld, v: %lg, r: %lg, a: %lg, dr: %lg\n", p->cid, p->id, SCF_EDA_V_Diode_ON, p->r, a, p->dr);
-
- p1 = c->pins[SCF_EDA_Diode_POS];
- p1->a = a;
-
- } else if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_B == p->id) {
-
- p1 = c->pins[SCF_EDA_NPN_E];
- p1->a = a;
- p1->aconst = 1;
-
- p1 = c->pins[SCF_EDA_NPN_C];
-
- a /= (1 + p1->hfe);
-
- p1->a = p1->hfe * a;
- p1->aconst = 1;
-
- ses_ui_r(&p->dr, NULL, SCF_EDA_V_NPN_ON, 0, a, 0);
-
- p->dr -= p->r;
-
- scf_logw("c%ldp%ld, v: %lg, r: %lg, a: %lg, dr: %lg\n", p->cid, p->id, SCF_EDA_V_NPN_ON, p->r, a, p->dr);
- }
- }
-}
-
static void __ses_path_a_diode(ScfEfunction* f, ses_path_t* path, int i, int k, double cv, double* a)
{
ses_info_t* info;
pi = path->pins->data[i];
pj = path->pins->data[info->i];
- v -= info->n_diodes * SCF_EDA_V_Diode_ON + info->n_NPNs * SCF_EDA_V_NPN_ON;
+ v -= info->n_diodes * SCF_EDA_V_Diode_ON;
+ v -= info->n_NPNs * SCF_EDA_V_NPN_ON;
+ v -= info->n_PNPs * SCF_EDA_V_PNP_ON;
__ses_path_pr(f, path, i, info->i, NULL, &_r);
ScfEpin* pi;
ScfEpin* pj;
- if ((path->n_diodes + path->n_NPNs) * 2 >= path->pins->size) {
+ if ((path->n_diodes + path->n_NPNs + path->n_PNPs) * 2 >= path->pins->size) {
scf_loge("all components are diodes\n\n");
return -1;
}
- if (path->n_diodes + path->n_NPNs <= 0)
+ if (path->n_diodes + path->n_NPNs + path->n_PNPs <= 0)
return 0;
p0 = path->pins->data[0];
pi->v = el->v;
assert((SCF_EDA_Diode == c->type && SCF_EDA_Diode_POS == pi->id)
- || (SCF_EDA_NPN == c->type && SCF_EDA_NPN_B == pi->id));
+ || (SCF_EDA_NPN == c->type && SCF_EDA_NPN_B == pi->id)
+ || (SCF_EDA_PNP == c->type && SCF_EDA_PNP_E == pi->id));
__ses_path_capacitors(f, path, i, path->pins->size - 1, &cv);
__ses_path_capacitors(f, path, i, info->i, &cv2);
pi->v = p0->v - v - cv2;
- pj->v = pi->v - info->n_diodes * SCF_EDA_V_Diode_ON - info->n_NPNs * SCF_EDA_V_NPN_ON;
+ pj->v = pi->v - info->n_diodes * SCF_EDA_V_Diode_ON
+ - info->n_NPNs * SCF_EDA_V_NPN_ON
+ - info->n_PNPs * SCF_EDA_V_PNP_ON;
scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, cv2: %lg, r: %lg, v: %lg, a: %lg\n",
p0->cid, p0->id, p0->v, pi->cid, pi->id, pi->v, pj->cid, pj->id, pj->v, cv2, r, v, a);
+++ /dev/null
-#include"ses_core.h"
-
-void __ses_path_dr_transistor(ScfEfunction* f, ses_path_t* path, int i, int j)
-{
- ScfEpin* p = path->pins->data[i];
- ScfEpin* p1 = path->pins->data[j];
-
- double v = p->v - p1->v;
- double r;
- double dr;
-
- __ses_path_sr(f, path, i, j, &r);
-
- ses_ui_r(&dr, NULL, v, 0, p->a, 0);
-
- p->dr = dr - r;
-
- scf_logi("c%ldp%ld--c%ldp%ld, v: %lg, r: %lg, dr: %lg, p->sr: %lg, p->a: %lg, p->dr: %lg\n",
- p->cid, p->id, p1->cid, p1->id, v, r, dr, p->sr, p->a, p->dr);
-}
-
-int __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe, int vinit)
-{
- ScfEcomponent* c2;
- ScfEline* el;
- ScfEpin* p2;
-
- ScfEcomponent* B = f->components[0];
- ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS];
- ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG];
-
- size_t i;
- double Voff = SCF_EDA_Diode == c->type ? SCF_EDA_V_Diode_OFF : SCF_EDA_V_NPN_OFF;
- double Von = SCF_EDA_Diode == c->type ? SCF_EDA_V_Diode_ON : SCF_EDA_V_NPN_ON;
-
- pb->v = f->elines[pb->lid]->v;
- pe->v = f->elines[pe->lid]->v;
-
- if (pb->v < SCF_EDA_V_MIN) {
-
- if (pe->v < SCF_EDA_V_MIN)
- return 0;
-
- pb->v = pe->v + Von;
-
- if (pb->v > Bp->v) {
- pb->v = Bp->v;
- if (!c->lock)
- c->status = SCF_EDA_Status_OFF;
- } else
- c->status = SCF_EDA_Status_ON;
- goto _changed;
-
- } else if (pe->v < SCF_EDA_V_MIN) {
- pe->v = pb->v - Von;
-
- if (pe->v < Bn->v) {
- pe->v = Bn->v;
- if (!c->lock)
- c->status = SCF_EDA_Status_OFF;
- } else
- c->status = SCF_EDA_Status_ON;
- goto _changed;
-
- } else if (pb->v - pe->v < Voff) {
-
- if (c->status != SCF_EDA_Status_OFF) {
- if (!c->lock)
- c->status = SCF_EDA_Status_OFF;
- goto _changed;
- }
- } else if (SCF_EDA_Status_ON != c->status) {
- c->status = SCF_EDA_Status_ON;
- goto _changed;
- }
-
- return 0;
-
-_changed:
- if (SCF_EDA_NPN == c->type) {
-
- p2 = c->pins [SCF_EDA_NPN_C];
- el = f->elines[p2->lid];
- el->vinit = vinit;
-
- for (i = 0; i + 1 < el->n_pins; i += 2) {
-
- c2 = f->components[el->pins[i]];
- p2 = c->pins [el->pins[i + 1]];
-
- if (SCF_EDA_NPN == c2->type && SCF_EDA_NPN_B == p2->id) {
- c2->status = SCF_EDA_Status_ON;
- c2->lock = 1;
-
- scf_loge("\033[35mc%ld, status: %d\033[0m\n", c2->id, c2->status);
- }
- }
- }
-
- scf_loge("\033[34mc%ld, status: %d, pb->v: %lg, pe->v: %lg, diff: %lg, Von: %lg, Voff: %lg\033[0m\n",
- c->id, c->status, pb->v, pe->v, pb->v - pe->v, Von, Voff);
- return 1;
-}
-
-int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
-{
- ScfEcomponent* c;
- ScfEline* el;
- ScfEpin* p0;
- ScfEpin* pj;
-
- ScfEpin* p;
- ScfEpin* pc;
- ScfEpin* pb;
-
- int i;
- int j = path->pins->size - 1;
-
- p0 = path->pins->data[0];
- pj = path->pins->data[j];
-
- el = f->elines[p0->lid];
- p0->v = el->v;
-
- el = f->elines[pj->lid];
- pj->v = el->v;
-
- for (i = path->pins->size - 1; i >= 0; i--) {
- pc = path->pins->data[i];
- pj = path->pins->data[j];
-
- double v;
- double a;
- double pr;
- double _pr;
-
- c = f->components[pc->cid];
-
- scf_logd("i: %d, c%ldp%ld--c%ldp%ld, pc->v: %lg, pc->a: %lg\n", i, p0->cid, p0->id, pc->cid, pc->id, pc->v, pc->a);
-
- if (SCF_EDA_NPN != c->type || SCF_EDA_NPN_C != pc->id) {
-
- if (j < path->pins->size - 1) {
- pc->a = pj->a;
-
- if (pc->lid != pj->lid) {
- __ses_path_pr(f, path, i, j, NULL, &pr);
-
- ses_ir_u(&v, NULL, pj->a, 0, pr, 0);
-
- pc->v = p0->v - v;
-
- if (path->childs)
- __ses_path_split_i(f, path, i, j, pj->a, &pc->a);
-
- } else
- pc->v = pj->v;
-
- j = i;
- }
- continue;
- }
-
- if (!pc->aconst)
- break;
-
- pb = c->pins[SCF_EDA_NPN_B];
- pc->a = pc->hfe * pb->a;
-
- __ses_path_pr(f, path, 0, i, NULL, &pr);
-
- ses_ir_u(&v, NULL, pc->a, 0, pr, 0);
-
- pc->v = p0->v - v;
-
- scf_logi("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, pc->pr: %lg, pb c%ldp%ld->a: %lg, pj: c%ldp%ld->v: %lg\n",
- i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, pc->pr, pb->cid, pb->id, pb->a, pj->cid, pj->id, pj->v);
-
- if (pc->v < pj->v) {
- v = p0->v - pj->v;
-
- __ses_path_pr(f, path, 0, j, NULL, &_pr);
-
- ses_ur_i(&a, NULL, v, 0, _pr, 0);
-
- if (path->childs)
- __ses_path_split_i(f, path, 0, j, a, &a);
-
- ses_ir_u(&v, NULL, a, 0, pr, 0);
-
- pc->v = p0->v - v;
- pc->a = a;
-
- scf_logi("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, _pr: %lg pc->pr: %lg\n",
- i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, _pr, pc->pr);
- }
-
- el = f->elines[pc->lid];
- el->v = pc->v;
-
- scf_logw("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, pc->dr: %lg\n",
- i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, pc->dr);
-
- a = pc->a;
-
- if (path->childs) {
- __ses_path_split_i(f, path, i, j, a, &pc->a);
-
- if (i > 0) {
- p = path->pins->data[i - 1];
- p->a = a;
- p->v = el->v;
-
- __ses_path_split_i(f, path, 0, i - 1, a, &p->a);
- }
- } else
- p0->a = a;
-
- __ses_path_dr_transistor(f, path, i, j);
-
- scf_loge("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, pc->dr: %lg\n\n",
- i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, pc->dr);
-
- j = i;
- }
-
- return 0;
-}
-
-static int ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
-{
- ses_path_t* child;
- ScfEcomponent* B;
- ScfEpin* p0;
- ScfEpin* p1;
- ScfEpin* Bp;
- ScfEpin* Bn;
-
- size_t i;
- size_t j;
- size_t k;
-
- if (!path || path->pins->size < 2)
- return -EINVAL;
-
- if (2 == path->pins->size)
- return 0;
-
- B = f->components[0];
- Bp = B->pins[SCF_EDA_Battery_POS];
- Bn = B->pins[SCF_EDA_Battery_NEG];
-
- p0 = path->pins->data[0];
- p1 = path->pins->data[path->pins->size - 1];
-
- __ses_path_jr(f, path);
-
- int ret = __ses_path_va_transistor(f, path);
- if (ret < 0)
- return ret;
-
- if (path->childs) {
- for (j = 0; j < path->childs->size; j++) {
- child = path->childs->data[j];
-
- ret = ses_path_va_transistor(f, child);
- if (ret < 0)
- return ret;
- }
- }
-
- return 0;
-}
-
-static int _va_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
-{
- ses_path_t* path;
-
- int i;
-
- for (i = 0; i < ctx->paths->size; i++) {
- path = ctx->paths->data[i];
-
- scf_logi("i: %d, path->index: %d\n", i, path->index);
-
- int ret = ses_path_va_transistor(f, path);
- if (ret < 0)
- return ret;
-
- printf("\n");
- }
-
- return 0;
-}
-
-ses_step_t ses_step_va_transistor =
-{
- .name = "va_transistor",
-
- .handler = _va_transistor_handler,
-};
extern ses_step_t ses_step_battery;
extern ses_step_t ses_step_dc_input;
-//extern ses_step_t ses_step_ac_start;
extern ses_step_t ses_step_dc_diode;
-extern ses_step_t ses_step_dc_transistor;
-
-//extern ses_step_t ses_step_ac_transistor;
-//extern ses_step_t ses_step_ac_diode;
+extern ses_step_t ses_step_dc_npn;
+extern ses_step_t ses_step_dc_pnp;
extern ses_step_t ses_step_topo;
extern ses_step_t ses_step_va_capacitor;
extern ses_step_t ses_step_a_stat;
-extern ses_step_t ses_step_a_balance;
extern ses_step_t ses_step_output;
extern ses_step_t ses_step_simplify;
static ses_step_t* ses_steps_1[] =
{
&ses_step_dc_diode,
- &ses_step_dc_transistor,
+ &ses_step_dc_npn,
+ &ses_step_dc_pnp,
&ses_step_topo,
-// &ses_step_jr,
-
&ses_step_va_diode,
- &ses_step_va_transistor,
-// &ses_step_jr,
&ses_step_va,
&ses_step_status,
};
static ses_step_t* ses_steps_2[] =
{
&ses_step_open,
-// &ses_step_simplify2,
&ses_step_va_nodes,
- &ses_step_va_capacitor,
+// &ses_step_va_capacitor,
// &ses_step_a_stat,
printf(" ");
printf(")");
- if (edge->npn_b)
- printf(" b[%d]", edge->npn_b->index);
+ if (edge->edge_b)
+ printf(" b[%d]", edge->edge_b->index);
printf("; ");
}
#CFILES += main.c
#CFILES += test.c
-CFILES += fft.c
+#CFILES += fft.c
+CFILES += pnp.c
CFILES += ../scf_eda_pack.c
CFILES += ../pack/scf_pack.c
--- /dev/null
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include"ses_core.h"
+
+int main(int argc, char* argv[])
+{
+ ScfEcomponent* B;
+
+ ScfEcomponent* R0;
+ ScfEcomponent* C0;
+ ScfEcomponent* T0;
+
+ ScfEcomponent* R1;
+ ScfEcomponent* R2;
+ ScfEcomponent* R3;
+ ScfEcomponent* C1;
+ ScfEcomponent* C2;
+ ScfEcomponent* C3;
+
+ ScfEcomponent* R4;
+ ScfEcomponent* R5;
+
+ ScfEfunction* f;
+ ScfEboard* b;
+
+ b = scf_eboard__alloc();
+ f = scf_efunction__alloc("sin_oscillator");
+
+ EDA_INST_ADD_COMPONENT(f, B, SCF_EDA_Battery);
+
+ B->pins[SCF_EDA_Battery_NEG]->flags = SCF_EDA_PIN_NEG;
+ B->pins[SCF_EDA_Battery_POS]->flags = SCF_EDA_PIN_POS;
+
+ EDA_INST_ADD_COMPONENT(f, R0, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, C0, SCF_EDA_Capacitor);
+ EDA_INST_ADD_COMPONENT(f, T0, SCF_EDA_PNP);
+
+ 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, C1, SCF_EDA_Capacitor);
+ EDA_INST_ADD_COMPONENT(f, C2, SCF_EDA_Capacitor);
+ EDA_INST_ADD_COMPONENT(f, C3, SCF_EDA_Capacitor);
+
+ EDA_INST_ADD_COMPONENT(f, R4, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, R5, SCF_EDA_Resistor);
+
+ EDA_PIN_ADD_PIN(B, SCF_EDA_Battery_POS, R0, 1);
+ EDA_PIN_ADD_PIN(R0, 1, C0, 1);
+ EDA_PIN_ADD_PIN(R0, 0, C0, 0);
+ EDA_PIN_ADD_PIN(R0, 0, T0, SCF_EDA_NPN_E);
+ EDA_PIN_ADD_PIN(T0, SCF_EDA_NPN_C, R5, 1);
+ EDA_PIN_ADD_PIN(R5, 0, B, SCF_EDA_Battery_NEG);
+
+ EDA_PIN_ADD_PIN(B, SCF_EDA_Battery_POS, R4, 1);
+ EDA_PIN_ADD_PIN(R4, 0, R3, 1);
+ EDA_PIN_ADD_PIN(R3, 1, T0, SCF_EDA_NPN_B);
+ EDA_PIN_ADD_PIN(R3, 0, B, SCF_EDA_Battery_NEG);
+
+ EDA_PIN_ADD_PIN(C1, 1, T0, SCF_EDA_NPN_C);
+ EDA_PIN_ADD_PIN(C1, 0, C2, 1);
+ EDA_PIN_ADD_PIN(C2, 0, C3, 1);
+ EDA_PIN_ADD_PIN(C3, 0, T0, SCF_EDA_NPN_B);
+
+ EDA_PIN_ADD_PIN(C1, 0, R1, 1);
+ EDA_PIN_ADD_PIN(C2, 0, R2, 1);
+ EDA_PIN_ADD_PIN(R1, 0, B, SCF_EDA_Battery_NEG);
+ EDA_PIN_ADD_PIN(R2, 0, B, SCF_EDA_Battery_NEG);
+
+ T0->pins[SCF_EDA_NPN_C]->flags |= SCF_EDA_PIN_OUT;
+ T0->pins[SCF_EDA_NPN_C]->hfe = 150;
+
+ R1->r = 1000 * 10;
+ R2->r = 1000 * 10;
+ R3->r = 1000 * 10;
+ R4->r = 1000 * 10;
+ R5->r = 1000;
+ R0->r = 1000;
+ C0->uf = 10;
+ C1->uf = 0.01;
+ C2->uf = 0.01;
+ C3->uf = 0.01;
+ C1->r = 1;
+ C2->r = 1;
+ C3->r = 1;
+
+ scf_eboard__add_function(b, f);
+
+ int len = 0;
+ uint8_t* buf = NULL;
+
+ ScfEboard_pack(b, &buf, &len);
+ ScfEboard_free(b);
+ b = NULL;
+
+ FILE* fp = fopen("./pnp_oscillator.cpk", "wb");
+ if (!fp)
+ return -EINVAL;
+
+ fwrite(buf, len, 1, fp);
+ fclose(fp);
+
+ return 0;
+}