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
CFILES += ses_step_open.c
CFILES += ses_step_va_nodes.c
-CFILES += ses_step_va_capacitor.c
CFILES += ses_step_a_stat.c
printf("f: %s\n", f->name);
- ses_steps_analyse(f, 1000, 1);
+ ses_steps_analyse(f, 100, 76000);
}
#endif
{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[] =
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;
double v;
double a;
-
double a0;
- double cda;
int type;
int index;
struct ses_edge_s
{
- int refs;
- int index;
-
ses_path_t* path;
int vip_m;
int vip_n;
double a;
double a0;
- uint8_t vflag:1;
+ int index;
+
uint8_t bflag:1;
};
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;
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);
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);
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);
if (!paths)
return -ENOMEM;
- int ret = __ses_topo_paths(f, paths);
+ int ret = ses_layout_paths(f, paths);
if (ret < 0)
goto end;
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;
--- /dev/null
+#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);
+}
#include"ses_core.h"
#include <gsl/gsl_linalg.h>
-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;
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;
}
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;
}
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;
}
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];
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;
edge_c->hfe = c->pins[SCF_EDA_NPN_C]->hfe;
}
+ case SCF_EDA_Inductor:
if (!node) {
node = ses_node_alloc();
if (!node)
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; \
}
}
- 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;
}
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];
}
}
- *nodes = vec;
+ *pnodes = nodes;
+ *pedges = edges;
return 0;
}
...
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)
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;
}
}
- 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 {
// 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++;
}
}
}
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;
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];
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;
}
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;
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;
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) {
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) {
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",
}
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;
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);
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);
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);
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");
#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;
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;
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;
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];
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;
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;
}
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)
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;
}
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) {
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;
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)
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];
if (path1 == path0)
continue;
+ if (path1->n_transistors > 0)
+ continue;
+
p2 = path1->pins->data[0];
p3 = path1->pins->data[path1->pins->size - 1];
ScfEpin* Bn;
ScfEpin* p0;
ScfEpin* p1;
+ ScfEpin* p2;
+ ScfEpin* p3;
ScfEpin* p;
int i;
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++) {
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];
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;
ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG];
ScfEpin* p0;
ScfEpin* p1;
- ScfEpin* p2;
- ScfEpin* p3;
int i;
int j;
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)
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) {
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];
ScfEpin* p1;
int i;
+ int j;
for (i = paths->size - 1; i >= 0; i--) {
path = paths->data[i];
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));
+ }
}
}
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;
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];
double sr = 0;
double cv = 0;
+ double lv = 0;
double dv = 0;
double da = 0;
double pr;
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;
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++;
}
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;
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)
if (n - m < 1)
return 0;
-// if (path->vflag)
-// return 0;
-
ScfEcomponent* c;
ScfEline* el;
ScfEpin* p;
}
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;
__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;
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",
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");
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;
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;
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);
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;
double r;
double a;
double cv = 0;
+ double lv = 0;
int i = 0;
int j;
|| (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;
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;
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);
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;
&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,
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);
}
}
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));
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);
#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
--- /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* 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;
+}
--- /dev/null
+#include <stdio.h>
+#include <math.h>
+
+#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;
+}
#define REAL(z,i) ((z)[2*(i)])
#define IMAG(z,i) ((z)[2*(i)+1])
-#define N 1024
+#define N 256
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);