From: yu.dongliang <18588496441@163.com> Date: Wed, 5 Jun 2024 13:52:32 +0000 (+0800) Subject: support Inductor for examples/colpitts_oscillator.cpk X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=ee79e0cfe0fac8279d2f8bff684a7c9b09b22026;p=ses.git support Inductor for examples/colpitts_oscillator.cpk --- diff --git a/Makefile b/Makefile index 9619bf1..4535c6c 100644 --- a/Makefile +++ b/Makefile @@ -4,12 +4,12 @@ CFILES += scf_eda_pack.c CFILES += pack/scf_pack.c CFILES += ses_layout.c +CFILES += ses_layout_topo.c CFILES += ses_graph.c CFILES += ses_utils.c CFILES += ses_path.c CFILES += ses_flow.c -CFILES += ses_mesh_analysis.c CFILES += ses_node_analysis.c CFILES += ses_steps.c @@ -30,7 +30,6 @@ CFILES += ses_step_va_line.c CFILES += ses_step_open.c CFILES += ses_step_va_nodes.c -CFILES += ses_step_va_capacitor.c CFILES += ses_step_a_stat.c diff --git a/examples/colpitts_oscillator.cpk b/examples/colpitts_oscillator.cpk new file mode 100644 index 0000000..4d1e411 Binary files /dev/null and b/examples/colpitts_oscillator.cpk differ diff --git a/main.c b/main.c index c608d2a..9757d9a 100644 --- a/main.c +++ b/main.c @@ -107,7 +107,7 @@ int main(int argc, char* argv[]) printf("f: %s\n", f->name); - ses_steps_analyse(f, 1000, 1); + ses_steps_analyse(f, 100, 76000); } #endif diff --git a/scf_eda_pack.c b/scf_eda_pack.c index c837e73..ab2f548 100644 --- a/scf_eda_pack.c +++ b/scf_eda_pack.c @@ -21,7 +21,7 @@ static scf_edata_t component_datas[] = {SCF_EDA_Resistor, 0, 0, 0, 0, 1e4, 0, 0, 0}, {SCF_EDA_Capacitor, 0, 0, 0, 0, 10, 0.1, 0, 0}, - {SCF_EDA_Inductor, 0, 0, 0, 0, 0, 0, 1e3, 0}, + {SCF_EDA_Inductor, 0, 0, 0, 0, 10, 0, 1e3, 0}, }; static scf_edata_t pin_datas[] = diff --git a/ses_core.h b/ses_core.h index abdbf99..f4eff2a 100644 --- a/ses_core.h +++ b/ses_core.h @@ -10,7 +10,6 @@ typedef struct ses_path_s ses_path_t; typedef struct ses_edge_s ses_edge_t; typedef struct ses_flow_s ses_flow_t; typedef struct ses_node_s ses_node_t; -typedef struct ses_mesh_s ses_mesh_t; typedef struct ses_info_s ses_info_t; typedef struct ses_data_s ses_data_t; @@ -105,9 +104,7 @@ struct ses_path_s double v; double a; - double a0; - double cda; int type; int index; @@ -124,9 +121,6 @@ struct ses_path_s struct ses_edge_s { - int refs; - int index; - ses_path_t* path; int vip_m; int vip_n; @@ -144,7 +138,8 @@ struct ses_edge_s double a; double a0; - uint8_t vflag:1; + int index; + uint8_t bflag:1; }; @@ -156,25 +151,13 @@ struct ses_node_s double a; double a0; + int64_t lid; + int index; int vip_i; ses_path_t* path; }; -struct ses_mesh_s -{ - scf_vector_t* edges; - - int n_diodes; - int n_NPNs; - - double cv; - double r; - - double a; - double a0; -}; - struct ses_ctx_s { scf_vector_t* paths; @@ -213,15 +196,6 @@ ses_edge_t* ses_edge_alloc(ses_path_t* path, int first, int last); void ses_edge_free (ses_edge_t* edge); void ses_edge_print(ses_edge_t* edge); -ses_mesh_t* ses_mesh_alloc(); -void ses_mesh_free (ses_mesh_t* mesh); -void ses_mesh_print(ses_mesh_t* mesh); - -int ses_mesh_ref_edge(ses_mesh_t* mesh, ses_edge_t* edge); -int ses_mesh_add_edge(ses_mesh_t* mesh, ses_path_t* path, int m, int n, ses_edge_t** pp); -void ses_meshs_print(scf_vector_t* meshs); -void ses_meshs_free (scf_vector_t* meshs); - ses_node_t* ses_node_alloc(); void ses_node_free (ses_node_t* node); void ses_node_print(ses_node_t* node); @@ -243,6 +217,7 @@ void ses_ctx_free (ses_ctx_t* ctx); void ses_components_print(ScfEfunction* f); void ses_elines_print (ScfEfunction* f); +int ses_layout_paths (ScfEfunction* f, scf_vector_t* paths); int ses_layout_board (ScfEboard* b); int ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count); @@ -252,33 +227,23 @@ int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, se int ses_flow_find_pos (ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f); int ses_flow_find_neg (ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f); -int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path); -int __ses_path_va_diode (ScfEfunction* f, ses_path_t* path); -int __ses_path_va_bridge (ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns, int64_t count); -int __ses_path_va_branch (ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count); +int __ses_path_va_diode (ScfEfunction* f, ses_path_t* path); +int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns, int64_t count); +int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count); void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double la, double* a); int __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe, int vinit); -int __ses_topo_paths (ScfEfunction* f, scf_vector_t* paths); void __ses_status_check_line(ScfEfunction* f, ScfEline* el, int* changed); -int __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv); - -int __ses_meshs_PPN (ScfEfunction* f, ses_flow_t* flow, ses_path_t* bridge, scf_vector_t** meshs); -int __ses_meshs_path (ScfEfunction* f, ses_path_t* path, scf_vector_t** meshs); - -int __ses_meshs_path_solve(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int* changed, int64_t ns, int64_t count); -int __ses_meshs_PPN_solve (ScfEfunction* f, ses_flow_t* flow, ses_path_t* bridge, int* changed, int64_t ns, int64_t count); -int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t** nodes); +int __ses_nodes_path (ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t** pnodes, scf_vector_t** pedges); int __ses_nodes_path_solve(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int* changed, int64_t ns, int64_t count); -int __ses_path_jr (ScfEfunction* f, ses_path_t* path); -void __ses_path_pr (ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* child, double* r); -void __ses_path_jpr(ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* child, double* jr); -void __ses_path_sr (ScfEfunction* f, ses_path_t* path, int i, int j, double* r); -void __ses_path_jsr(ScfEfunction* f, ses_path_t* path, int i, int j, double* jr); +int __ses_path_jr(ScfEfunction* f, ses_path_t* path); +void __ses_path_pr(ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* child, double* r); +void __ses_path_sr(ScfEfunction* f, ses_path_t* path, int i, int j, double* r); +void __ses_path_lc(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv, double* lv, double* uf, double* uh, double* la); int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count); int __ses_path_va2(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count); diff --git a/ses_layout.c b/ses_layout.c index b4aaeb7..12c1389 100644 --- a/ses_layout.c +++ b/ses_layout.c @@ -636,7 +636,7 @@ static int __ses_layout_lines4(ScfEfunction* f) if (!paths) return -ENOMEM; - int ret = __ses_topo_paths(f, paths); + int ret = ses_layout_paths(f, paths); if (ret < 0) goto end; @@ -1604,8 +1604,6 @@ int ses_layout_function(ScfEfunction* f, int d) f->w = 0; f->h = 0; -// qsort(f->elines, f->n_elines, sizeof(ScfEline*), eline_cmp); - int ret = __ses_layout_lines(f, d); if (ret < 0) return ret; diff --git a/ses_layout_topo.c b/ses_layout_topo.c new file mode 100644 index 0000000..79d7a19 --- /dev/null +++ b/ses_layout_topo.c @@ -0,0 +1,400 @@ +#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 __layout_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __paths, ses_path_t** ppath) +{ + ScfEcomponent* c; + ScfEline* el; + ScfEpin* np; + ScfEpin* p; + + int64_t i; + int64_t j; + + if (SCF_EDA_Status_OFF == rc->status) + return SCF_EDA_Status_OFF; + + if (SCF_EDA_Diode == rc->type && SCF_EDA_Diode_NEG == rp->id) + return SCF_EDA_Path_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) + return -ENOMEM; + } + + if (scf_vector_add((*ppath)->pins, rp) < 0) + return -ENOMEM; + + 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%ldp%ld, l%ld, vflag: %d, pflag: %d\n", rp->cid, rp->id, rp->lid, rp->vflag, rp->pflag); + + int ret = 0; + + for (i = 0; i < rc->n_pins; i++) { + np = rc->pins[i]; + + if (np->vflag) + continue; + + 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%ldp%ld, l%ld, vflag: %d, pflag: %d\n", np->cid, np->id, np->lid, np->vflag, np->pflag); + + el = f->elines[np->lid]; + + if (SCF_EDA_PIN_POS & el->flags) { + scf_logd("pos l%ld\n\n", el->id); + + ret = SCF_EDA_Path_OFF; + continue; + } + + if (!*ppath) { + *ppath = ses_path_alloc(); + if (!*ppath) + 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) + || (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E == np->id))) + np->vflag = 1; + + if (SCF_EDA_PIN_NEG & el->flags) { + scf_logd("neg l%ld\n\n", el->id); + + ret = __ses_dfs_add_path(__paths, *ppath); + if (ret < 0) + return ret; + + *ppath = NULL; + return 0; + } + + ret = 0; + + for (j = 0; j + 1 < el->n_pins; j += 2) { + + c = f->components[el->pins[j]]; + p = c->pins [el->pins[j + 1]]; + + if (p->pflag) { + if (p != np && *ppath) { + scf_logd("branch: c%ld_p%ld, l%ld\n\n", c->id, p->id, el->id); + + if ((*ppath)->pins->size > 0) { + + ret = __ses_dfs_add_path(__paths, *ppath); + if (ret < 0) + return ret; + } else + ses_path_free(*ppath); + + *ppath = NULL; + } + continue; + } + + if (p->vflag) + continue; + + 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; + + ret = __layout_dfs_path(f, c, p, __paths, ppath); + if (ret < 0) + return ret; + + if (SCF_EDA_Path_OFF == ret) + p->vflag = 0; + } + + if (*ppath) { + scf_vector_del((*ppath)->pins, np); + + if (SCF_EDA_Status_OFF != ret) + ret = SCF_EDA_Path_OFF; + } + + if (SCF_EDA_Path_OFF == ret) + np->vflag = 0; + } + + if (SCF_EDA_Status_OFF == ret || SCF_EDA_Path_OFF == ret) { + if (*ppath) + scf_vector_del((*ppath)->pins, rp); + + if (SCF_EDA_Path_OFF == ret) { + rp->vflag = 0; + + 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\n", rp->cid, rp->id, rp->lid); + } + + return ret; +} + +static int __layout_add_path(ses_path_t* parent, ses_path_t* child) +{ + ses_path_t* path; + ScfEpin* cp0 = child->pins->data[0]; + ScfEpin* cp1 = child->pins->data[child->pins->size - 1]; + ScfEpin* p0; + ScfEpin* p1; + + int i; + int j; + + if (!parent->childs) { + parent->childs = scf_vector_alloc(); + if (!parent->childs) + return -ENOMEM; + } + + for (i = 0; i < parent->childs->size; i++) { + path = parent->childs->data[i]; + + p0 = path->pins->data[0]; + p1 = path->pins->data[path->pins->size - 1]; + + if (p0->lid == cp0->lid && p1->lid == cp1->lid) + return __layout_add_path(path, child); + } + + child->parent_p0 = -1; + child->parent_p1 = -1; + + for (j = 0; j < parent->pins->size; j++) { + p0 = parent->pins->data[j]; + + if (p0->lid == cp0->lid) + child->parent_p0 = (j + 1) & ~0x1; + + else if (p0->lid == cp1->lid) + child->parent_p1 = j; + + if (child->parent_p0 >= 0 && child->parent_p1 >= 0) + break; + } + + child->parent = parent; + return scf_vector_add(parent->childs, child); +} + +static int _layout_layers(ScfEfunction* f, scf_vector_t* paths) +{ + ScfEcomponent* B; + ses_path_t* child; + ses_path_t* parent; + ScfEpin* Bp; + ScfEpin* Bn; + ScfEpin* p0; + ScfEpin* p1; + ScfEpin* p2; + ScfEpin* p3; + ScfEpin* p; + + int i; + int j; + int k; + + B = f->components[0]; + Bp = B->pins[SCF_EDA_Battery_POS]; + Bn = B->pins[SCF_EDA_Battery_NEG]; + + for (i = paths->size - 1; i >= 0; i--) { + child = paths->data[i]; + + assert(child->pins->size >= 2); + + p0 = child->pins->data[0]; + p1 = child->pins->data[child->pins->size - 1]; + + if (p0->lid == Bp->lid && p1->lid == Bn->lid) + continue; + + for (j = paths->size - 1; j >= 0; j--) { + parent = paths->data[j]; + + if (parent == child) + continue; + + int n = 0; + + for (k = 0; k < parent->pins->size; k++) { + p = parent->pins->data[k]; + + if (p->lid == p0->lid) + n |= 0x1; + + if (p->lid == p1->lid) + n |= 0x2; + + if (0x3 == n) + goto branch; + } + } + + continue; + +branch: + if (scf_vector_del(paths, child) < 0) + return -1; + + if (__layout_add_path(parent, child) < 0) { + ses_path_free(child); + return -ENOMEM; + } + } + + return 0; +} + +static int ses_layout_layers(ScfEfunction* f, scf_vector_t* paths) +{ + ses_path_t* path; + + int size; + + do { + size = paths->size; + + int ret = _layout_layers(f, paths); + if (ret < 0) + return ret; + + } while (size > paths->size); + + return 0; +} + +static int _layout_paths(ScfEfunction* f, ScfEline* el, scf_vector_t* paths) +{ + if (!f || !el || !paths) + return -EINVAL; + + ses_path_t* path; + ScfEcomponent* c; + ScfEcomponent* B; + ScfEpin* p; + + size_t i; + + B = f->components[0]; + path = NULL; + + for (i = 0; i + 1 < el->n_pins; i += 2) { + + c = f->components[el->pins[i]]; + p = c->pins [el->pins[i + 1]]; + + if (c == B) + continue; + + int ret = __layout_dfs_path(f, c, p, paths, &path); + if (ret < 0) + return ret; + + if (!path) + continue; + + if (SCF_EDA_Status_OFF == ret || SCF_EDA_Path_OFF == ret) { + ses_path_free(path); + path = NULL; + continue; + } + + if (scf_vector_add(paths, path) < 0) { + ses_path_free(path); + return -ENOMEM; + } + + path = NULL; + } + + if (path) { + ses_path_free(path); + path = NULL; + } + + for (i = 0; i < paths->size; i++) { + path = paths->data[i]; + + path->index = i; + } + + return 0; +} + +int ses_layout_paths(ScfEfunction* f, scf_vector_t* paths) +{ + if (!f || !paths) + return -EINVAL; + + ses_path_t* path; + ScfEcomponent* B; + ScfEline* el; + + scf_vector_clear(paths, ( void (*)(void*) )ses_path_free); + + B = f->components[0]; + el = f->elines[B->pins[SCF_EDA_Battery_POS]->lid]; + + int ret = _layout_paths(f, el, paths); + if (ret < 0) + return ret; + + int i; + for (i = 0; i < f->n_elines; i++) { + el = f->elines[i]; + + if (el->flags & SCF_EDA_PIN_IN) { + + ret = _layout_paths(f, el, paths); + if (ret < 0) + return ret; + } + } + + return ses_layout_layers(f, paths); +} diff --git a/ses_node_analysis.c b/ses_node_analysis.c index 0da595c..4167499 100644 --- a/ses_node_analysis.c +++ b/ses_node_analysis.c @@ -1,83 +1,43 @@ #include"ses_core.h" #include -int ses_node_ref_edge(ses_node_t* node, ses_edge_t* edge) +ses_edge_t* ses_edges_find_edge(scf_vector_t* edges, ses_path_t* path, int vip_i) { - int ret = scf_vector_add(node->edges, edge); - if (ret < 0) - return ret; - - edge->refs++; - return 0; -} - -int ses_node_add_edge(ses_node_t* node, ses_path_t* path, int m, int n, ses_edge_t** pp) -{ - ses_edge_t* edge = ses_edge_alloc(path, m, n); - if (!edge) - return -ENOMEM; - - int ret = scf_vector_add(node->edges, edge); - if (ret < 0) { - ses_edge_free(edge); - return ret; - } - - if (pp) - *pp = edge; - return 0; -} - -ses_edge_t* ses_nodes_find_edge(scf_vector_t* nodes, ses_path_t* path, int vip_i) -{ - ses_node_t* node; ses_edge_t* edge; - int i; int j; + for (j = 0; j < edges->size; j++) { + edge = edges->data[j]; - for (i = 0; i < nodes->size; i++) { - node = nodes->data[i]; - - for (j = 0; j < node->edges->size; j++) { - edge = node->edges->data[j]; - - if (edge->path == path - && (edge->vip_m == vip_i || edge->vip_n == vip_i)) - return edge; - } + if (edge->path == path + && (edge->vip_m == vip_i || edge->vip_n == vip_i)) + return edge; } return NULL; } -ses_edge_t* ses_nodes_find_edge_by_pin(scf_vector_t* nodes, ScfEpin* vip) +ses_edge_t* ses_edges_find_edge_by_pin(scf_vector_t* edges, ScfEpin* vip) { - ses_node_t* node; ses_edge_t* edge; - int i; int j; int k; - for (i = 0; i < nodes->size; i++) { - node = nodes->data[i]; + for (j = 0; j < edges->size; j++) { + edge = edges->data[j]; - for (j = 0; j < node->edges->size; j++) { - edge = node->edges->data[j]; + for (k = edge->vip_n; k >= edge->vip_m; k--) { - for (k = edge->vip_n; k >= edge->vip_m; k--) { - - if (vip == edge->path->pins->data[k]) - return edge; - } + if (vip == edge->path->pins->data[k]) + return edge; } } 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 __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* nodes, scf_vector_t* edges) { ses_path_t* child; ses_path_t* bridge; @@ -107,7 +67,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s if (conn->vflag) continue; - ret = __ses_nodes_path2(f, conn, 0, conn->pins->size - 1, nodes, n_edges); + ret = __ses_nodes_path2(f, conn, 0, conn->pins->size - 1, nodes, edges); if (ret < 0) return ret; } @@ -120,7 +80,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s if (child->vflag) continue; - ret = __ses_nodes_path2(f, child, 0, child->pins->size - 1, nodes, n_edges); + ret = __ses_nodes_path2(f, child, 0, child->pins->size - 1, nodes, edges); if (ret < 0) return ret; } @@ -133,7 +93,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s if (bridge->vflag) continue; - ret = __ses_nodes_path2(f, bridge, 0, bridge->pins->size - 1, nodes, n_edges); + ret = __ses_nodes_path2(f, bridge, 0, bridge->pins->size - 1, nodes, edges); if (ret < 0) return ret; } @@ -142,7 +102,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s scf_logd("path: %d, vflag: %d, vip_m: %d, vip_n: %d\n", path->index, path->vflag, vip_m, vip_n); int bflag = 0; - for (i = vip_n - 1; i > vip_m; i -= 2) { + for (i = vip_n - 1; i >= vip_m; i -= 2) { p = path->pins->data[i]; c = f->components[p->cid]; @@ -154,7 +114,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s case SCF_EDA_NPN: if (SCF_EDA_NPN_B == p->id) { - edge_c = ses_nodes_find_edge_by_pin(nodes, c->pins[SCF_EDA_NPN_C]); + edge_c = ses_edges_find_edge_by_pin(edges, c->pins[SCF_EDA_NPN_C]); if (!edge_c) { scf_loge("\n"); return -EINVAL; @@ -164,6 +124,7 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s edge_c->hfe = c->pins[SCF_EDA_NPN_C]->hfe; } + case SCF_EDA_Inductor: if (!node) { node = ses_node_alloc(); if (!node) @@ -185,9 +146,9 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s if (!node) \ return -ENOMEM; \ } \ - edge = ses_nodes_find_edge(nodes, _path, _m); \ + edge = ses_edges_find_edge(edges, _path, _m); \ if (edge) { \ - ret = ses_node_ref_edge(node, edge); \ + ret = scf_vector_add(node->edges, edge); \ if (ret < 0) { \ ses_node_free(node); \ return ret; \ @@ -245,25 +206,50 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s } } - if (!node) - continue; + if (!node) { + if (i > vip_m) + continue; - ret = ses_node_add_edge(node, path, i, j, &edge); + node = ses_node_alloc(); + if (!node) + return -ENOMEM; + } + + ret = scf_vector_add(nodes, node); if (ret < 0) { ses_node_free(node); return ret; } - edge->index = (*n_edges)++; + + p = path->pins->data[i]; + + node->vip_i = i; + node->path = path; + node->lid = p->lid; + + edge = ses_edge_alloc(path, i, j); + if (!edge) + return -ENOMEM; + + ret = scf_vector_add(edges, edge); + if (ret < 0) { + ses_edge_free(edge); + return ret; + } + + edge->index = edges->size - 1; edge->node1 = node; edge->bflag = bflag; bflag = 0; + ret = scf_vector_add(node->edges, edge); + if (ret < 0) + return ret; + if (prev) { - ret = ses_node_ref_edge(prev, edge); - if (ret < 0) { - ses_node_free(node); + ret = scf_vector_add(prev->edges, edge); + if (ret < 0) return ret; - } edge->node0 = prev; } @@ -272,77 +258,50 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s edge_c = NULL; } - ret = scf_vector_add(nodes, node); - if (ret < 0) { - ses_node_free(node); - return ret; - } - node->vip_i = i; - node->path = path; - prev = node; node = NULL; j = i - 1; } - if (j > vip_m) { - if (!prev) { - prev = ses_node_alloc(); - if (!prev) - return -ENOMEM; - - ret = scf_vector_add(nodes, prev); - if (ret < 0) { - ses_node_free(prev); - return ret; - } - prev->vip_i = j; - prev->path = path; - } - - ret = ses_node_add_edge(prev, path, vip_m, j, &edge); - if (ret < 0) - return ret; - edge->index = (*n_edges)++; - edge->node0 = prev; - edge->bflag = bflag; - bflag = 0; - - if (edge_c) { - edge_c->edge_b = edge; - edge_c = NULL; - } - } - return 0; } -int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t** nodes) +int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t** pnodes, scf_vector_t** pedges) { - scf_vector_t* vec = scf_vector_alloc(); - if (!vec) - return -ENOMEM; - - ses_node_t* node; - ses_edge_t* edge; + scf_vector_t* nodes; + scf_vector_t* edges; + ses_node_t* node; + ses_edge_t* edge; - int n_edges = 0; int i; int j; - int ret = __ses_nodes_path2(f, path, vip_m, vip_n, vec, &n_edges); + nodes = scf_vector_alloc(); + if (!nodes) + return -ENOMEM; + + edges = scf_vector_alloc(); + if (!edges) { + scf_vector_free(nodes); + return -ENOMEM; + } + + int ret = __ses_nodes_path2(f, path, vip_m, vip_n, nodes, edges); if (ret < 0) { - scf_vector_clear(vec, (void (*)(void*) )ses_node_free); - scf_vector_free(vec); + scf_vector_clear(nodes, (void (*)(void*) )ses_node_free); + scf_vector_clear(edges, (void (*)(void*) )ses_edge_free); + scf_vector_free(nodes); + scf_vector_free(edges); return ret; } - for (i = 0; i < vec->size; ) { - node = vec->data[i]; + for (i = 0; i < nodes->size; ) { + node = nodes->data[i]; + + if (nodes->size > 1 && node->edges->size <= 1) { - if (node->edges->size <= 1) { - assert(0 == scf_vector_del(vec, node)); + assert(0 == scf_vector_del(nodes, node)); for (j = 0; j < node->edges->size; j++) { edge = node->edges->data[j]; @@ -361,7 +320,8 @@ int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, sc } } - *nodes = vec; + *pnodes = nodes; + *pedges = edges; return 0; } @@ -384,45 +344,38 @@ int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, sc ... v[m - 1][0] - v[m - 1][1] - a[m - 1] * R[m - 1] = C[m - 1] */ -static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* nodes, int* changed, int64_t ns, int64_t count) +static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* nodes, scf_vector_t* edges, int* changed, int64_t ns, int64_t count) { ses_node_t* node; ses_edge_t* edge; ScfEcomponent* c; - ScfEline* el; + ScfEcomponent* B = f->components[0]; + ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; + ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; + ScfEpin* pm = path->pins->data[vip_m]; ScfEpin* pn = path->pins->data[vip_n]; ScfEpin* p0; ScfEpin* p1; + ScfEline* el; int ret = 0; int i; int j; - int t = 0; - int m = 0; + int m = edges->size; int n = nodes->size; - for (i = 0; i < nodes->size; i++) { - node = nodes->data[i]; - - for (j = 0; j < node->edges->size; j++) { - edge = node->edges->data[j]; - - if (!edge->vflag) { - m++; - edge->vflag = 1; - - if (edge->edge_b) - t++; - } - } - } + if (pm->lid == Bp->lid) + n = nodes->size - 1; int N = n + m; - scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, n_nodes: %d, n_edges: %d, t: %d, N: %d\n", pm->cid, pm->id, pm->v, pn->cid, pn->id, pn->v, n, m, t, N); + pm->v = f->elines[pm->lid]->v; + pn->v = f->elines[pn->lid]->v; + + scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, n: %d, m: %d, N: %d\n", pm->cid, pm->id, pm->v, pn->cid, pn->id, pn->v, n, m, N); double* A = calloc(N * N + N + N + (N + N + N * N + N * N), sizeof(double)); if (!A) @@ -435,12 +388,16 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, double* V = S + N; double* U = V + N * N; double cv; + double lv; + double uf; + double uh; + double la; double r; __ses_path_jr(f, path); - for (i = 0; i < nodes->size; i++) { - node = nodes->data[i]; + for (i = 0; i < n; i++) { + node = nodes->data[i]; b[i] = 0; @@ -455,92 +412,71 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, } } - for (i = 0; i < nodes->size; i++) { - node = nodes->data[i]; - - scf_logd("node->index: %d\n", node->index); - - for (j = 0; j < node->edges->size; j++) { - edge = node->edges->data[j]; - - if (!edge->vflag) - continue; - edge->vflag = 0; + for (j = 0; j < edges->size; j++) { + edge = edges->data[j]; - __ses_path_capacitors(f, edge->path, edge->vip_m, edge->vip_n, &cv); + __ses_path_lc(f, edge->path, edge->vip_m, edge->vip_n, &cv, &lv, &uf, &uh, &la); - p0 = edge->path->pins->data[edge->vip_m]; - p1 = edge->path->pins->data[edge->vip_n]; + p0 = edge->path->pins->data[edge->vip_m]; + p1 = edge->path->pins->data[edge->vip_n]; - double _pr0 = p0->pr; - double _sr0 = p0->sr; - double _pr1 = p1->pr; - double _sr1 = p1->sr; + double _pr0 = p0->pr; + double _sr0 = p0->sr; + double _pr1 = p1->pr; + double _sr1 = p1->sr; - if (0 == edge->vip_m) { - p0->pr = 0; - p0->sr = 0; - } + if (0 == edge->vip_m) { + p0->pr = 0; + p0->sr = 0; + } - if (edge->vip_n == edge->path->pins->size - 1) { - p1->pr = edge->path->pr; - p1->sr = edge->path->sr; - } + if (edge->vip_n == edge->path->pins->size - 1) { + p1->pr = edge->path->pr; + p1->sr = edge->path->sr; + } - if (0 == edge->vip_m && edge->vip_n == edge->path->pins->size - 1) - r = edge->path->pr; + if (0 == edge->vip_m && edge->vip_n == edge->path->pins->size - 1) + r = edge->path->sr; + else + __ses_path_sr(f, edge->path, edge->vip_m, edge->vip_n, &r); + + p0->pr = _pr0; + p0->sr = _sr0; + p1->pr = _pr1; + p1->sr = _sr1; + + edge->r = r; + + scf_logd("c%ldp%ld-c%ldp%ld, r: %lg, cv: %lg, uh: %lg, la: %lg, edge->index: %d\n", p0->cid, p0->id, p1->cid, p1->id, r, cv, uh, la, edge->index); +/* dv = idt / C + v = Ldi/dt + v0 - v1 - ir = cv + idt/C + Ldi/dt + v0 - v1 - ir = cv + idt/C + Li/dt - Li0/dt + + v0 - v1 - i * (r + dt/C + L/dt) = cv - Li0/dt +*/ + if (edge->bflag) + b[n + edge->index] = cv + SCF_EDA_V_NPN_ON; + else { + b[n + edge->index] = cv - uh * 1000.0 * la / ns; + + if (uf > 0.0) + A[(n + edge->index) * N + n + edge->index] = -r - uh * 1000.0 / ns - ns / 1000.0 / uf; else - __ses_path_sr(f, edge->path, edge->vip_m, edge->vip_n, &r); - - p0->pr = _pr0; - p0->sr = _sr0; - p1->pr = _pr1; - p1->sr = _sr1; - - edge->r = r; - - 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->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; - } - - if (edge->path == path) { - - if (edge->node0) - A[(n + edge->index) * N + edge->node0->index] = -1; - - else if (edge->vip_n == vip_n) - b[n + edge->index] += pn->v; - - - if (edge->node1) - A[(n + edge->index) * N + edge->node1->index] = 1; - - else if (edge->vip_m == vip_m) - b[n + edge->index] -= pm->v; - - } else { - if (edge->node0) - A[(n + edge->index) * N + edge->node0->index] = -1; - - else if (edge->path->parent_p1 == vip_n) - b[n + edge->index] -= pn->v; - + A[(n + edge->index) * N + n + edge->index] = -r - uh * 1000.0 / ns; + } - if (edge->node1) - A[(n + edge->index) * N + edge->node1->index] = 1; + if (edge->node0 && edge->node0->lid != Bn->lid) + A[(n + edge->index) * N + edge->node0->index] = -1; + else + b[n + edge->index] += Bn->v; - else if (edge->path->parent_p0 == vip_m) - b[n + edge->index] -= pm->v; - } - } + if (edge->node1 && edge->node1->lid != Bp->lid) + A[(n + edge->index) * N + edge->node1->index] = 1; + else + b[n + edge->index] -= Bp->v; } - int n_amplifiers; do { @@ -572,31 +508,27 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, // scf_logi("X:\n"); // gsl_vector_fprintf(stdout, &_X.vector, "%lg"); - for (i = 0; i < nodes->size; i++) { - node = nodes->data[i]; - - for (j = 0; j < node->edges->size; j++) { - edge = node->edges->data[j]; + for (j = 0; j < edges->size; j++) { + edge = edges->data[j]; - if (edge->edge_b) { - double Ic = X[n + edge->index]; - double Ib = X[n + edge->edge_b->index]; + if (edge->edge_b) { + double Ic = X[n + edge->index]; + double Ib = X[n + edge->edge_b->index]; - double dI = Ib * edge->hfe - Ic; + double dI = Ib * edge->hfe - Ic; - if (dI < -1e-10) { - scf_logi("Ic: %lg, Ib: %lg, dI: %lg\n", Ic, Ib, dI); + if (dI < -1e-10) { + scf_logi("Ic: %lg, Ib: %lg, dI: %lg\n", Ic, Ib, dI); - int k; - for (k = 0; k < N; k++) - A[(n + edge->index) * N + k] = 0; + int k; + 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->edge_b->index] = edge->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++; - } + n_amplifiers++; } } } @@ -605,63 +537,115 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, for (i = 0; i < N; i++) scf_logi("%lg\n", X[i]); - for (i = 0; i < nodes->size; i++) { - node = nodes->data[i]; + for (i = 0; i < n; i++) { + node = nodes->data[i]; - p0 = node->path->pins->data[node->vip_i]; - - el = f->elines[p0->lid]; + el = f->elines[node->lid]; el->v = X[i]; + } + + int __changed = 0; + + for (j = 0; j < edges->size; j++) { + edge = edges->data[j]; + + p0 = edge->path->pins->data[edge->vip_m]; + p1 = edge->path->pins->data[edge->vip_n]; + + c = f->components[p0->cid]; + + edge->a = X[n + edge->index]; + + scf_logd("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, a: %lg, edge->index: %d\n", p0->cid, p0->id, p0->v, p1->cid, p1->id, p1->v, edge->a, edge->index); + + if (SCF_EDA_NPN == c->type) { + p0->a = edge->a; + p1->a = c->pins[SCF_EDA_NPN_B]->a + c->pins[SCF_EDA_NPN_C]->a; + + if (SCF_EDA_NPN_B == p0->id && edge->a < 0) { + c->status = SCF_EDA_Status_OFF; + c->lock = 1; + __changed++; + + scf_loge("\033[34mc%ld, status: %d, a: %lg, edge->index: %d\033[0m\n", c->id, c->status, edge->a, edge->index); + } + + } else if (SCF_EDA_PNP == c->type) { + p1->a = edge->a; + p0->a = c->pins[SCF_EDA_PNP_B]->a + c->pins[SCF_EDA_PNP_C]->a; + + if (SCF_EDA_PNP_B == p1->id && edge->a < 0) { + c->status = SCF_EDA_Status_OFF; + c->lock = 1; + __changed++; + + scf_loge("\033[34mc%ld, status: %d, a: %lg, edge->index: %d\033[0m\n", c->id, c->status, edge->a, edge->index); + } + } + } - scf_logi("c%ldp%ld, e%ld->v: %lg, node->index: %d\n", p0->cid, p0->id, el->id, el->v, node->index); + if (__changed > 0) { + *changed += __changed; + return 0; } -#if 1 - for (i = 0; i < nodes->size; i++) { - node = nodes->data[i]; + for (j = 0; j < edges->size; j++) { + edge = edges->data[j]; - for (j = 0; j < node->edges->size; j++) { - edge = node->edges->data[j]; + p0 = edge->path->pins->data[edge->vip_m]; + p1 = edge->path->pins->data[edge->vip_n]; - if (edge->vflag) - continue; - edge->vflag = 1; + c = f->components[p0->cid]; - p0 = edge->path->pins->data[edge->vip_m]; - p1 = edge->path->pins->data[edge->vip_n]; + p0->v = f->elines[p0->lid]->v; + p1->v = f->elines[p1->lid]->v; - c = f->components[p0->cid]; + scf_logd("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, a: %lg, edge->index: %d\n", p0->cid, p0->id, p0->v, p1->cid, p1->id, p1->v, edge->a, edge->index); - p0->v = f->elines[p0->lid]->v; - p1->v = f->elines[p1->lid]->v; + if (SCF_EDA_NPN == c->type) { + ses_ui_r(&edge->r, 0, p0->v - p1->v, 0, edge->a, 0); - edge->a = X[n + edge->index]; + p0->dr = edge->r - p0->r; + p0->a = edge->a; + p1->a = c->pins[SCF_EDA_NPN_B]->a + c->pins[SCF_EDA_NPN_C]->a; - scf_logd("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, a: %lg, edge->index: %d\n", p0->cid, p0->id, p0->v, p1->cid, p1->id, p1->v, edge->a, edge->index); + if (SCF_EDA_NPN_B == p0->id && p0->a < 0) { + c->status = SCF_EDA_Status_OFF; - if (SCF_EDA_NPN == c->type) { - ses_ui_r(&edge->r, 0, p0->v - p1->v, 0, edge->a, 0); + scf_loge("\033[34mc%ld, status: %d, a: %lg, edge->index: %d\033[0m\n", c->id, c->status, edge->a, edge->index); + } + continue; - p0->dr = edge->r - p0->r; - 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); - } 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; - 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; + if (SCF_EDA_PNP_B == p1->id && p1->a < 0) { + c->status = SCF_EDA_Status_OFF; + + scf_loge("\033[34mc%ld, status: %d, a: %lg, edge->index: %d\033[0m\n", c->id, c->status, edge->a, edge->index); } + continue; - ret = __ses_path_va_branch(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ns, count); - if (ret < 0) - goto error; + } else if (SCF_EDA_Inductor == c->type) { + int sign = p0->id - !p0->id; + + c->v = (edge->a * sign - c->a) * c->uh * 1000.0 / ns; + + } else if (SCF_EDA_Capacitor == c->type) { + int sign = p0->id - !p0->id; + + c->v += edge->a * sign * ns / 1000.0 / c->uf; } + + ret = __ses_path_va_branch(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ns, count); + if (ret < 0) + goto error; } -#endif + error: free(A); return ret; @@ -670,8 +654,7 @@ error: int __ses_nodes_path_solve(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int* changed, int64_t ns, int64_t count) { scf_vector_t* nodes = NULL; - ses_node_t* node; - ses_edge_t* edge; + scf_vector_t* edges = NULL; ScfEline* el; ScfEpin* pm = path->pins->data[vip_m]; @@ -679,16 +662,18 @@ int __ses_nodes_path_solve(ScfEfunction* f, ses_path_t* path, int vip_m, int vip ScfEpin* p0; ScfEpin* p1; - int ret = __ses_nodes_path(f, path, vip_m, vip_n, &nodes); + int ret = __ses_nodes_path(f, path, vip_m, vip_n, &nodes, &edges); if (ret < 0) return ret; ses_nodes_print(nodes); - ret = __ses_nodes_path_solve2(f, path, vip_m, vip_n, nodes, changed, ns, count); + ret = __ses_nodes_path_solve2(f, path, vip_m, vip_n, nodes, edges, changed, ns, count); scf_vector_clear(nodes, (void (*)(void*) )ses_node_free); + scf_vector_clear(edges, (void (*)(void*) )ses_edge_free); scf_vector_free(nodes); + scf_vector_free(edges); return ret; } diff --git a/ses_path.c b/ses_path.c index b52dbf3..d17ce5d 100644 --- a/ses_path.c +++ b/ses_path.c @@ -375,29 +375,6 @@ int ses_path_add(ses_path_t* parent, ses_path_t* child, ScfEfunction* f) int j; - for (j = 0; j < parent->childs->size; j++) { - path = parent->childs->data[j]; - - p0 = path->pins->data[0]; - p1 = path->pins->data[path->pins->size - 1]; - - if (p0->lid == cp0->lid && p1->lid == cp1->lid) { - - if (child->pins->size == (child->n_diodes + child->n_NPNs) * 2 - && path->pins->size > (path->n_diodes + path->n_NPNs) * 2) { - - parent->childs->data[j] = child; - child->parent = parent; - child->parent_p0 = path->parent_p0; - child->parent_p1 = path->parent_p1; - child->type = SES_PATH_BRANCH; - - return ses_path_add(child, path, f); - } else - return ses_path_add(path, child, f); - } - } - if (scf_vector_add(parent->childs, child) < 0) return -ENOMEM; diff --git a/ses_step_dc_npn.c b/ses_step_dc_npn.c index 147bf2e..1dcf564 100644 --- a/ses_step_dc_npn.c +++ b/ses_step_dc_npn.c @@ -45,11 +45,13 @@ static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t 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_NPN_OFF); + if (c->lock) { + scf_loge("\033[34mc%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", + c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF); + continue; + } if (lb->v < SCF_EDA_V_MIN) { - if (le->v < SCF_EDA_V_MIN) continue; @@ -60,10 +62,9 @@ static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t if (le->v == Bn->v) lb->vconst = 1; - if (pb->v > Bp->v) { - if (!c->lock) - c->status = SCF_EDA_Status_OFF; - } else + if (pb->v > Bp->v) + c->status = SCF_EDA_Status_OFF; + else c->status = SCF_EDA_Status_ON; } else if (le->v < SCF_EDA_V_MIN) { @@ -75,10 +76,9 @@ static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t if (lb->v == Bp->v) le->vconst = 1; - if (pe->v < Bn->v) { - if (!c->lock) - c->status = SCF_EDA_Status_OFF; - } else + if (pe->v < Bn->v) + c->status = SCF_EDA_Status_OFF; + else c->status = SCF_EDA_Status_ON; } else if (lb->v >= le->v + SCF_EDA_V_NPN_OFF) { @@ -92,16 +92,15 @@ static int _dc_npn_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t pb->v = lb->v; pe->v = le->v; - if (pb->v > Bp->v) { - if (!c->lock) - c->status = SCF_EDA_Status_OFF; - } else + if (pb->v > Bp->v) + 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; + + 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", diff --git a/ses_step_dc_pnp.c b/ses_step_dc_pnp.c index bbc7ef8..5c1a75d 100644 --- a/ses_step_dc_pnp.c +++ b/ses_step_dc_pnp.c @@ -105,7 +105,7 @@ static int _dc_pnp_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t } 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); + c->id, c->status, c->lock, pb->v, pe->v, pe->v - pb->v, SCF_EDA_V_PNP_OFF); } return 0; diff --git a/ses_step_simplify.c b/ses_step_simplify.c index 471ed97..848de5e 100644 --- a/ses_step_simplify.c +++ b/ses_step_simplify.c @@ -151,8 +151,8 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) break; case SCF_EDA_Capacitor: - cairo_set_source_rgb(cr, 0.8, 0.0, 0.0); + p = c->pins[SCF_EDA_Battery_POS]; if (p->y < c->y) { cairo_move_to(cr, c->x - 8, c->y - 5); @@ -199,7 +199,64 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); - snprintf(text, sizeof(text) - 1, "%lguf", c->uf); + if (c->uf < 1e-6) + snprintf(text, sizeof(text) - 1, "%lgpF", c->uf * 1e6); + else if (c->uf < 1e-3) + snprintf(text, sizeof(text) - 1, "%lgnF", c->uf * 1000.0); + else + snprintf(text, sizeof(text) - 1, "%lguF", c->uf); + + cairo_move_to (cr, c->x + 4, c->y - 5); + cairo_show_text(cr, text); + cairo_stroke(cr); + break; + + case SCF_EDA_Inductor: + cairo_set_source_rgb(cr, 0.8, 0.0, 0.0); + p = c->pins[SCF_EDA_Battery_POS]; +#define DRAW_Inductor() \ + do { \ + if (p->y < c->y) { \ + cairo_arc(cr, c->x + 1, c->y - 15, 5, M_PI * 0.45, M_PI * 1.55); \ + cairo_stroke(cr); \ + cairo_arc(cr, c->x + 1, c->y - 5, 5, M_PI * 0.45, M_PI * 1.55); \ + cairo_stroke(cr); \ + cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); \ + cairo_move_to(cr, c->x, c->y - 19); \ + } else { \ + cairo_arc(cr, c->x + 1, c->y + 15, 5, M_PI * 0.45, M_PI * 1.55); \ + cairo_stroke(cr); \ + cairo_arc(cr, c->x + 1, c->y + 5, 5, M_PI * 0.45, M_PI * 1.55); \ + cairo_stroke(cr); \ + cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); \ + cairo_move_to(cr, c->x, c->y + 19); \ + } \ + cairo_line_to(cr, p->x, p->y); \ + } while (0) + + DRAW_Inductor(); + cairo_stroke(cr); + + cairo_set_source_rgb(cr, 0.0, 0.0, 0.8); + p = c->pins[SCF_EDA_Battery_NEG]; + DRAW_Inductor(); + cairo_stroke(cr); + + cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + + ses_text_v(cr, c->x + 10, c->y + 10, c->v); + ses_text_a(cr, c->x + 10, c->y + 25, c->a); + + cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); + + if (c->uh > 100000.0) + snprintf(text, sizeof(text) - 1, "%lgH", c->uh / 1000000.0); + else if (c->uh > 100.0) + snprintf(text, sizeof(text) - 1, "%lgmH", c->uh / 1000.0); + else if (c->uh < 1e-3) + snprintf(text, sizeof(text) - 1, "%lgnH", c->uh * 1000.0); + else + snprintf(text, sizeof(text) - 1, "%lguH", c->uh); cairo_move_to (cr, c->x + 4, c->y - 5); cairo_show_text(cr, text); @@ -435,7 +492,7 @@ int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t b t %= 1000; uint8_t time[512]; - snprintf(time, sizeof(time) - 1, "%ld,%ld,%ld,%ldns", s, ms, us, t); + snprintf(time, sizeof(time) - 1, "%03ld,%03ld,%03ld,%03ldns", s, ms, us, t); cairo_move_to (cr, 10, 20); cairo_show_text(cr, time); cairo_stroke(cr); @@ -589,13 +646,13 @@ static int _simplify_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx char file[128]; snprintf(file, sizeof(file) - 1, "./simplify_%ld.png", i); -#if 0 - if (count < 60 * 1000) +#if 1 + if (count < 70000) return 0; #endif if (count % 10 == 0) { -#if 0 +#if 1 static FILE* fp = NULL; if (!fp) fp = fopen("v.txt", "w"); diff --git a/ses_step_topo.c b/ses_step_topo.c index 44da2bf..ffffc88 100644 --- a/ses_step_topo.c +++ b/ses_step_topo.c @@ -1,17 +1,24 @@ #include"ses_core.h" -static int __ses_dfs_add_path(scf_vector_t* paths, ses_path_t* path) +static int __ses_dfs_add_ppath(scf_vector_t* paths, ses_path_t** ppath) { ScfEpin* p; int j; - if (scf_vector_add(paths, path) < 0) - return -ENOMEM; + if (*ppath) { + if ((*ppath)->pins->size > 0) { + + if (scf_vector_add(paths, *ppath) < 0) + return -ENOMEM; - for (j = 0; j < path->pins->size; j++) { - p = path->pins->data[j]; - p->pflag = 1; - p->path = (uintptr_t)path; + for (j = 0; j < (*ppath)->pins->size; j++) { + p = (*ppath)->pins->data[j]; + p->pflag = 1; + p->path = (uintptr_t)*ppath; + } + } else + ses_path_free(*ppath); + *ppath = NULL; } return 0; @@ -24,11 +31,8 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v ScfEpin* np; ScfEpin* p; - size_t i; - size_t j; - - if (SCF_EDA_Status_OFF == rc->status) - return SCF_EDA_Status_OFF; + int64_t i; + int64_t j; if (SCF_EDA_Diode == rc->type && SCF_EDA_Diode_NEG == rp->id) return SCF_EDA_Path_OFF; @@ -39,20 +43,22 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v 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_EDA_Status_OFF != rc->status) { + if (!*ppath) { + *ppath = ses_path_alloc(); + if (!*ppath) + return -ENOMEM; + } + + if (scf_vector_add((*ppath)->pins, rp) < 0) return -ENOMEM; } - if (scf_vector_add((*ppath)->pins, rp) < 0) - return -ENOMEM; - 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); + scf_logd("c%ldp%ld, l%ld, vflag: %d, pflag: %d\n", rp->cid, rp->id, rp->lid, rp->vflag, rp->pflag); int ret = 0; @@ -67,7 +73,7 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v 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); + scf_logd("c%ldp%ld, l%ld, vflag: %d, pflag: %d\n", np->cid, np->id, np->lid, np->vflag, np->pflag); el = f->elines[np->lid]; @@ -78,33 +84,37 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v continue; } - if (!*ppath) { - *ppath = ses_path_alloc(); - if (!*ppath) - return -ENOMEM; - } + if (SCF_EDA_Status_OFF != rc->status) { + if (!*ppath) { + *ppath = ses_path_alloc(); + if (!*ppath) + return -ENOMEM; + } - if (SCF_EDA_PNP == rc->type && 0 == (*ppath)->pins->size) { + if (SCF_EDA_PNP == rc->type && 0 == (*ppath)->pins->size) { - if (scf_vector_add((*ppath)->pins, rp) < 0) + if (scf_vector_add((*ppath)->pins, rp) < 0) + return -ENOMEM; + } + + if (scf_vector_add((*ppath)->pins, np) < 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) || (SCF_EDA_PNP == rc->type && SCF_EDA_PNP_E == np->id))) np->vflag = 1; if (SCF_EDA_PIN_NEG & el->flags) { + scf_logd("neg l%ld\n\n", el->id); - ret = __ses_dfs_add_path(__paths, *ppath); - if (ret < 0) - return ret; + return __ses_dfs_add_ppath(__paths, ppath); + } + + if (SCF_EDA_NPN == rc->type && SCF_EDA_NPN_C == rp->id) { + scf_logd("NPN C, c%ldp%ld\n\n", rp->cid, rp->id); - *ppath = NULL; - return 0; + return __ses_dfs_add_ppath(__paths, ppath); } ret = 0; @@ -115,16 +125,12 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v p = c->pins [el->pins[j + 1]]; if (p->pflag) { - if (p != np && *ppath) { + if (p != np) { scf_logd("branch: c%ld_p%ld, l%ld\n\n", c->id, p->id, el->id); - if ((*ppath)->pins->size > 0) { - - ret = __ses_dfs_add_path(__paths, *ppath); - if (ret < 0) - return ret; - } else - ses_path_free(*ppath); + ret = __ses_dfs_add_ppath(__paths, ppath); + if (ret < 0) + return ret; *ppath = NULL; } @@ -134,18 +140,14 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v if (p->vflag) continue; - if (SCF_EDA_Capacitor == rc->type && SCF_EDA_Capacitor != c->type) { - if (*ppath) { - if ((*ppath)->pins->size > 0) { + if ((SCF_EDA_Capacitor == rc->type || SCF_EDA_Inductor == rc->type) + && SCF_EDA_Capacitor != c->type && SCF_EDA_Inductor != c->type) { - ret = __ses_dfs_add_path(__paths, *ppath); - if (ret < 0) - return ret; - } else - ses_path_free(*ppath); + ret = __ses_dfs_add_ppath(__paths, ppath); + if (ret < 0) + return ret; - *ppath = NULL; - } + *ppath = NULL; } if (!((SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id) @@ -154,7 +156,8 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v ses_path_t* tmp = NULL; - if (SCF_EDA_Capacitor != rc->type && SCF_EDA_Capacitor == c->type) { + if ((SCF_EDA_Capacitor == c->type || SCF_EDA_Inductor == c->type) + && SCF_EDA_Capacitor != rc->type && SCF_EDA_Inductor != rc->type) { tmp = *ppath; *ppath = NULL; } @@ -166,8 +169,17 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v if (SCF_EDA_Path_OFF == ret) p->vflag = 0; - if (tmp) + if (tmp) { *ppath = tmp; + + if (j + 2 >= el->n_pins) { + + ret = __ses_dfs_add_ppath(__paths, ppath); + if (ret < 0) + return ret; + *ppath = NULL; + } + } } if (*ppath) { @@ -243,6 +255,14 @@ static int ses_path_to_npn(const ScfEfunction* f, const ses_path_t* path, int pi return ses_pin_to_npn(f, p0, pid) || ses_pin_to_npn(f, p1, pid); } +static int ses_path_to_pnp(const ScfEfunction* f, const ses_path_t* path, int pid) +{ + const ScfEpin* p0 = path->pins->data[0]; + const ScfEpin* p1 = path->pins->data[path->pins->size - 1]; + + return ses_pin_to_pnp(f, p0, pid) || ses_pin_to_pnp(f, p1, pid); +} + static int _ses_child_cmp(const void* v0, const void* v1) { const ses_path_t* p0 = *(const ses_path_t**)v0; @@ -445,28 +465,28 @@ static int _ses_connect_cmp(const void* v0, const void* v1, void* arg) if (0 == p0->n_capacitors) { if (0 == p1->n_capacitors) { - if (ses_path_to_npn(f, p0, SCF_EDA_NPN_B)) + if (ses_path_to_npn(f, p0, SCF_EDA_NPN_B) || ses_path_to_pnp(f, p0, SCF_EDA_PNP_B)) return -1; - if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B)) + if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B) || ses_path_to_pnp(f, p1, SCF_EDA_PNP_B)) return 1; - if (ses_path_to_npn(f, p0, SCF_EDA_NPN_C)) + if (ses_path_to_npn(f, p0, SCF_EDA_NPN_C) || ses_path_to_pnp(f, p0, SCF_EDA_PNP_C)) return -1; - if (ses_path_to_npn(f, p1, SCF_EDA_NPN_C)) + if (ses_path_to_npn(f, p1, SCF_EDA_NPN_C) || ses_path_to_pnp(f, p1, SCF_EDA_PNP_C)) return 1; } return -1; } else if (0 == p1->n_capacitors) return 1; - if (ses_path_to_npn(f, p0, SCF_EDA_NPN_C)) + if (ses_path_to_npn(f, p0, SCF_EDA_NPN_C) || ses_path_to_pnp(f, p0, SCF_EDA_PNP_C)) return -1; - if (ses_path_to_npn(f, p1, SCF_EDA_NPN_C)) + if (ses_path_to_npn(f, p1, SCF_EDA_NPN_C) || ses_path_to_pnp(f, p1, SCF_EDA_PNP_C)) return 1; - if (ses_path_to_npn(f, p0, SCF_EDA_NPN_B)) + if (ses_path_to_npn(f, p0, SCF_EDA_NPN_B) || ses_path_to_pnp(f, p0, SCF_EDA_PNP_B)) return 1; - if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B)) + if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B) || ses_path_to_pnp(f, p1, SCF_EDA_PNP_B)) return -1; if (p0->n_capacitors > p1->n_capacitors) @@ -678,6 +698,11 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths) for (i = 0; i < paths->size; ) { path0 = paths->data[i]; + if (path0->n_transistors > 0) { + i++; + continue; + } + p0 = path0->pins->data[0]; p1 = path0->pins->data[path0->pins->size - 1]; @@ -697,6 +722,9 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths) if (path1 == path0) continue; + if (path1->n_transistors > 0) + continue; + p2 = path1->pins->data[0]; p3 = path1->pins->data[path1->pins->size - 1]; @@ -978,6 +1006,8 @@ static int _topo_layers(ScfEfunction* f, scf_vector_t* paths) ScfEpin* Bn; ScfEpin* p0; ScfEpin* p1; + ScfEpin* p2; + ScfEpin* p3; ScfEpin* p; int i; @@ -1005,6 +1035,14 @@ static int _topo_layers(ScfEfunction* f, scf_vector_t* paths) if (parent == child) continue; + p2 = parent->pins->data[0]; + p3 = parent->pins->data[parent->pins->size - 1]; + + if (p2->lid == p0->lid && p3->lid == p1->lid) + continue; + if (p3->lid == p0->lid && p2->lid == p1->lid) + continue; + int n = 0; for (k = 0; k < parent->pins->size; k++) { @@ -1160,7 +1198,7 @@ static void _topo_clear(ScfEfunction* f) c = f->components[i]; c->vflag = 0; c->lock = 0; - c->a = 0; +// c->a = 0; for (j = 0; j < c->n_pins; j++) { p = c->pins[j]; @@ -1230,6 +1268,57 @@ static int _topo_paths(ScfEfunction* f, ScfEline* el, scf_vector_t* paths) return 0; } +static int __topo_bridge_connection(scf_vector_t* paths, ses_path_t* bridge, ScfEpin* vip, ses_path_t** ppath) +{ + ses_path_t* path; + ses_path_t* conn; + ScfEpin* p0 = bridge->pins->data[0]; + ScfEpin* p1 = bridge->pins->data[bridge->pins->size - 1]; + ScfEpin* p2; + ScfEpin* p3; + + int j; + int k; + + for (j = 0; j < paths->size; j++) { + path = paths->data[j]; + + if (path == bridge) + continue; + + p2 = path->pins->data[0]; + p3 = path->pins->data[path->pins->size - 1]; + + if (p2->lid == p0->lid && p3->lid == p1->lid) + continue; + if (p3->lid == p0->lid && p2->lid == p1->lid) + continue; + + for (k = 0; k < path->pins->size; k++) { + p2 = path->pins->data[k]; + + if (p2->lid == vip->lid) { + *ppath = path; + return k; + } + } + + if (path->childs) { + k = __topo_bridge_connection(path->childs, bridge, vip, ppath); + if (k >= 0) + return k; + } + + if (path->bridges) { + k = __topo_bridge_connection(path->bridges, bridge, vip, ppath); + if (k >= 0) + return k; + } + } + + return -1; +} + static int _topo_bridge_piers(ScfEfunction* f, scf_vector_t* paths) { ses_path_t* pier; @@ -1240,8 +1329,6 @@ static int _topo_bridge_piers(ScfEfunction* f, scf_vector_t* paths) ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; ScfEpin* p0; ScfEpin* p1; - ScfEpin* p2; - ScfEpin* p3; int i; int j; @@ -1253,40 +1340,30 @@ static int _topo_bridge_piers(ScfEfunction* f, scf_vector_t* paths) p0 = pier->pins->data[0]; p1 = pier->pins->data[pier->pins->size - 1]; - if (p0->lid != Bp->lid && p1->lid != Bn->lid) - continue; - - pier->parent_p0 = -2; - pier->parent_p1 = -2; + bridge = NULL; - for (j = paths->size - 1; j >= 0; j--) { - bridge = paths->data[j]; - - if (pier == bridge) + if (p0->lid == Bp->lid) { + if (p1->lid == Bn->lid) continue; - p2 = bridge->pins->data[0]; - p3 = bridge->pins->data[bridge->pins->size - 1]; - - if (p2->lid == Bp->lid || p3->lid == Bn->lid) + k = __topo_bridge_connection(paths, pier, p1, &bridge); + if (k < 0) continue; - for (k = 0; k < bridge->pins->size; k++) { - p2 = bridge->pins->data[k]; + pier->parent_p0 = -2; + pier->parent_p1 = k; - if (p2->lid == p0->lid) { - pier->parent_p0 = (k + 1) & ~0x1; - goto found; + } else if (p1->lid == Bn->lid) { - } else if (p2->lid == p1->lid) { - pier->parent_p1 = k; - goto found; - } - } - } + k = __topo_bridge_connection(paths, pier, p0, &bridge); + if (k < 0) + continue; + + pier->parent_p0 = (k + 1) & ~0x1; + pier->parent_p1 = -2; + } else + continue; - continue; -found: if (!bridge->bridges) { bridge->bridges = scf_vector_alloc(); if (!bridge->bridges) @@ -1305,46 +1382,6 @@ found: return 0; } -static int __topo_bridge_connection(scf_vector_t* paths, ses_path_t* bridge, ScfEpin* vip, ses_path_t** ppath) -{ - ses_path_t* path; - ses_path_t* conn; - ScfEpin* p; - - int j; - int k; - - for (j = 0; j < paths->size; j++) { - path = paths->data[j]; - - if (path == bridge) - continue; - - for (k = 0; k < path->pins->size; k++) { - p = path->pins->data[k]; - - if (p->lid == vip->lid) { - *ppath = path; - return k; - } - } - - if (path->childs) { - k = __topo_bridge_connection(path->childs, bridge, vip, ppath); - if (k >= 0) - return k; - } - - if (path->bridges) { - k = __topo_bridge_connection(path->bridges, bridge, vip, ppath); - if (k >= 0) - return k; - } - } - - return -1; -} - static int _topo_add_connection(ses_path_t* path, ses_path_t* conn) { if (!conn->connections) { @@ -1359,6 +1396,8 @@ static int _topo_add_connection(ses_path_t* path, ses_path_t* conn) static int _topo_bridge_connections(ScfEfunction* f, scf_vector_t* paths) { ses_path_t* path; + ses_path_t* conn0; + ses_path_t* conn1; ScfEcomponent* B = f->components[0]; ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; @@ -1367,6 +1406,7 @@ static int _topo_bridge_connections(ScfEfunction* f, scf_vector_t* paths) ScfEpin* p1; int i; + int j; for (i = paths->size - 1; i >= 0; i--) { path = paths->data[i]; @@ -1379,26 +1419,68 @@ static int _topo_bridge_connections(ScfEfunction* f, scf_vector_t* paths) int k0 = __topo_bridge_connection(paths, path, p0, &path->conn0); if (k0 < 0) - return -EINVAL; + continue; int k1 = __topo_bridge_connection(paths, path, p1, &path->conn1); if (k1 < 0) - return -EINVAL; + continue; - path->parent = ses_path_same_net(path->conn0, path->conn1); - if (path->parent) { - path->parent_p0 = (k0 + 1) & ~0x1; - path->parent_p1 = k1; + path->parent_p0 = (k0 + 1) & ~0x1; + path->parent_p1 = k1; + path->parent = path->conn0; - int ret = _topo_add_connection(path, path->conn0); - if (ret < 0) - return ret; + int ret = _topo_add_connection(path, path->conn0); + if (ret < 0) + return ret; - ret = _topo_add_connection(path, path->conn1); - if (ret < 0) - return ret; + ret = _topo_add_connection(path, path->conn1); + if (ret < 0) + return ret; + + assert(0 == scf_vector_del(paths, path)); + } - assert(0 == scf_vector_del(paths, path)); + return 0; +} + +static int _topo_path_parallel(ScfEfunction* f, scf_vector_t* paths) +{ + ses_path_t* child; + ses_path_t* parent; + ScfEpin* p0; + ScfEpin* p1; + ScfEpin* p2; + ScfEpin* p3; + ScfEpin* p; + + int i; + int j; + + for (i = paths->size - 1; i >= 0; i--) { + child = paths->data[i]; + + assert(child->pins->size >= 2); + + p0 = child->pins->data[0]; + p1 = child->pins->data[child->pins->size - 1]; + + for (j = paths->size - 1; j >= 0; j--) { + parent = paths->data[j]; + + if (parent == child) + continue; + + p2 = parent->pins->data[0]; + p3 = parent->pins->data[parent->pins->size - 1]; + + if (p0->lid == p2->lid && p1->lid == p3->lid) { + + int ret = ses_path_add(parent, child, f); + if (ret < 0) + return ret; + + assert(0 == scf_vector_del(paths, child)); + } } } @@ -1439,41 +1521,6 @@ static int __ses_topo_layers(ScfEfunction* f, scf_vector_t* paths) return _topo_bridge_piers(f, paths); } -int __ses_topo_paths(ScfEfunction* f, scf_vector_t* paths) -{ - if (!f || !paths) - return -EINVAL; - - ses_path_t* path; - ScfEcomponent* B; - ScfEline* el; - - _topo_clear(f); - - scf_vector_clear(paths, ( void (*)(void*) )ses_path_free); - - B = f->components[0]; - el = f->elines[B->pins[SCF_EDA_Battery_POS]->lid]; - - int ret = _topo_paths(f, el, paths); - if (ret < 0) - return ret; - - int i; - for (i = 0; i < f->n_elines; i++) { - el = f->elines[i]; - - if (el->flags & SCF_EDA_PIN_IN) { - - ret = _topo_paths(f, el, paths); - if (ret < 0) - return ret; - } - } - - return __ses_topo_layers(f, paths); -} - static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) { ses_path_t* path; @@ -1500,6 +1547,10 @@ static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* if (ret < 0) return ret; + ret = _topo_path_parallel(f, ctx->paths); + if (ret < 0) + return ret; + int i; for (i = 0; i < ctx->paths->size; i++) { path = ctx->paths->data[i]; diff --git a/ses_step_va.c b/ses_step_va.c index cbdfb2c..7610a28 100644 --- a/ses_step_va.c +++ b/ses_step_va.c @@ -122,6 +122,7 @@ static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, int n, double sr = 0; double cv = 0; + double lv = 0; double dv = 0; double da = 0; double pr; @@ -133,14 +134,14 @@ static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, int n, ses_ur_i(&child->a0, NULL, v, 0, child->pr, 0); - if (__ses_path_capacitors(f, path, i, k, &cv) > 0) - v += cv; + __ses_path_lc(f, path, i, k, &cv, &lv, NULL, NULL, NULL); + v += cv + lv; ses_ur_i(&child->a, NULL, v, 0, child->pr, 0); - scf_logw("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d, n_NPNs: %d), v: %lg, cv: %lg, dv: %lg, a: %lg, pr: %lg, sr: %lg\n", + scf_logw("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d, n_NPNs: %d), v: %lg, cv: %lg, lv: %lg, dv: %lg, a: %lg, pr: %lg, sr: %lg\n", child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id, - child->n_diodes, child->n_NPNs, v, cv, dv, *a, pr, sr); + child->n_diodes, child->n_NPNs, v, cv, lv, dv, *a, pr, sr); *a -= child->a0; @@ -181,9 +182,9 @@ static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, int n, p1->pr = _pr1; p1->sr = _sr1; - scf_loge("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d), p->v: %lg, v: %lg, child->a0: %lg, child->a: %lg, cv: %lg, cda: %lg\n\n", + scf_loge("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d), p->v: %lg, v: %lg, child->a0: %lg, child->a: %lg, cv: %lg, lv: %lg\n\n", child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id, - child->n_diodes + child->n_NPNs, p0->v, v, child->a0, child->a, cv, child->cda); + child->n_diodes + child->n_NPNs, p0->v, v, child->a0, child->a, cv, lv); n_childs++; } @@ -207,7 +208,7 @@ static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i, p->v = p0->v - v; - if (SCF_EDA_Capacitor == c->type && (i & 0x1)) { + if ((SCF_EDA_Capacitor == c->type || SCF_EDA_Inductor == c->type) && (i & 0x1)) { int sign = !p->id - p->id; p->v -= c->v * sign; @@ -216,30 +217,55 @@ static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i, scf_logd("c%ldp%ld, c%ldp%ld, a: %lg, r: %lg, v: %lg, p0->v: %lg, p->v: %lg\n", p0->cid, p0->id, p->cid, p->id, a, r, v, p0->v, p->v); } -int __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv) +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; - double v = 0; - int k = 0; - int i; + 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 = f->components[p->cid]; - if (SCF_EDA_Capacitor == c->type && (i & 0x1)) { + if (i & 0x1) { int sign = !p->id - p->id; - v += c->v * sign; - k++; + 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; + } } } - - *cv = v; - return k; } int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count) @@ -255,9 +281,6 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double if (n - m < 1) return 0; -// if (path->vflag) -// return 0; - ScfEcomponent* c; ScfEline* el; ScfEpin* p; @@ -281,23 +304,23 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double } double cv = 0; + double lv = 0; double a = 0; double v = p0->v - p1->v; - __ses_path_capacitors(f, path, m, n, &cv); - v -= cv; + __ses_path_lc(f, path, m, n, &cv, &lv, NULL, NULL, NULL); + v -= cv + lv; ses_ur_i(&a, NULL, v, 0, pr, 0); if (0 == m && path->pins->size - 1 == n) path->a = a; - scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, 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, pr, path->pr, a); + scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, lv: %lg, pr: %lg, path->pr: %lg, a: %lg\n\n", + path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, lv, pr, path->pr, a); double r = 0; double dv = 0; - double dv0 = 0; double dvc = 0; int i0 = m; @@ -314,7 +337,7 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double __ses_path_split_v(f, path, i0, i, a); p->a = a; - p->v -= dv0 + dvc; + p->v -= dvc; el->v = p->v; r += p->r + p->dr; @@ -326,20 +349,30 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double int sign = !p->id - p->id; - c->a = a * sign; p2->a = a; if (SCF_EDA_Capacitor == c->type) { cv = c->v * sign; dv -= cv; - c->v += a * sign * ns / 1e3 / c->uf; - + c->a = a * sign; dvc += cv; - scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uf: %lg\n", + scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uF: %lg\n", c->id, c->v, p->v, p2->v, dv, p->a, c->a, ns, c->uf); - } + + } else if (SCF_EDA_Inductor == c->type) { + lv = c->v * sign; + dv -= lv; + + c->a = a * sign; + dvc += lv; + + scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uH: %lg\n", + c->id, c->v, p->v, p2->v, dv, p->a, c->a, ns, c->uh); + } else + c->a = a * sign; + c->count = 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", @@ -385,8 +418,8 @@ int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double r = 0; } else { dv = p->v; - scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, a: %lg, p->pr: %lg, dv0: %lg, e%ld->v: %lg\n", - path->index, i, p->cid, p->id, p->v, dv, a, p->pr, dv0, el->id, el->v); + scf_loge("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"); @@ -429,19 +462,20 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i ScfEpin* cp1; double cv = 0; + double lv = 0; double a = 0; double v = p0->v - p1->v; - __ses_path_capacitors(f, path, m, n, &cv); - v -= cv; + __ses_path_lc(f, path, m, n, &cv, &lv, NULL, NULL, NULL); + v -= cv + lv; ses_ur_i(&a, NULL, v, 0, pr, 0); if (0 == m && path->pins->size - 1 == n) path->a = a; - scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, 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, pr, path->pr, a); + scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, lv: %lg, pr: %lg, path->pr: %lg, a: %lg\n\n", + path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, lv, pr, path->pr, a); double r = 0; double dv = 0; @@ -505,6 +539,14 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uf: %lg\n", c->id, c->v, p->v, p2->v, dv, p->a, c->a, ns, c->uf); + + } else if (SCF_EDA_Inductor == c->type) { + lv = c->v * sign; + dv -= lv; + ses_ur_i(&p->a, NULL, dv, 0, r, 0); + + dvc += lv; + } else if (p->a > a) { p->a = a; c->a = p->a * sign; diff --git a/ses_step_va_diode.c b/ses_step_va_diode.c index 286b466..985a139 100644 --- a/ses_step_va_diode.c +++ b/ses_step_va_diode.c @@ -96,10 +96,11 @@ void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double continue; double cv = 0; + double lv = 0; if (child->n_capacitors > 0) { - __ses_path_capacitors(f, child, 0, child->pins->size - 1, &cv); - v -= cv; + __ses_path_lc(f, child, 0, child->pins->size - 1, &cv, &lv, NULL, NULL, NULL); + v -= cv + lv; ses_ur_i(&child->a, NULL, v, 0, child->pr, 0); } else { ses_ur_i(&child->a, NULL, v, 0, child->pr, 0); @@ -125,8 +126,8 @@ void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double goto ok; } - scf_logi("k: %d, c%ldp%ld--c%ldp%ld, v: %lg, cv: %lg, child->pr: %lg, r: %lg, child->a: %lg, el->a: %lg\n", - k, cp0->cid, cp0->id, cp1->cid, cp1->id, v, cv, child->pr, r, child->a, la); + scf_logi("k: %d, c%ldp%ld--c%ldp%ld, v: %lg, cv: %lg, lv: %lg, child->pr: %lg, r: %lg, child->a: %lg, el->a: %lg\n", + k, cp0->cid, cp0->id, cp1->cid, cp1->id, v, cv, lv, child->pr, r, child->a, la); cp1->v = p1->v; cp0->v = p0->v; @@ -235,6 +236,7 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path) double r; double a; double cv = 0; + double lv = 0; int i = 0; int j; @@ -252,9 +254,9 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path) || (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_lc(f, path, i, path->pins->size - 1, &cv, &lv, NULL, NULL, NULL); - __ses_path_a_diode(f, path, i, j, cv, &a); + __ses_path_a_diode(f, path, i, j, cv + lv, &a); if (a < 0) break; @@ -269,15 +271,16 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path) ses_ir_u(&v, NULL, a, 0, r, 0); double cv2 = 0; - __ses_path_capacitors(f, path, i, info->i, &cv2); + double lv2 = 0; + __ses_path_lc(f, path, i, info->i, &cv2, &lv2, NULL, NULL, NULL); - pi->v = p0->v - v - cv2; + pi->v = p0->v - v - cv2 - lv2; 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); + scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, cv2: %lg, lv2: %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, lv2, r, v, a); el = f->elines[pi->lid]; el->v = pi->v; diff --git a/ses_step_va_nodes.c b/ses_step_va_nodes.c index e450f7b..609c340 100644 --- a/ses_step_va_nodes.c +++ b/ses_step_va_nodes.c @@ -62,8 +62,8 @@ static int _va_nodes_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx p0 = path->pins->data[0]; p1 = path->pins->data[path->pins->size - 1]; - if (p0->lid != Bp->lid || p1->lid != Bn->lid) - continue; +// if (p0->lid != Bp->lid || p1->lid != Bn->lid) +// continue; scf_logi("i: %d, path->index: %d\n", i, path->index); diff --git a/ses_steps.c b/ses_steps.c index a269c8d..61c6a3b 100644 --- a/ses_steps.c +++ b/ses_steps.c @@ -12,13 +12,11 @@ extern ses_step_t ses_step_topo; extern ses_step_t ses_step_jr; extern ses_step_t ses_step_va_diode; -extern ses_step_t ses_step_va_transistor; extern ses_step_t ses_step_va; extern ses_step_t ses_step_status; extern ses_step_t ses_step_open; extern ses_step_t ses_step_va_nodes; -extern ses_step_t ses_step_va_capacitor; extern ses_step_t ses_step_a_stat; @@ -42,17 +40,16 @@ static ses_step_t* ses_steps_1[] = &ses_step_topo, - &ses_step_va_diode, +// &ses_step_va_diode, - &ses_step_va, - &ses_step_status, +// &ses_step_va, +// &ses_step_status, }; static ses_step_t* ses_steps_2[] = { &ses_step_open, &ses_step_va_nodes, -// &ses_step_va_capacitor, // &ses_step_a_stat, diff --git a/ses_utils.c b/ses_utils.c index a9ba53e..fd2a280 100644 --- a/ses_utils.c +++ b/ses_utils.c @@ -37,18 +37,12 @@ ses_edge_t* ses_edge_alloc(ses_path_t* path, int first, int last) edge->vip_m = first; edge->vip_n = last; - edge->refs = 1; return edge; } void ses_edge_free(ses_edge_t* edge) { if (edge) { - if (--edge->refs > 0) - return; - - assert(0 == edge->refs); - free(edge); } } @@ -103,68 +97,6 @@ void ses_edge_print(ses_edge_t* edge) printf("; "); } -ses_mesh_t* ses_mesh_alloc() -{ - ses_mesh_t* mesh = calloc(1, sizeof(ses_mesh_t)); - if (!mesh) - return NULL; - - mesh->edges = scf_vector_alloc(); - if (!mesh->edges) { - free(mesh); - return NULL; - } - - return mesh; -} - -void ses_mesh_free(ses_mesh_t* mesh) -{ - if (mesh) { - scf_vector_clear(mesh->edges, (void (*)(void*) )ses_edge_free); - scf_vector_free(mesh->edges); - - free(mesh); - } -} - -void ses_meshs_free(scf_vector_t* meshs) -{ - if (meshs) { - scf_vector_clear(meshs, (void (*)(void*) )ses_mesh_free); - scf_vector_free(meshs); - } -} - -void ses_mesh_print(ses_mesh_t* mesh) -{ - if (!mesh) - return; - - ses_edge_t* edge; - - int i; - - for (i = 0; i < mesh->edges->size; i++) { - edge = mesh->edges->data[i]; - - ses_edge_print(edge); - } - printf("\n"); -} - -void ses_meshs_print(scf_vector_t* meshs) -{ - if (!meshs) - return; - - int i; - for (i = 0; i < meshs->size; i++) { - - ses_mesh_print(meshs->data[i]); - } -} - ses_node_t* ses_node_alloc() { ses_node_t* node = calloc(1, sizeof(ses_node_t)); @@ -183,7 +115,6 @@ ses_node_t* ses_node_alloc() void ses_node_free(ses_node_t* node) { if (node) { - scf_vector_clear(node->edges, (void (*)(void*) )ses_edge_free); scf_vector_free(node->edges); free(node); diff --git a/test/Makefile b/test/Makefile index a10716e..5c5ce8c 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,7 +1,9 @@ #CFILES += main.c #CFILES += test.c -#CFILES += fft.c -CFILES += pnp.c +CFILES += fft.c +#CFILES += dct.c +#CFILES += pnp.c +#CFILES += colpitts.c CFILES += ../scf_eda_pack.c CFILES += ../pack/scf_pack.c diff --git a/test/colpitts.c b/test/colpitts.c new file mode 100644 index 0000000..dc1fe97 --- /dev/null +++ b/test/colpitts.c @@ -0,0 +1,101 @@ +#include +#include +#include +#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* L0; + + ScfEfunction* f; + ScfEboard* b; + + b = scf_eboard__alloc(); + f = scf_efunction__alloc("colpitts_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_NPN); + + 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, L0, SCF_EDA_Inductor); + + EDA_PIN_ADD_PIN(B, SCF_EDA_Battery_POS, R1, 1); + EDA_PIN_ADD_PIN(R1, 0, T0, SCF_EDA_NPN_C); + EDA_PIN_ADD_PIN(T0, SCF_EDA_NPN_E, R0, 1); + EDA_PIN_ADD_PIN(R0, 1, C0, 1); + EDA_PIN_ADD_PIN(R0, 0, C0, 0); + EDA_PIN_ADD_PIN(R0, 0, B, SCF_EDA_Battery_NEG); + + EDA_PIN_ADD_PIN(B, SCF_EDA_Battery_POS, R2, 1); + EDA_PIN_ADD_PIN(R2, 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, B, SCF_EDA_Battery_NEG); + EDA_PIN_ADD_PIN(L0, 1, T0, SCF_EDA_NPN_C); + EDA_PIN_ADD_PIN(L0, 0, C2, 1); + EDA_PIN_ADD_PIN(C2, 0, B, SCF_EDA_Battery_NEG); + EDA_PIN_ADD_PIN(C3, 1, C2, 1); + EDA_PIN_ADD_PIN(C3, 0, T0, SCF_EDA_NPN_B); + + T0->pins[SCF_EDA_NPN_C]->flags |= SCF_EDA_PIN_OUT; + T0->pins[SCF_EDA_NPN_C]->hfe = 150; + + R0->r = 1000; + R1->r = 1000; + R2->r = 1000 * 10; + R3->r = 1000 * 10; + C0->uf = 10; + C1->uf = 0.01; + C2->uf = 0.01; + C3->uf = 0.01; + C1->r = 1; + C2->r = 1; + C3->r = 1; + L0->uh = 1000; + L0->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("./colpitts_oscillator.cpk", "wb"); + if (!fp) + return -EINVAL; + + fwrite(buf, len, 1, fp); + fclose(fp); + + return 0; +} diff --git a/test/dct.c b/test/dct.c new file mode 100644 index 0000000..6d05f9f --- /dev/null +++ b/test/dct.c @@ -0,0 +1,69 @@ +#include +#include + +#define N 256 + +void dct(double* dst, double* src, int n) +{ + int i; + int u; + + for (u = 0; u < n; u++) { + dst[u] = 0; + + for (i = 0; i < n; i++) + dst[u] += src[i] * cos((i + 0.5) * 3.1415926 * u / n); + + if (0 == u) + dst[u] *= sqrt(1.0 / n); + else + dst[u] *= sqrt(2.0 / n); + } +} + +int main() +{ + double v; + + int i; + int j; + + FILE* fp = fopen("v.txt", "r"); + + double src[N]; + double dst[N]; + + for (i = 0; i < N; i++) { + fscanf(fp, "%d, %lg", &j, &v); + src[i] = v; + } + + dct(dst, src, N); + + double Zmax = 0; + double sum = 0; + int imax = 0; + + for (i = 0; i < N; i++) { + + if (i > 0) { + double Z = sqrt(dst[i] * dst[i]); + + if (Zmax < Z) { + Zmax = Z; + imax = i; + } + + sum += Z; + } + + printf("%d, %lg\n", i, dst[i]); + } + + double f = 100 * 1000 * imax / N; + + printf("avg: %lg, Zmax: %lg, imax: %d, f: %lg\n", sum / (N - 1), Zmax, imax, f); + + fclose(fp); + return 0; +} diff --git a/test/fft.c b/test/fft.c index f2384dc..b7812ee 100644 --- a/test/fft.c +++ b/test/fft.c @@ -8,7 +8,7 @@ #define REAL(z,i) ((z)[2*(i)]) #define IMAG(z,i) ((z)[2*(i)+1]) -#define N 1024 +#define N 256 int main() { @@ -32,7 +32,7 @@ int main() double sum = 0; int imax = 0; - for (i = 0; i < N; i++) { + for (i = 0; i < N / 2; i++) { if (i > 0) { double real = REAL(data, i) / sqrt(N);