From 196fcc3234810d3049aefdc5b594d0ea1b49d09e Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Fri, 7 Jun 2024 19:06:19 +0800 Subject: [PATCH] node analysis for DC --- Makefile | 1 - examples/add.cpk | Bin 1328 -> 1321 bytes main.c | 2 +- scf_eda_pack.c | 4 +- ses_mesh_analysis.c | 451 -------------------------------- ses_node_analysis.c | 212 ++++++++++++---- ses_path.c | 9 +- ses_step_simplify.c | 35 ++- ses_step_simplify2.c | 551 ---------------------------------------- ses_step_topo.c | 104 ++++++-- ses_step_va_capacitor.c | 476 ---------------------------------- 11 files changed, 267 insertions(+), 1578 deletions(-) delete mode 100644 ses_mesh_analysis.c delete mode 100644 ses_step_simplify2.c delete mode 100644 ses_step_va_capacitor.c diff --git a/Makefile b/Makefile index 4535c6c..c2528e8 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,6 @@ CFILES += ses_step_a_stat.c CFILES += ses_step_output.c CFILES += ses_step_simplify.c -CFILES += ses_step_simplify2.c CFLAGS += -g -D_GNU_SOURCE CFLAGS += -I./ diff --git a/examples/add.cpk b/examples/add.cpk index ed6037bdab3a8326037f1da43e53375b3fef996a..81750b927a09a87201365ecb5486c0f6ce55611c 100644 GIT binary patch delta 120 zcmdnMwUTSX77lR+1_nMphy2NgOfnO1dZO?ryE8sS7Dz_s$V}eJdname); - ses_steps_analyse(f, 100, 76000); + ses_steps_analyse(f, 100, 3); } #endif diff --git a/scf_eda_pack.c b/scf_eda_pack.c index ab2f548..cd251bf 100644 --- a/scf_eda_pack.c +++ b/scf_eda_pack.c @@ -31,10 +31,10 @@ static scf_edata_t pin_datas[] = {SCF_EDA_Diode, 0, SCF_EDA_Diode_NEG, 0, 0, 750, 0, 0, 0}, {SCF_EDA_NPN, 0, SCF_EDA_NPN_B, 0, 0, 750, 0, 0, 0}, - {SCF_EDA_NPN, 0, SCF_EDA_NPN_C, 0, 0, 10, 0, 0, 150}, + {SCF_EDA_NPN, 0, SCF_EDA_NPN_C, 0, 0, 3, 0, 0, 250}, {SCF_EDA_PNP, 0, SCF_EDA_PNP_B, 0, 0, 750, 0, 0, 0}, - {SCF_EDA_PNP, 0, SCF_EDA_PNP_C, 0, 0, 10, 0, 0, 150}, + {SCF_EDA_PNP, 0, SCF_EDA_PNP_C, 0, 0, 3, 0, 0, 250}, }; static scf_edata_t* _pin_find_data(const uint64_t type, const uint64_t model, const uint64_t pid) diff --git a/ses_mesh_analysis.c b/ses_mesh_analysis.c deleted file mode 100644 index 0a9f62e..0000000 --- a/ses_mesh_analysis.c +++ /dev/null @@ -1,451 +0,0 @@ -#include"ses_core.h" -#include - -int ses_mesh_ref_edge(ses_mesh_t* mesh, ses_edge_t* edge) -{ - int ret = scf_vector_add(mesh->edges, edge); - if (ret < 0) - return ret; - - edge->refs++; - return 0; -} - -int ses_mesh_add_edge(ses_mesh_t* mesh, 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(mesh->edges, edge); - if (ret < 0) { - ses_edge_free(edge); - return ret; - } - - if (pp) - *pp = edge; - return 0; -} - -static int __ses_meshs_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int vip_i, scf_vector_t** meshs) -{ - scf_vector_t* vec; - ses_path_t* child; - - ses_edge_t* edge = NULL; - ses_edge_t* prev = NULL; - ses_mesh_t* mesh; - ses_mesh_t* right = NULL; - - int ret = -1; - - vec = scf_vector_alloc(); - if (!vec) - return -ENOMEM; - - right = ses_mesh_alloc(); - if (!right) { - ret = -ENOMEM; - goto error; - } - - int i; - int j = vip_i; - int k; - - for (i = vip_i - 1; i >= vip_m; i -= 2) { - - ScfEpin* p = path->pins->data[i]; - - if (!path->childs) - continue; - - for (k = 0; k < path->childs->size; k++) { - child = path->childs->data[k]; - - if (child->parent_p0 == i && child->parent_p1 == vip_n) - break; - } - - if (k >= path->childs->size) - continue; - scf_logd("c%ldp%ld\n", p->cid, p->id); - - mesh = ses_mesh_alloc(); - if (!mesh) { - ret = -ENOMEM; - goto error; - } - - ret = scf_vector_add(vec, mesh); - if (ret < 0) { - ses_mesh_free(mesh); - goto error; - } - - if (prev) { - ret = ses_mesh_add_edge(mesh, prev->path, prev->vip_n, prev->vip_m, NULL); - if (ret < 0) - goto error; - } - - ret = ses_mesh_add_edge(mesh, path, j, i, &edge); - if (ret < 0) - goto error; - ret = ses_mesh_ref_edge(right, edge); - if (ret < 0) - goto error; - - ret = ses_mesh_add_edge(mesh, child, 0, child->pins->size - 1, &prev); - if (ret < 0) - goto error; - - j = i - 1; - } - - if (j > vip_m) { - ret = ses_mesh_add_edge(right, path, j, vip_m, NULL); - if (ret < 0) - goto error; - } - - ret = scf_vector_add(vec, right); - if (ret < 0) - goto error; - - *meshs = vec; - return 0; - -error: - if (right) - ses_mesh_free(right); - - scf_vector_clear(vec, (void (*)(void*) )ses_mesh_free); - scf_vector_free(vec); - return ret; -} - -int __ses_meshs_path(ScfEfunction* f, ses_path_t* path, scf_vector_t** meshs) -{ - int n = path->pins->size - 1; - - return __ses_meshs_path2(f, path, 0, n, n, meshs); -} - -/* - a[vip_n, 0] = Iright + I[0] - a[0, 1] = Iright + I[1] - a[1, 2] = Iright + I[2] - ... - a[n - 2, n - 1] = Iright + I[n - 1] - a[n - 1, vip_m] = Iright - - a[0] = I[0] - I[1] - a[1] = I[1] - I[2] - ... - a[n - 1] = I[n - 1] - ------------------------------ - v[0] - a[0] * R[0] = C[0] + Vn - v[1] - a[1] * R[1] = C[1] + Vn -... - v[n - 1] - a[n - 1] * R[n - 1] = C[n - 1] + Vn - - - v[vip_n] - v[0] - a[vip_n, 0] * R[vip_n, 0] = C[vip_n, 0] - v[0] - v[1] - a[0, 1] * R[0, 1] = C[0, 1] -... - v[n - 2] - v[n - 1] - a[n - 2, n - 1] * R[n - 2, n - 1] = C[n - 2, n - 1] - v[n - 1] - a[n - 1, m] * R[n - 1, m] = C[n - 1, m] + Vm - ------------------------------ - v[0] - (I[0] - I[1]) * R[0] = C[0] + Vn - v[1] - (I[1] - I[2]) * R[1] = C[1] + Vn -... - v[n - 2] - (I[n -2] - I[n-1]) * R[n - 2] = C[n - 2] + Vn - v[n - 1] - I[n -1] * R[n - 1] = C[n - 1] + Vn - - - v[0] - (Iright + I[0]) * R[vip_n, 0] = C[vip_n, 0] - Vn - v[0] - v[1] - (Iright + I[1]) * R[0, 1] = C[0, 1] -... - v[n - 2] - v[n - 1] - (Iright + I[n-1]) * R[n - 2, n - 1] = C[n - 2, n - 1] - v[n - 1] - Iright * R[n - 1, m] = C[n - 1, m] + Vm - ------------------------------ - 0: v[0] - 1: v[1] - ... -n - 1: v[n - 1] - -n : I[0] -n + 1: I[1] - ... -2n -1: I[n - 1] -2n : Iright -*/ - -static int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* meshs, int* changed, int64_t ns, int64_t count) -{ - ses_mesh_t* mesh; - ses_edge_t* edge; - - ScfEline* el; - ScfEpin* pm = path->pins->data[vip_m]; - ScfEpin* pn = path->pins->data[vip_n]; - ScfEpin* p0; - ScfEpin* p1; - - int ret = 0; - - int n = meshs->size - 1; - int N = 2 * n + 1; - int i; - - scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, n_childs: %d, N: %d\n", pm->cid, pm->id, pm->v, pn->cid, pn->id, pn->v, n, N); - - double* A = calloc(N * N + N + N, sizeof(double)); - if (!A) - return -ENOMEM; - - double* b = A + N * N; - double* X = b + N; - double cv; - double r; - - __ses_path_jr(f, path); - - for (i = 0; i < meshs->size - 1; i++) { - mesh = meshs->data[i]; - - edge = mesh->edges->data[mesh->edges->size - 1]; - - __ses_path_capacitors(f, edge->path, edge->vip_m, edge->vip_n, &cv); - b[i] = cv + pn->v; - - if (0 == edge->vip_m && edge->vip_n == edge->path->pins->size - 1) - r = edge->path->pr; - else - __ses_path_sr(f, edge->path, edge->vip_m, edge->vip_n, &r); - - edge->r = r; - - p0 = edge->path->pins->data[edge->vip_m]; - p1 = edge->path->pins->data[edge->vip_n]; - scf_logi("c%ldp%ld-c%ldp%ld, r: %lg, cv: %lg\n", p0->cid, p0->id, p1->cid, p1->id, r, cv); - - A[i * N + i] = 1; - A[i * N + n + i] = -r; - - if (i < n - 1) - A[i * N + n + i + 1] = r; - } - - mesh = meshs->data[meshs->size - 1]; - - for (i = 0; i < mesh->edges->size; i++) { - edge = mesh->edges->data[i]; - - if (edge->vip_m > edge->vip_n) { - - if (0 == edge->vip_n && edge->vip_m == edge->path->pins->size - 1) - r = edge->path->pr; - else - __ses_path_sr(f, edge->path, edge->vip_n, edge->vip_m, &r); - - __ses_path_capacitors(f, edge->path, edge->vip_n, edge->vip_m, &cv); - b[n + i] = -cv; - } else { - __ses_path_capacitors(f, edge->path, edge->vip_m, edge->vip_n, &cv); - b[n + i] = cv; - - if (0 == edge->vip_m && edge->vip_n == edge->path->pins->size - 1) - r = edge->path->pr; - else - __ses_path_sr(f, edge->path, edge->vip_m, edge->vip_n, &r); - } - - if (i > 0) - A[(n + i) * N + i - 1] = 1; - else - b[n + i] -= pn->v; - - if (i < n) { - A[(n + i) * N + i] = -1; - A[(n + i) * N + n + i] = -r; - } else - b[n + i] += pm->v; - - A[(n + i) * N + 2 * n] = -r; - - p0 = edge->path->pins->data[edge->vip_m]; - p1 = edge->path->pins->data[edge->vip_n]; - - edge->r = r; - - scf_logi("c%ldp%ld-c%ldp%ld, r: %lg, cv: %lg, vip_m: %d, vip_n: %d\n", p0->cid, p0->id, p1->cid, p1->id, r, cv, edge->vip_m, edge->vip_n); - } - - gsl_matrix_view _A = gsl_matrix_view_array(A, N, N); - gsl_vector_view _b = gsl_vector_view_array(b, N); - gsl_vector_view _X = gsl_vector_view_array(X, N); - - int s; - gsl_permutation* _P = gsl_permutation_alloc(N); - if (!_P) { - ret = -ENOMEM; - goto P_failed; - } - - gsl_linalg_LU_decomp(&_A.matrix, _P, &s); - gsl_linalg_LU_solve (&_A.matrix, _P, &_b.vector, &_X.vector); - - scf_logi("X:\n"); - gsl_vector_fprintf(stdout, &_X.vector, "%lg"); -#if 1 - for (i = 0; i < meshs->size - 1; i++) { - mesh = meshs->data[i]; - - edge = mesh->edges->data[mesh->edges->size - 1]; - - p0 = edge->path->pins->data[edge->vip_m]; - p1 = edge->path->pins->data[edge->vip_n]; - - el = f->elines[p0->lid]; - el->v = X[i]; - - ret = __ses_path_va_branch(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ns, count); - if (ret < 0) - goto error; - } - - mesh = meshs->data[meshs->size - 1]; - - for (i = 0; i < mesh->edges->size; i++) { - edge = mesh->edges->data[i]; - - p0 = edge->path->pins->data[edge->vip_m]; - p1 = edge->path->pins->data[edge->vip_n]; - - ret = __ses_path_va_branch(f, edge->path, edge->vip_n, edge->vip_m, edge->r, changed, ns, count); - if (ret < 0) - goto error; - } -#endif -error: - gsl_permutation_free(_P); -P_failed: - free(A); - return ret; -} - -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) -{ - scf_vector_t* meshs = NULL; - ses_mesh_t* mesh; - ses_edge_t* edge; - - ScfEline* el; - ScfEpin* pm = path->pins->data[vip_m]; - ScfEpin* pn = path->pins->data[vip_n]; - ScfEpin* p0; - ScfEpin* p1; - - int ret = __ses_meshs_path2(f, path, vip_m, vip_n, vip_n, &meshs); - if (ret < 0) - return ret; - - ses_meshs_print(meshs); - - ret = __ses_meshs_path_solve2(f, path, vip_m, vip_n, meshs, changed, ns, count); - - scf_vector_clear(meshs, (void (*)(void*) )ses_mesh_free); - scf_vector_free(meshs); - - return ret; -} - -int __ses_meshs_PPN(ScfEfunction* f, ses_flow_t* flow, ses_path_t* bridge, scf_vector_t** meshs) -{ - scf_vector_t* vec = NULL; - ses_path_t* path = flow->paths->data[0]; - - ses_edge_t* edge0 = NULL; - ses_edge_t* edge1 = NULL; - ses_mesh_t* mesh; - ses_mesh_t* left; - ses_mesh_t* right; - - int ret = __ses_meshs_path2(f, path, flow->vip_m, flow->vip_n, flow->vip_i, &vec); - if (ret < 0) - return ret; - - mesh = vec->data[0]; - right = vec->data[vec->size - 1]; - - left = ses_mesh_alloc(); - if (!left) { - ret = -ENOMEM; - goto error; - } - - ret = scf_vector_add(vec, left); - if (ret < 0) { - ses_mesh_free(left); - goto error; - } - scf_vector_mov_first(vec, vec->size - 1, left); - - ret = ses_mesh_add_edge(left, bridge, 0, bridge->pins->size - 1, &edge0); - if (ret < 0) - goto error; - - ret = ses_mesh_ref_edge(right, edge0); - if (ret < 0) - goto error; - - ret = ses_mesh_add_edge(left, path, flow->vip_i + 1, flow->vip_n, NULL); - if (ret < 0) - goto error; - - ret = ses_mesh_add_edge(mesh, path, flow->vip_n, flow->vip_i + 1, &edge1); - if (ret < 0) - goto error; - - scf_vector_mov_first(right->edges, right->edges->size - 1, edge0); - scf_vector_mov_first(mesh ->edges, mesh ->edges->size - 1, edge1); - - *meshs = vec; - return 0; - -error: - scf_vector_clear(vec, (void (*)(void*) )ses_mesh_free); - scf_vector_free(vec); - return ret; -} - -int __ses_meshs_PPN_solve(ScfEfunction* f, ses_flow_t* flow, ses_path_t* bridge, int* changed, int64_t ns, int64_t count) -{ - scf_vector_t* meshs = NULL; - ses_path_t* path = flow->paths->data[0]; - ses_mesh_t* mesh; - ses_edge_t* edge; - - ScfEline* el; - ScfEpin* pm = path->pins->data[flow->vip_m]; - ScfEpin* pn = path->pins->data[flow->vip_n]; - ScfEpin* p0; - ScfEpin* p1; - - int ret = __ses_meshs_PPN(f, flow, bridge, &meshs); - if (ret < 0) - return ret; - - ses_meshs_print(meshs); - - ret = __ses_meshs_path_solve2(f, path, flow->vip_m, flow->vip_n, meshs, changed, ns, count); - - scf_vector_clear(meshs, (void (*)(void*) )ses_mesh_free); - scf_vector_free(meshs); - return ret; -} diff --git a/ses_node_analysis.c b/ses_node_analysis.c index 4167499..02fa9a3 100644 --- a/ses_node_analysis.c +++ b/ses_node_analysis.c @@ -43,10 +43,10 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s ses_path_t* bridge; ses_path_t* conn; - ses_edge_t* edge = NULL; - ses_edge_t* edge_c = NULL; - ses_node_t* prev = NULL; - ses_node_t* node = NULL; + ses_edge_t* edge = NULL; + ses_edge_t* edge2 = NULL; + ses_node_t* prev = NULL; + ses_node_t* node = NULL; ScfEcomponent* c; ScfEpin* p; @@ -114,15 +114,11 @@ 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_edges_find_edge_by_pin(edges, c->pins[SCF_EDA_NPN_C]); - if (!edge_c) { - scf_loge("\n"); - return -EINVAL; - } - bflag = 1; - edge_c->hfe = c->pins[SCF_EDA_NPN_C]->hfe; - } + edge2 = ses_edges_find_edge_by_pin(edges, c->pins[SCF_EDA_NPN_C]); + + } else if (SCF_EDA_NPN_C == p->id) + edge2 = ses_edges_find_edge_by_pin(edges, c->pins[SCF_EDA_NPN_B]); case SCF_EDA_Inductor: if (!node) { @@ -253,9 +249,16 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s edge->node0 = prev; } - if (edge_c) { - edge_c->edge_b = edge; - edge_c = NULL; + if (edge2) { + if (edge ->bflag) { + edge2->edge_b = edge; + edge2->hfe = c->pins[SCF_EDA_NPN_C]->hfe; + } else { + assert(edge2->bflag); + edge->edge_b = edge2; + edge->hfe = c->pins[SCF_EDA_NPN_C]->hfe; + } + edge2 = NULL; } prev = node; @@ -454,17 +457,13 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, 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 - A[(n + edge->index) * N + n + edge->index] = -r - uh * 1000.0 / ns; - } + */ + 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 + A[(n + edge->index) * N + n + edge->index] = -r - uh * 1000.0 / ns; if (edge->node0 && edge->node0->lid != Bn->lid) A[(n + edge->index) * N + edge->node0->index] = -1; @@ -477,15 +476,28 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, b[n + edge->index] -= Bp->v; } - int n_amplifiers; + scf_logi("-----check transistor ON / OFF\n"); + + gsl_matrix_view _A = gsl_matrix_view_array(U, N, N); + gsl_vector_view _b = gsl_vector_view_array(b, N); + gsl_vector_view _X = gsl_vector_view_array(X, N); + + gsl_vector_view _W = gsl_vector_view_array(W, N); + gsl_vector_view _S = gsl_vector_view_array(S, N); + gsl_matrix_view _V = gsl_matrix_view_array(V, N, N); + + int __changed = 0; + int __need = 0; do { - n_amplifiers = 0; + __changed = 0; + __need = 0; + memcpy(U, A, sizeof(double) * N * N); -#if 0 +#if 1 for (i = 0; i < N; i++) { for (j = 0; j < N; j++) - printf("%8lg ", A[i * N + j]); + printf("%lg ", A[i * N + j]); printf("\n"); } printf("\n"); @@ -494,46 +506,76 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, printf("%lg\n", b[j]); #endif - gsl_matrix_view _A = gsl_matrix_view_array(U, N, N); - gsl_vector_view _b = gsl_vector_view_array(b, N); - gsl_vector_view _X = gsl_vector_view_array(X, N); - - gsl_vector_view _W = gsl_vector_view_array(W, N); - gsl_vector_view _S = gsl_vector_view_array(S, N); - gsl_matrix_view _V = gsl_matrix_view_array(V, N, N); - gsl_linalg_SV_decomp(&_A.matrix, &_V.matrix, &_S.vector, &_W.vector); gsl_linalg_SV_solve (&_A.matrix, &_V.matrix, &_S.vector, &_b.vector, &_X.vector); -// scf_logi("X:\n"); -// gsl_vector_fprintf(stdout, &_X.vector, "%lg"); + scf_logi("X:\n"); + for (i = 0; i < N; i++) + scf_logi("%lg\n", X[i]); 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]; + p0 = edge->path->pins->data[edge->vip_m]; + p1 = edge->path->pins->data[edge->vip_n]; + c = f->components[p0->cid]; - double dI = Ib * edge->hfe - Ic; + if (edge->bflag) { + double Vb; + double Ve; - if (dI < -1e-10) { - scf_logi("Ic: %lg, Ib: %lg, dI: %lg\n", Ic, Ib, dI); + if (edge->node1 && edge->node1->lid != Bp->lid) + Vb = X[edge->node1->index]; + else + Vb = Bp->v; - int k; - for (k = 0; k < N; k++) - A[(n + edge->index) * N + k] = 0; + if (edge->node0 && edge->node0->lid != Bn->lid) + Ve = X[edge->node0->index]; + else + Ve = Bn->v; - 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; + double dV = Vb - Ve; - n_amplifiers++; + if (dV > 0.07) { + if (dV < SCF_EDA_V_NPN_ON * 0.99) { + + scf_logi("edge: [%d] c%ldp%ld-c%ldp%ld, Vb: %lg, Ve: %lg, dV: %lg\n", + edge->index, p0->cid, p0->id, p1->cid, p1->id, Vb, Ve, dV); + + double Ib = X[n + edge->index]; + + A[(n + edge->index) * N + n + edge->index] = -SCF_EDA_V_NPN_ON / Ib; + __need++; + } + } else { + c->status = SCF_EDA_Status_OFF; + c->lock = 1; + __changed++; + + scf_loge("\033[34mc%ld, status: %d, dV: %lg, edge->index: %d\033[0m\n", c->id, c->status, dV, edge->index); } } } - } while (n_amplifiers > 0); + } while (__need > 0); + + scf_logi("-----check transistor on amplified / saturate\n"); + + memcpy(U, A, sizeof(double) * N * N); +#if 1 + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) + printf("%lg ", A[i * N + j]); + printf("\n"); + } + printf("\n"); + + for (j = 0; j < N; j++) + printf("%lg\n", b[j]); +#endif + gsl_linalg_SV_decomp(&_A.matrix, &_V.matrix, &_S.vector, &_W.vector); + gsl_linalg_SV_solve (&_A.matrix, &_V.matrix, &_S.vector, &_b.vector, &_X.vector); + scf_logi("X:\n"); for (i = 0; i < N; i++) scf_logi("%lg\n", X[i]); @@ -544,7 +586,67 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, el->v = X[i]; } - int __changed = 0; + if (__changed > 0) { + *changed += __changed; + return 0; + } + + 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]; + + double dI = Ib * edge->hfe - Ic; + + if (Ib > 0 && dI < -1e-10) { + p0 = edge->path->pins->data[edge->vip_m]; + p1 = edge->path->pins->data[edge->vip_n]; + + scf_logi("edge: [%d] c%ldp%ld-c%ldp%ld [b%d], Ic: %lg, Ib: %lg, dI: %lg\n", + edge->index, p0->cid, p0->id, p1->cid, p1->id, edge->edge_b->index, Ic, Ib, dI); + + 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; + } + } + } + + scf_logi("-----final result\n"); + + memcpy(U, A, sizeof(double) * N * N); +#if 1 + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) + printf("%lg ", A[i * N + j]); + printf("\n"); + } + printf("\n"); + + for (j = 0; j < N; j++) + printf("%lg\n", b[j]); +#endif + gsl_linalg_SV_decomp(&_A.matrix, &_V.matrix, &_S.vector, &_W.vector); + gsl_linalg_SV_solve (&_A.matrix, &_V.matrix, &_S.vector, &_b.vector, &_X.vector); + + scf_logi("result X:\n"); + for (i = 0; i < N; i++) + scf_logi("%lg\n", X[i]); + + for (i = 0; i < n; i++) { + node = nodes->data[i]; + + el = f->elines[node->lid]; + el->v = X[i]; + } + + __changed = 0; for (j = 0; j < edges->size; j++) { edge = edges->data[j]; diff --git a/ses_path.c b/ses_path.c index d17ce5d..c3a5039 100644 --- a/ses_path.c +++ b/ses_path.c @@ -478,15 +478,8 @@ int ses_path_add(ses_path_t* parent, ses_path_t* child, ScfEfunction* f) continue; } - if (path->parent_p0 == child->parent_p0 && path->parent_p1 == old_parent_p1) { - - assert(0 == scf_vector_del(parent->childs, path)); - - ret = ses_path_add(child, path, f); - if (ret < 0) - return ret; + if (path->parent_p0 == child->parent_p0 && path->parent_p1 == old_parent_p1) continue; - } cp0 = path->pins->data[0]; cp1 = path->pins->data[path->pins->size - 1]; diff --git a/ses_step_simplify.c b/ses_step_simplify.c index 848de5e..c945639 100644 --- a/ses_step_simplify.c +++ b/ses_step_simplify.c @@ -388,9 +388,17 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) } cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - ses_text_a(cr, c->x, (pb->y + c->y) / 2, pb->a); - ses_text_a(cr, c->x, c->y, pc->a); - ses_text_a(cr, c->x, (pe->y + c->y) / 2, pe->a); + if (pb->y > c->y) + ses_text_a(cr, c->x, c->y + 20, pb->a); + else + ses_text_a(cr, c->x, c->y - 20, pb->a); + + ses_text_a(cr, c->x, c->y, pc->a); + + if (pe->y > c->y) + ses_text_a(cr, c->x, c->y + 20, pe->a); + else + ses_text_a(cr, c->x, c->y - 20, pe->a); cairo_stroke(cr); break; @@ -449,9 +457,18 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) } cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - ses_text_a(cr, c->x, (pb->y + c->y) / 2, pb->a); - ses_text_a(cr, c->x, c->y, pc->a); - ses_text_a(cr, c->x, (pe->y + c->y) / 2, pe->a); + + if (pb->y > c->y) + ses_text_a(cr, c->x, c->y + 20, pb->a); + else + ses_text_a(cr, c->x, c->y - 20, pb->a); + + ses_text_a(cr, c->x, c->y, pc->a); + + if (pe->y > c->y) + ses_text_a(cr, c->x, c->y + 20, pe->a); + else + ses_text_a(cr, c->x, c->y - 20, pe->a); cairo_stroke(cr); break; default: @@ -646,12 +663,12 @@ 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 1 - if (count < 70000) +#if 0 + if (count < 64000) return 0; #endif - if (count % 10 == 0) { + if (1 || count % 10 == 0) { #if 1 static FILE* fp = NULL; if (!fp) diff --git a/ses_step_simplify2.c b/ses_step_simplify2.c deleted file mode 100644 index afdc666..0000000 --- a/ses_step_simplify2.c +++ /dev/null @@ -1,551 +0,0 @@ -#include -#include"ses_core.h" - -static void ses_text_cda(cairo_t* cr, int x, int y, double a) -{ - char text[64]; - - cairo_set_source_rgb(cr, 0.0, 0.7, 0.0); - - if (a > 1e-1 || a < -1e-1) { - snprintf(text, sizeof(text) - 1, "%lgA", (int)(a * 1000) / 1000.0); - - cairo_move_to (cr, x, y); - cairo_show_text(cr, text); - - } else if (a > 1e-5 || a < -1e-5) { - snprintf(text, sizeof(text) - 1, "%lgmA", (int)(a * 1000000) / 1000.0); - - cairo_move_to (cr, x, y); - cairo_show_text(cr, text); - - } else { - snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000000LL) / 1000.0); - - cairo_move_to (cr, x, y); - cairo_show_text(cr, text); - } -} - -static void ses_text_a(cairo_t* cr, int x, int y, double a) -{ - char text[64]; - - if (a > 0) - cairo_set_source_rgb(cr, 0.7, 0.0, 0.0); - else - cairo_set_source_rgb(cr, 0.0, 0.0, 0.7); - - if (a > 1e-1 || a < -1e-1) { - snprintf(text, sizeof(text) - 1, "%lgA", (int)(a * 1000) / 1000.0); - - cairo_move_to (cr, x, y); - cairo_show_text(cr, text); - - } else if (a > 1e-5 || a < -1e-5) { - snprintf(text, sizeof(text) - 1, "%lgmA", (int)(a * 1000000) / 1000.0); - - cairo_move_to (cr, x, y); - cairo_show_text(cr, text); - - } else if (a > 1e-9 || a < -1e-9) { - snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000000LL) / 1000.0); - - cairo_move_to (cr, x, y); - cairo_show_text(cr, text); - } -} - -static void ses_text_v(cairo_t* cr, int x, int y, double v) -{ - char text[64]; - - if (v > 0) - cairo_set_source_rgb(cr, 0.7, 0.0, 0.0); - else - cairo_set_source_rgb(cr, 0.0, 0.0, 0.7); - - if (v > 1e-1 || v < -1e-1) { - snprintf(text, sizeof(text) - 1, "%lgv", (int)(v * 1000) / 1000.0); - - cairo_move_to (cr, x, y); - cairo_show_text(cr, text); - - } else if (v > 1e-5 || v < -1e-5) { - snprintf(text, sizeof(text) - 1, "%lgmV", (int)(v * 1000000) / 1000.0); - - cairo_move_to (cr, x, y); - cairo_show_text(cr, text); - } -} - -static void __ses_function_draw(ScfEfunction* f, cairo_t* cr) -{ - ScfEcomponent* c; - ScfEpin* p; - ScfEpin* pb; - ScfEpin* pc; - ScfEpin* pe; - - size_t j; - size_t k; - - for (j = 0; j < f->n_components; j++) { - c = f->components[j]; - - cairo_set_line_width(cr, 2.5); - - uint8_t text[64]; - int n = snprintf(text, sizeof(text) - 1, "%ld", c->id); - - cairo_set_source_rgb (cr, 0, 0, 0); - cairo_select_font_face(cr, "Calibri", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size (cr, 20); - cairo_move_to (cr, c->x - 10 - n * 10, c->y - 5); - cairo_show_text (cr, text); - cairo_stroke(cr); - - if ((SCF_EDA_Diode == c->type || SCF_EDA_NPN == c->type) && SCF_EDA_Status_OFF == c->status) - cairo_set_source_rgb(cr, 0.0, 0.6, 0.6); - else - cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); - - for (k = 0; k < c->n_pins; k++) { - p = c->pins[k]; - - cairo_arc (cr, p->x, p->y, 4, 0, 2 * M_PI); - cairo_fill(cr); - } - cairo_stroke(cr); - - int dx0; - int dy0; - - int dx1; - int dy1; - int dx2; - int dy2; - - int dx3; - int dy3; - int dx4; - int dy4; - - switch (c->type) { - - case SCF_EDA_Battery: - p = c->pins[SCF_EDA_Battery_POS]; - - if (p->y < c->y) { - cairo_move_to(cr, c->x - 12, c->y - 5); - cairo_line_to(cr, c->x + 12, c->y - 5); - - cairo_move_to(cr, c->x, c->y - 5); - cairo_line_to(cr, p->x, p->y); - - cairo_move_to(cr, c->x - 8, c->y + 5); - cairo_line_to(cr, c->x + 8, c->y + 5); - - p = c->pins[SCF_EDA_Battery_NEG]; - cairo_move_to(cr, c->x, c->y + 5); - cairo_line_to(cr, p->x, p->y); - - } else { - cairo_move_to(cr, c->x - 12, c->y + 5); - cairo_line_to(cr, c->x + 12, c->y + 5); - - cairo_move_to(cr, c->x, c->y + 5); - cairo_line_to(cr, p->x, p->y); - - cairo_move_to(cr, c->x - 8, c->y - 5); - cairo_line_to(cr, c->x + 8, c->y - 5); - - p = c->pins[SCF_EDA_Battery_NEG]; - cairo_move_to(cr, c->x, c->y - 5); - cairo_line_to(cr, p->x, p->y); - } - - cairo_stroke(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); - cairo_line_to(cr, c->x + 8, c->y - 5); - cairo_stroke(cr); - - cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); - cairo_move_to(cr, c->x, c->y - 5); - } else { - cairo_move_to(cr, c->x - 8, c->y + 5); - cairo_line_to(cr, c->x + 8, c->y + 5); - cairo_stroke(cr); - - cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); - cairo_move_to(cr, c->x, c->y + 5); - } - cairo_line_to(cr, p->x, p->y); - cairo_stroke(cr); - - cairo_set_source_rgb(cr, 0.0, 0.0, 0.8); - p = c->pins[SCF_EDA_Battery_NEG]; - if (p->y < c->y) { - cairo_move_to(cr, c->x - 8, c->y - 5); - cairo_line_to(cr, c->x + 8, c->y - 5); - cairo_stroke(cr); - - cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); - cairo_move_to(cr, c->x, c->y - 5); - } else { - cairo_move_to(cr, c->x - 8, c->y + 5); - cairo_line_to(cr, c->x + 8, c->y + 5); - cairo_stroke(cr); - - cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); - cairo_move_to(cr, c->x, c->y + 5); - } - cairo_line_to(cr, p->x, p->y); - 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); - - 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_Resistor: - p = c->pins[0]; - - vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 6); - forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 12); - - cairo_move_to(cr, p->x, p->y); - cairo_line_to(cr, c->x - dx1, c->y - dy1); - cairo_stroke(cr); - - cairo_set_source_rgb(cr, 0.0, 0.0, 0.8); - - cairo_move_to (cr, c->x - dx1 + dx0, c->y - dy1 + dy0); - cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); - cairo_stroke(cr); - - cairo_set_source_rgb(cr, 0.6, 0.6, 0.0); - - cairo_move_to (cr, c->x - dx1 - dx0, c->y - dy1 - dy0); - cairo_rel_line_to(cr, dx1 * 2, dy1 * 2); - cairo_rel_line_to(cr, dx0 * 2, dy0 * 2); - cairo_rel_line_to(cr, -dx1 * 2, -dy1 * 2); - - p = c->pins[1]; - cairo_move_to (cr, p->x, p->y); - cairo_line_to (cr, c->x + dx1, c->y + dy1); - cairo_stroke(cr); - - cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - - 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->r > 1e6) - snprintf(text, sizeof(text) - 1, "%dM", (int)(c->r / 1000000.0)); - else - snprintf(text, sizeof(text) - 1, "%dk", (int)(c->r / 1000.0)); - - cairo_move_to (cr, c->x + 4, c->y - 5); - cairo_show_text(cr, text); - cairo_stroke(cr); - break; - - case SCF_EDA_Diode: - p = c->pins[SCF_EDA_Diode_POS]; - - vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 6); - forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 6); - - cairo_move_to(cr, p->x, p->y); - cairo_line_to(cr, c->x - dx1, c->y - dy1); - - cairo_rel_move_to(cr, dx0, dy0); - cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); - cairo_line_to (cr, c->x + dx1, c->y + dy1); - cairo_line_to (cr, c->x + dx0 - dx1, c->y + dy0 - dy1); - - p = c->pins[SCF_EDA_Diode_NEG]; - - cairo_move_to (cr, p->x, p->y); - cairo_line_to (cr, c->x + dx1, c->y + dy1); - cairo_rel_move_to(cr, dx0, dy0); - cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); - - ses_text_a(cr, c->x + 10, c->y + 25, c->a); - cairo_stroke(cr); - break; - - case SCF_EDA_NPN: - pb = c->pins[SCF_EDA_NPN_B]; - pc = c->pins[SCF_EDA_NPN_C]; - pe = c->pins[SCF_EDA_NPN_E]; - - vertical(&dx0, &dy0, c->x - pb->x, c->y - pb->y, 8); - forward (&dx3, &dy3, c->x - pb->x, c->y - pb->y, 8); - - cairo_arc(cr, c->x - dx3 / 2, c->y - dy3 / 2, 12, 0, 2 * M_PI); - - cairo_move_to (cr, pb->x, pb->y); - cairo_line_to (cr, c->x - dx3, c->y - dy3); - cairo_rel_move_to(cr, dx0, dy0); - cairo_rel_line_to(cr, -dx0 * 2, -dy0 * 2); - cairo_stroke(cr); - - if ((c->x + dx3 + dx0 > c->x + dx3 - dx0 && pe->x > pc->x) - || (c->x + dx3 + dx0 < c->x + dx3 - dx0 && pe->x < pc->x)) { - - cairo_move_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); - cairo_line_to(cr, pe->x, pe->y); - - vertical(&dx1, &dy1, dx3 * 2 + dx0, dy3 * 2 + dy0, 3); - forward (&dx4, &dy4, dx3 * 2 + dx0, dy3 * 2 + dy0, 8); - - cairo_move_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1); - cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); - cairo_line_to(cr, c->x - dx3 + dx4 - dx1, c->y - dy3 + dy4 - dy1); - cairo_stroke(cr); - - cairo_move_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); - cairo_line_to(cr, pc->x, pc->y); - cairo_stroke(cr); - } else { - cairo_move_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0); - cairo_line_to(cr, pc->x, pc->y); - cairo_stroke(cr); - - cairo_move_to(cr, c->x - dx3, c->y - dy3); - cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); - cairo_line_to(cr, pe->x, pe->y); - - vertical(&dx1, &dy1, dx3 * 2 - dx0, dy3 * 2 - dy0, 3); - forward (&dx4, &dy4, dx3 * 2 - dx0, dy3 * 2 - dy0, 8); - - cairo_move_to(cr, c->x - dx3 + dx4 + dx1, c->y - dy3 + dy4 + dy1); - cairo_line_to(cr, c->x + dx3 - dx0, c->y + dy3 - dy0); - cairo_line_to(cr, c->x - dx3 + dx4 - dx1, c->y - dy3 + dy4 - dy1); - cairo_stroke(cr); - } - - cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - ses_text_a(cr, c->x, (pb->y + c->y) / 2, pb->a); - ses_text_a(cr, c->x, c->y, pc->a); - ses_text_a(cr, c->x, (pe->y + c->y) / 2, pe->a); - cairo_stroke(cr); - break; - default: - break; - }; - } -} - -static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh, int64_t count) -{ - ScfEcomponent* B; - ScfEcomponent* c; - ScfEline* el; - ScfLine* l; - - cairo_surface_t* surface; - cairo_t* cr; - - surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, bx + bw, by + bh); - cr = cairo_create (surface); - - cairo_set_line_width(cr, 2); - cairo_set_source_rgb(cr, 1, 1, 1); - cairo_rectangle (cr, 0, 0, bx + bw, by + bh); - cairo_fill(cr); - cairo_stroke(cr); - - long i; - long j; - long k; - - B = f->components[0]; - - for (j = 0; j < f->n_elines; j++) { - el = f->elines[j]; - - cairo_set_line_width(cr, 2); - - if (SCF_EDA_PIN_POS & el->flags) - cairo_set_source_rgb(cr, 1, 0, 0); - - else if (SCF_EDA_PIN_NEG & el->flags) - cairo_set_source_rgb(cr, 0, 0, 1); - - else if (SCF_EDA_PIN_OUT & el->flags) - cairo_set_source_rgb(cr, 1, 0, 1); - - else if (el->v == B->pins[SCF_EDA_Battery_POS]->v) - cairo_set_source_rgb(cr, 0.8, 0, 0); - - else if (el->v == B->pins[SCF_EDA_Battery_NEG]->v) - cairo_set_source_rgb(cr, 0, 0, 0.8); - - else if (SCF_EDA_PIN_IN & el->flags) - cairo_set_source_rgb(cr, 0, 1, 0); - - else if (SCF_EDA_PIN_CF & el->flags) - cairo_set_source_rgb(cr, 0.8, 0, 1.0); - else - cairo_set_source_rgb(cr, 1, 0.5, 0.1); - - uint8_t text[64]; - ScfLine* prev = NULL; - - for (k = 0; k < el->n_lines; k++) { - l = el->lines[k]; - - if (l->x0 > l->x1) - continue; - - if (!prev) { - if (el->vconst) - cairo_select_font_face(cr, "Calibri", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - else - cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - - cairo_set_font_size(cr, 28); - - int n = snprintf(text, sizeof(text) - 1, "%ld", el->id); - - cairo_move_to (cr, l->x0 - 10 - n * 12, l->y0 + 10); - cairo_show_text(cr, text); - cairo_stroke(cr); - - // V of line - if (el->v < SCF_EDA_V_MIN) - n = snprintf(text, sizeof(text) - 1, "0v"); - else if (el->v > SCF_EDA_V_MAX) - n = snprintf(text, sizeof(text) - 1, "%lgv", B->pins[SCF_EDA_Battery_POS]->v); - - else if (el->v > 1e-2 || el->v < -1e-2) - n = snprintf(text, sizeof(text) - 1, "%lgv", (int)(el->v * 1000) / 1000.0); - - else if (el->v > 1e-5 || el->v < -1e-5) - n = snprintf(text, sizeof(text) - 1, "%lgmV", (int)(el->v * 1000000) / 1000.0); - else - n = snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(el->v * 1000000000LL) / 1000.0); - - // A of line - if (el->aout > 1e-1 || el->aout < -1e-1) - n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgA", (int)(el->aout * 1000) / 1000.0); - - else if (el->aout > 1e-5 || el->aout < -1e-5) - n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgmA", (int)(el->aout * 1000000) / 1000.0); - else - n += snprintf(text + n, sizeof(text) - 1 - n, ", %lguA", (int64_t)(el->aout * 1000000000LL) / 1000.0); - - if (el->ain > 1e-1 || el->ain < -1e-1) - n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgA", (int)(el->ain * 1000) / 1000.0); - - else if (el->ain > 1e-5 || el->ain < -1e-5) - n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgmA", (int)(el->ain * 1000000) / 1000.0); - else - n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lguA", (int64_t)(el->ain * 1000000000LL) / 1000.0); - - int cx = INT_MAX; - int cy = l->y0; - - for (i = 0; i < el->n_pins; i += 2) { - c = f->components[el->pins[i]]; - - if (c->x > l->x0 && c->x < cx) { - cx = c->x; - cy = c->y; - } - } - - cairo_set_font_size(cr, 20); - - if (cy > l->y0) { - cairo_move_to (cr, cx - 40, l->y0 - 8); - cairo_show_text(cr, text); - cairo_stroke(cr); - } else { - cairo_move_to (cr, cx - 40, l->y0 + 24); - cairo_show_text(cr, text); - cairo_stroke(cr); - } - } - - cairo_set_line_width(cr, 4); - cairo_move_to(cr, l->x0, l->y0); - cairo_line_to(cr, l->x1, l->y1); - cairo_stroke(cr); - - if (prev) { - if (!(el->flags & SCF_EDA_PIN_BORDER)) - cairo_set_line_width(cr, 1); - - cairo_move_to(cr, prev->x0, prev->y0); - cairo_line_to(cr, l->x0, l->y0); - cairo_stroke(cr); - } - - prev = l; - } - } - - __ses_function_draw(f, cr); - - char file[128]; - snprintf(file, sizeof(file) - 1, "./simplify2_%ld.png", count); - - cairo_surface_write_to_png(surface, file); - - cairo_destroy(cr); - cairo_surface_destroy(surface); - return 0; -} - -static int _simplify_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) -{ - ScfEline* el; - - int i; -#if 0 - for (i = 0; i < f->n_elines; i++) { - el = f->elines[i]; - - if (el->flags & SCF_EDA_PIN_OUT) { - if (el->v < 1) - return 0; - else - break; - } - } -#endif - -// if (count % 5000 == 0) - _simplify_draw(f, f->x, f->y, f->w, f->h, count); - return 0; -} - -ses_step_t ses_step_simplify2 = -{ - .name = "simplify2", - - .handler = _simplify_handler, -}; diff --git a/ses_step_topo.c b/ses_step_topo.c index ffffc88..c2861b7 100644 --- a/ses_step_topo.c +++ b/ses_step_topo.c @@ -108,6 +108,8 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v if (SCF_EDA_PIN_NEG & el->flags) { scf_logd("neg l%ld\n\n", el->id); + if (SCF_EDA_Status_OFF == rc->status) + return 0; return __ses_dfs_add_ppath(__paths, ppath); } @@ -117,6 +119,13 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v return __ses_dfs_add_ppath(__paths, ppath); } + ses_path_t* off = NULL; + + if (SCF_EDA_Status_OFF == rc->status) { + off = *ppath; + *ppath = NULL; + } + ret = 0; for (j = 0; j + 1 < el->n_pins; j += 2) { @@ -182,6 +191,9 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v } } + if (off) + *ppath = off; + if (*ppath) { scf_vector_del((*ppath)->pins, np); @@ -1093,16 +1105,16 @@ static int topo_epin_cmp(const void* v0, const void* v1, void* arg) ScfEcomponent* c0 = f->components[p0[0]]; ScfEcomponent* c1 = f->components[p1[0]]; - if (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_C == p0[1]) + if (SCF_EDA_Diode == c0->type || (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_B == p0[1])) return -1; - if (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_C == p1[1]) + if (SCF_EDA_Diode == c1->type || (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_B == p1[1])) return 1; - if (SCF_EDA_Diode == c0->type || (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_B == p0[1])) + if (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_C == p0[1]) return -1; - if (SCF_EDA_Diode == c1->type || (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_B == p1[1])) + if (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_C == p1[1]) return 1; if (SCF_EDA_Capacitor == c0->type) @@ -1443,35 +1455,64 @@ static int _topo_bridge_connections(ScfEfunction* f, scf_vector_t* paths) return 0; } -static int _topo_path_parallel(ScfEfunction* f, scf_vector_t* paths) +static int _topo_paths_mov_top(scf_vector_t* paths, ses_path_t* parent, ses_path_t* child) { - ses_path_t* child; - ses_path_t* parent; - ScfEpin* p0; - ScfEpin* p1; - ScfEpin* p2; - ScfEpin* p3; + ses_path_t* path; + ScfEpin* p0 = parent->pins->data[0]; ScfEpin* p; - int i; - int j; + int k; - for (i = paths->size - 1; i >= 0; i--) { - child = paths->data[i]; + for (k = paths->size - 1; k >= 0; k--) { + path = paths->data[k]; + p = path->pins->data[0]; - assert(child->pins->size >= 2); + if (p->lid != p0->lid) + continue; - p0 = child->pins->data[0]; - p1 = child->pins->data[child->pins->size - 1]; + path->parent_p0 = 0; + path->parent = parent; + path->conn0 = parent; + path->conn1 = child; - for (j = paths->size - 1; j >= 0; j--) { - parent = paths->data[j]; + int ret = _topo_add_connection(path, path->conn0); + if (ret < 0) + return ret; - if (parent == child) - continue; + ret = _topo_add_connection(path, path->conn1); + if (ret < 0) + return ret; - p2 = parent->pins->data[0]; - p3 = parent->pins->data[parent->pins->size - 1]; + assert(0 == scf_vector_del(paths, path)); + } + + return 0; +} + +static int _topo_path_parallel(ScfEfunction* f, scf_vector_t* paths) +{ + ses_path_t* parent; + ses_path_t* child; + ScfEpin* p0; + ScfEpin* p1; + ScfEpin* p2; + ScfEpin* p3; + + int i; + int j; + int k; + + for (i = 0; i < paths->size - 1; i++) { + parent = paths->data[i]; + + p0 = parent->pins->data[0]; + p1 = parent->pins->data[parent->pins->size - 1]; + + for (j = paths->size - 1; j > i; j--) { + child = paths->data[j]; + + p2 = child->pins->data[0]; + p3 = child->pins->data[child->pins->size - 1]; if (p0->lid == p2->lid && p1->lid == p3->lid) { @@ -1480,6 +1521,18 @@ static int _topo_path_parallel(ScfEfunction* f, scf_vector_t* paths) return ret; assert(0 == scf_vector_del(paths, child)); + + if (child->childs) { + ret = _topo_paths_mov_top(child->childs, parent, child); + if (ret < 0) + return ret; + } + + if (child->bridges) { + ret = _topo_paths_mov_top(child->bridges, parent, child); + if (ret < 0) + return ret; + } } } } @@ -1539,6 +1592,9 @@ static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* if (ret < 0) return ret; +// _topo_print(ctx->paths); +// scf_logi("----\n"); + ret = __ses_topo_layers(f, ctx->paths); if (ret < 0) return ret; diff --git a/ses_step_va_capacitor.c b/ses_step_va_capacitor.c deleted file mode 100644 index e15a7ba..0000000 --- a/ses_step_va_capacitor.c +++ /dev/null @@ -1,476 +0,0 @@ -#include"ses_core.h" - -void __ses_status_check_line(ScfEfunction* f, ScfEline* el, int* changed) -{ - ScfEcomponent* c; - ScfEpin* p0; - ScfEpin* p1; - - int i; - - for (i = 0; i < el->n_pins; i += 2) { - - c = f->components[el->pins[i]]; - p0 = c->pins [el->pins[i + 1]]; - - if (SCF_EDA_Diode == c->type) { - - p0 = c->pins[SCF_EDA_Diode_POS]; - p1 = c->pins[SCF_EDA_Diode_NEG]; - - double v0 = p0->v; - double v1 = p1->v; - - *changed += __ses_status_check(f, c, p0, p1, 0); - - p0->v = v0; - p1->v = v1; - - } else if (SCF_EDA_NPN == c->type - && (SCF_EDA_NPN_B == p0->id || SCF_EDA_NPN_E == p0->id)) { - - p0 = c->pins[SCF_EDA_NPN_B]; - p1 = c->pins[SCF_EDA_NPN_E]; - - double v0 = p0->v; - double v1 = p1->v; - - *changed += __ses_status_check(f, c, p0, p1, 0); - - p0->v = v0; - p1->v = v1; - } - } -} - -int __ses_flow_va(ScfEfunction* f, ses_flow_t* flow, double* rp, double* rn, int* changed, int64_t ns, int64_t count) -{ -#if 1 - ses_path_t* fpath = flow->paths->data[0]; - ScfEline* el = NULL; - ScfEpin* p0 = fpath->pins->data[flow->vip_m]; - ScfEpin* p1 = fpath->pins->data[flow->vip_n]; - - double tmp; - - __ses_path_jr(f, fpath); - - if (rp) { - int ret = __ses_path_va2(f, fpath, flow->vip_m, flow->vip_i, *rp, changed, ns, count); - if (ret < 0) - return ret; - } - - if (rn) { - int ret = __ses_path_va2(f, fpath, flow->vip_i + 1, flow->vip_n, *rn, changed, ns, count); - if (ret < 0) - return ret; - } -#endif - return 0; -} - -void __ses_flow_solve_cross(ses_flow_t* flow0, ses_flow_t* flow1, ses_path_t* bridge) -{ - ses_path_t* path0; - ses_path_t* path1; - ses_path_t* path; - - int i; - int j; - - for (i = 0; i < flow0->paths->size; i++) { - path0 = flow0->paths->data[i]; - - for (j = 0; j < flow1->paths->size; j++) { - path1 = flow1->paths->data[j]; - - if (path0 == path1) { - flow1->paths->size = j + 1; - flow0->paths->size = i + 1; - goto cross; - } - } - } - - return; - -cross: - scf_logi("-----------\n"); - - if (i > 0) { - if (j > 0) { - scf_logi("-----------\n"); - return; - } - - path = flow0->paths->data[i - 1]; - - if (flow1->vip_i > path->parent_p0 && flow1->vip_i < path->parent_p1) { - flow1->vip_m = path->parent_p0; - flow1->vip_n = path->parent_p1; - } - - } else if (j > 0) { - path = flow1->paths->data[j - 1]; - - if (flow0->vip_i > path->parent_p0 && flow0->vip_i < path->parent_p1) { - flow0->vip_m = path->parent_p0; - flow0->vip_n = path->parent_p1; - } - - } else { - path = flow0->paths->data[0]; - - if (flow0->vip_i < flow1->vip_i) { - flow0->vip_m = flow0->vip_i; - flow0->vip_n = flow1->vip_i; - } else { - flow1->vip_m = flow1->vip_i; - flow1->vip_n = flow0->vip_i; - } - } -} - -static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_t* bridge, int* changed, int64_t ns, int64_t count) -{ - ses_flow_t* flow0; - ses_flow_t* flow1; - ses_path_t* fpath; - - ScfEcomponent* B; - ScfEline* el; - ScfEpin* p0; - ScfEpin* p1; - ScfEpin* fp0; - ScfEpin* fp1; - ScfEpin* fp2; - ScfEpin* fp3; - ScfEpin* Bp; - ScfEpin* Bn; - - if (bridge->vflag) - return 0; - - B = f->components[0]; - Bp = B->pins[SCF_EDA_Battery_POS]; - Bn = B->pins[SCF_EDA_Battery_NEG]; - - p0 = bridge->pins->data[0]; - p1 = bridge->pins->data[bridge->pins->size - 1]; - - if (p0->lid == Bp->lid && p1->lid == Bn->lid) - return 0; - - scf_loge("c%ldp%ld-c%ldp%ld-------------------------\n", p0->cid, p0->id, p1->cid, p1->id); - - flow0 = ses_flow_alloc(); - if (!flow0) - return -ENOMEM; - - int ret = ses_paths_find_flow(flow0, paths, p0, bridge); - if (ret < 0) { - ses_flow_free(flow0); - return ret; - } - - flow1 = ses_flow_alloc(); - if (!flow1) { - ses_flow_free(flow0); - return -ENOMEM; - } - - ret = ses_paths_find_flow(flow1, paths, p1, bridge); - if (ret < 0) - goto error; - - if (flow0->paths->size > 0) { - fpath = flow0->paths->data[0]; - - if (!fpath->vflag) { - ret = __ses_path_va_capacitor(f, paths, fpath, changed, ns, count); - if (ret < 0) - goto error; - } - } - - if (flow1->paths->size > 0) { - fpath = flow1->paths->data[0]; - - if (!fpath->vflag) { - ret = __ses_path_va_capacitor(f, paths, fpath, changed, ns, count); - if (ret < 0) - goto error; - } - - if (flow0->paths->size > 0) { - - __ses_flow_solve_cross(flow0, flow1, bridge); - - flow0->paths->size = 1; - } - - flow1->paths->size = 1; - } else if (flow0->paths->size > 0) - flow0->paths->size = 1; - - double R; - double cv; - double Dv = bridge->n_NPNs * SCF_EDA_V_NPN_ON + bridge->n_diodes * SCF_EDA_V_Diode_ON; - double ja; - - __ses_path_jr(f, bridge); - - el = f->elines[p0->lid]; - p0->v = el->v; - - el = f->elines[p1->lid]; - p1->v = el->v; - - ses_flow_print(flow0); - ses_flow_jr(flow0, f); - printf("\n"); - - ses_flow_print(flow1); - ses_flow_jr(flow1, f); - printf("\n"); - - __ses_path_capacitors(f, bridge, 0, bridge->pins->size - 1, &cv); - - scf_logw("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg\n", p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v); - - if (p0->v - p1->v > cv) { - - if (p0->lid == Bp->lid) { - - fpath = flow1->paths->data[flow1->paths->size - 1]; - fp0 = fpath->pins->data[0]; - fp1 = fpath->pins->data[fpath->pins->size - 1]; - - printf("\n"); - scf_logi("-----------\n"); - ret = __ses_meshs_PPN_solve(f, flow1, bridge, changed, ns, count); - if (ret < 0) { - scf_loge("\n"); - return ret; - } - scf_logi("-----------\n\n"); - - bridge->vflag = 1; - - } else if (p1->lid == Bn->lid) { - - fpath = flow0->paths->data[flow0->paths->size - 1]; - fp0 = fpath->pins->data[0]; - fp1 = fpath->pins->data[fpath->pins->size - 1]; - - double U0 = fp0->v - flow0->pos_cv; - double U1 = Bn->v + cv + Dv; - double U2 = fp1->v + flow0->neg_cv; - - ses_va_PNN(U0, U1, U2, flow0->pos_r, bridge->pr, flow0->neg_r, - NULL, &ja, NULL, &p0->v); - - p1->v = Bn->v; - - scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n", - p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja); - - el = f->elines[p0->lid]; - el->v = p0->v; - - el = f->elines[p1->lid]; - el->v = p1->v; - - ret = __ses_path_va(f, bridge, changed, ns, count); - if (ret < 0) { - scf_loge("\n"); - goto error; - } - bridge->vflag = 1; - - ret = __ses_flow_va(f, flow0, &flow0->pos_r, &flow0->neg_r, changed, ns, count); - if (ret < 0) - goto error; - - } else { - fpath = flow0->paths->data[0]; - fp0 = fpath->pins->data[flow0->vip_m]; - fp1 = fpath->pins->data[flow0->vip_n]; - - double U0 = fp0->v - flow0->pos_cv; - double U1 = fp1->v + flow0->neg_cv; - - fpath = flow1->paths->data[0]; - fp2 = fpath->pins->data[flow1->vip_m]; - fp3 = fpath->pins->data[flow1->vip_n]; - - double U2 = fp2->v - flow1->pos_cv; - double U3 = fp3->v + flow1->neg_cv; - - double i0 = 0; - double i1 = 0; - double i2 = 0; - double i3 = 0; - - ses_va_bridge(U0, U1, U2, U3, cv, - flow0->pos_r, flow0->neg_r, flow1->pos_r, flow1->neg_r, bridge->pr, - &i0, &i1, &i2, &i3, &ja, &p0->v, &p1->v); - - scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n", - p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja); - - el = f->elines[p0->lid]; - el->v = p0->v; - - el = f->elines[p1->lid]; - el->v = p1->v; - - ret = __ses_path_va_branch(f, bridge, 0, bridge->pins->size - 1, bridge->pr, changed, ns, count); - if (ret < 0) { - scf_loge("\n"); - goto error; - } - bridge->vflag = 1; - - ret = __ses_flow_va(f, flow1, &flow1->pos_r, &flow1->neg_r, changed, ns, count); - if (ret < 0) - goto error; - - ret = __ses_flow_va(f, flow0, &flow0->pos_r, &flow0->neg_r, changed, ns, count); - if (ret < 0) - goto error; - } - } else { - assert(p0->lid != Bp->lid); - - if (p1->lid == Bn->lid) { - - R = bridge->pr + flow0->neg_r; - ja = (cv - p0->v) / R; - p1->v = Bn->v; - - scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n", - p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja); - - el = f->elines[p0->lid]; - el->v = p0->v; - - el = f->elines[p1->lid]; - el->v = p1->v; - - ret = __ses_path_va(f, bridge, changed, ns, count); - if (ret < 0) { - scf_loge("\n"); - goto error; - } - bridge->vflag = 1; - - } else { - fpath = flow1->paths->data[0]; - fp0 = fpath->pins->data[flow1->vip_m]; - fp1 = fpath->pins->data[flow1->vip_n]; - - double U0 = fp0->v - flow1->pos_cv; - double U1 = fp1->v + flow1->neg_cv; - - fpath = flow0->paths->data[0]; - fp2 = fpath->pins->data[flow0->vip_m]; - fp3 = fpath->pins->data[flow0->vip_n]; - - double U2 = fp2->v - flow0->pos_cv; - double U3 = fp3->v + flow0->neg_cv; - - double i0 = 0; - double i1 = 0; - double i2 = 0; - double i3 = 0; - - ses_va_bridge(U0, U1, U2, U3, -cv, - flow1->pos_r, flow1->neg_r, flow0->pos_r, flow0->neg_r, bridge->pr, - &i0, &i1, &i2, &i3, &ja, &p1->v, &p0->v); - - scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n", - p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja); - - el = f->elines[p0->lid]; - el->v = p0->v; - - el = f->elines[p1->lid]; - el->v = p1->v; - - ret = __ses_path_va(f, bridge, changed, ns, count); - if (ret < 0) { - scf_loge("\n"); - goto error; - } - bridge->vflag = 1; - - ret = __ses_flow_va(f, flow1, &flow1->pos_r, &flow1->neg_r, changed, ns, count); - if (ret < 0) - goto error; - - ret = __ses_flow_va(f, flow0, &flow0->pos_r, &flow0->neg_r, changed, ns, count); - if (ret < 0) - goto error; - } - } - - ret = 0; -error: - ses_flow_free(flow0); - ses_flow_free(flow1); - return ret; -} - -static int ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_t* bridge, int* changed, int64_t ns, int64_t count) -{ - if (!bridge || bridge->pins->size < 2) - return -EINVAL; - - return __ses_path_va_capacitor(f, paths, bridge, changed, ns, count); -} - -static int _va_capacitor_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) -{ - ses_path_t* path; - ScfEcomponent* B = f->components[0]; - ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS]; - ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; - ScfEpin* p0; - ScfEpin* p1; - - int i; - - for (i = 0; i < ctx->paths->size; i++) { - path = ctx->paths->data[i]; - - p0 = path->pins->data[0]; - p1 = path->pins->data[path->pins->size - 1]; - - if (p0->lid == Bp->lid && p1->lid == Bn->lid) - continue; - - scf_logi("i: %d, path->index: %d\n", i, path->index); - - int changed = 0; - - int ret = ses_path_va_capacitor(f, ctx->paths, path, &changed, ns, count); - if (ret < 0) - return ret; - - if (changed > 0) - break; - - printf("\n"); - } - - return 0; -} - -ses_step_t ses_step_va_capacitor = -{ - .name = "va_capacitor", - - .handler = _va_capacitor_handler, -}; -- 2.25.1