From 1db50e3d25549cc1b97172a0507b827f108b5676 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Sat, 18 May 2024 15:05:03 +0800 Subject: [PATCH] node analysis ok --- Makefile | 2 +- examples/test.cpk | Bin 0 -> 440 bytes main.c | 2 +- ses_core.h | 11 +- ses_node_analysis.c | 539 +++++++++++++++------ ses_path.c | 31 ++ ses_step_jr.c | 10 + ses_step_simplify.c | 34 +- ses_step_topo.c | 181 ++++++- ses_step_va_capacitor.c | 56 +-- ses_step_va_meshs.c => ses_step_va_nodes.c | 17 +- ses_steps.c | 4 +- ses_utils.c | 23 +- test/Makefile | 3 +- 14 files changed, 657 insertions(+), 256 deletions(-) create mode 100644 examples/test.cpk rename ses_step_va_meshs.c => ses_step_va_nodes.c (73%) diff --git a/Makefile b/Makefile index 06baec2..9b4794d 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ CFILES += ses_step_status.c CFILES += ses_step_va_line.c CFILES += ses_step_open.c -CFILES += ses_step_va_meshs.c +CFILES += ses_step_va_nodes.c CFILES += ses_step_va_capacitor.c CFILES += ses_step_a_stat.c diff --git a/examples/test.cpk b/examples/test.cpk new file mode 100644 index 0000000000000000000000000000000000000000..ab37f70d032e790270a458d0b9843643bb9d976e GIT binary patch literal 440 zcmZRvDbCD`&o55S%*jbC$uD9MVPIk4U|?WS;1B?k7=VR=K|p|og$GDu18h^TslDLV z6SU*wPd$6q5ut>I186Ex69>p_48Q`C0ZC&6e0&{;9grkABp7%=PUHZq=i@7AN0tRC z1X{+xA%M*|p!FOaJRminCNly_KAsQ<5Dy370l6BeoCB+~SwJ$lUG32CfMl!y$S7ct YV)Z`*3rGgyAtXIeCLd2EvPoc30QhPYwg3PC literal 0 HcmV?d00001 diff --git a/main.c b/main.c index c90f356..869dd09 100644 --- a/main.c +++ b/main.c @@ -107,7 +107,7 @@ int main(int argc, char* argv[]) printf("f: %s\n", f->name); - ses_steps_analyse(f, 100, 2); + ses_steps_analyse(f, 100, 1); } #endif diff --git a/ses_core.h b/ses_core.h index 207da68..bfa81a3 100644 --- a/ses_core.h +++ b/ses_core.h @@ -87,13 +87,16 @@ struct ses_path_s scf_vector_t* infos; scf_vector_t* childs; - scf_vector_t* bridges; + scf_vector_t* connections; ses_path_t* parent; int parent_p0; int parent_p1; + ses_path_t* conn0; + ses_path_t* conn1; + double parent_pr; double sr; @@ -132,6 +135,10 @@ struct ses_edge_s ses_node_t* node0; ses_node_t* node1; + ses_edge_t* npn_b; + int npn_index; + double npn_hfe; + double cv; double r; @@ -152,6 +159,7 @@ struct ses_node_s int index; int vip_i; + ses_path_t* path; }; struct ses_mesh_s @@ -196,6 +204,7 @@ int ses_path_xchg (ses_path_t* path0, int k0, ses_path_t* path1, int k1) int ses_path_save (ScfEfunction* f, ses_path_t* path, scf_vector_t** data); int ses_path_load (ScfEfunction* f, ses_path_t* path, scf_vector_t* data); +ses_path_t* ses_path_same_net(ses_path_t* path0, ses_path_t* path1); int ses_path_is_child(ses_path_t* parent, ses_path_t* child); ses_path_t* ses_path_find_child(ses_path_t* path, int m, int n); ses_path_t* ses_path_find_bridge(ses_path_t* path, int m, int n); diff --git a/ses_node_analysis.c b/ses_node_analysis.c index 0ede069..fd08742 100644 --- a/ses_node_analysis.c +++ b/ses_node_analysis.c @@ -28,7 +28,7 @@ int ses_node_add_edge(ses_node_t* node, ses_path_t* path, int m, int n, ses_edge return 0; } -ses_edge_t* ses_nodes_find_edge(scf_vector_t* nodes, ses_path_t* path, int vip_m, int vip_n) +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; @@ -43,8 +43,7 @@ ses_edge_t* ses_nodes_find_edge(scf_vector_t* nodes, ses_path_t* path, int vip_m edge = node->edges->data[j]; if (edge->path == path - && edge->vip_m == vip_m - && edge->vip_n == vip_n) + && (edge->vip_m == vip_i || edge->vip_n == vip_i)) return edge; } } @@ -52,174 +51,314 @@ ses_edge_t* ses_nodes_find_edge(scf_vector_t* nodes, ses_path_t* path, int vip_m return NULL; } -int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t** nodes) +ses_edge_t* ses_nodes_find_edge_by_pin(scf_vector_t* nodes, ScfEpin* vip) { - scf_vector_t* vec; - ses_path_t* child; - ses_path_t* bridge; + ses_node_t* node; + ses_edge_t* edge; - ses_edge_t* edge = NULL; - ses_node_t* prev = NULL; - ses_node_t* node = NULL; + int i; + int j; + int k; - int ret = -1; + for (i = 0; i < nodes->size; i++) { + node = nodes->data[i]; - vec = scf_vector_alloc(); - if (!vec) - return -ENOMEM; + for (j = 0; j < node->edges->size; j++) { + edge = node->edges->data[j]; - int n_nodes = 0; - int n_edges = 0; + for (k = edge->vip_n; k >= edge->vip_m; k--) { + + 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* n_NPNs) +{ + ses_path_t* child; + ses_path_t* bridge; + ses_path_t* conn; + + ses_edge_t* edge = NULL; + ses_edge_t* npn_c = NULL; + ses_node_t* prev = NULL; + ses_node_t* node = NULL; + + ScfEcomponent* c; + ScfEpin* p; + + int ret = -1; int i; int j = vip_n; int k; - for (i = vip_n - 1; i > vip_m; i -= 2) { + path->vflag = 1; - ScfEpin* p = path->pins->data[i]; + if (path->connections) { + for (k = 0; k < path->connections->size; k++) { + conn = path->connections->data[k]; - if (!path->childs) - continue; + scf_logd("path: %d, conn: %d, vflag: %d\n", path->index, conn->index, conn->vflag); + if (conn->vflag) + continue; - node = ses_node_alloc(); - if (!node) { - ret = -ENOMEM; - goto error; + ret = __ses_nodes_path2(f, conn, 0, conn->pins->size - 1, nodes, n_edges, n_NPNs); + if (ret < 0) + return ret; } + } - ret = ses_node_add_edge(node, path, i, j, &edge); - if (ret < 0) { - ses_node_free(node); - goto error; + if (path->childs) { + for (k = 0; k < path->childs->size; k++) { + child = path->childs->data[k]; + + if (child->vflag) + continue; + + ret = __ses_nodes_path2(f, child, 0, child->pins->size - 1, nodes, n_edges, n_NPNs); + if (ret < 0) + return ret; } - edge->index = n_edges++; - edge->node1 = node; + } - if (prev) { - ret = ses_node_ref_edge(prev, edge); - if (ret < 0) { - ses_node_free(node); - goto error; - } - edge->node0 = prev; + if (path->bridges) { + for (k = 0; k < path->bridges->size; k++) { + bridge = path->bridges->data[k]; + + if (bridge->vflag) + continue; + + ret = __ses_nodes_path2(f, bridge, 0, bridge->pins->size - 1, nodes, n_edges, n_NPNs); + if (ret < 0) + return ret; } + } - for (k = 0; k < path->childs->size; k++) { - child = path->childs->data[k]; + scf_logd("path: %d, vflag: %d, vip_m: %d, vip_n: %d\n", path->index, path->vflag, vip_m, vip_n); - if (child->parent_p0 == i) { -#define CHILD_EDGE_ADD_UNIQUE() \ - edge = ses_nodes_find_edge(vec, child, 0, child->pins->size - 1); \ - if (edge) { \ - ret = ses_node_ref_edge(node, edge); \ - if (ret < 0) { \ - ses_node_free(node); \ - goto error; \ - } \ - } else { \ - ret = ses_node_add_edge(node, child, 0, child->pins->size - 1, &edge); \ - if (ret < 0) { \ - ses_node_free(node); \ - goto error; \ - } \ - edge->index = n_edges++; \ - } \ + int n = 0; + for (i = vip_n - 1; i > vip_m; i -= 2) { + + p = path->pins->data[i]; + c = f->components[p->cid]; - CHILD_EDGE_ADD_UNIQUE(); - edge->node1 = node; + if (SCF_EDA_NPN == c->type) { - } else if (child->parent_p1 == i - 1) { + if (SCF_EDA_NPN_B == p->id) { + npn_c = ses_nodes_find_edge_by_pin(nodes, c->pins[SCF_EDA_NPN_C]); + if (!npn_c) { + scf_loge("\n"); + return -EINVAL; + } + + n++; + npn_c->npn_hfe = c->pins[SCF_EDA_NPN_C]->hfe; + } - CHILD_EDGE_ADD_UNIQUE(); - edge->node0 = node; + if (!node) { + node = ses_node_alloc(); + if (!node) + return -ENOMEM; } } - if (path->bridges) { - for (k = 0; k < path->bridges->size; k++) { - bridge = path->bridges->data[k]; + if (path->childs) { + for (k = 0; k < path->childs->size; k++) { + child = path->childs->data[k]; - if (bridge->parent_p0 == i) { -#define BRIDGE_EDGE_ADD_UNIQUE() \ - edge = ses_nodes_find_edge(vec, bridge, 0, bridge->pins->size - 1); \ + if (child->parent_p0 == i) { +#define EDGE_ADD_UNIQUE(_path, _m) \ + if (!node) { \ + node = ses_node_alloc(); \ + if (!node) \ + return -ENOMEM; \ + } \ + edge = ses_nodes_find_edge(nodes, _path, _m); \ if (edge) { \ ret = ses_node_ref_edge(node, edge); \ if (ret < 0) { \ ses_node_free(node); \ - goto error; \ + return ret; \ } \ } else { \ - ret = ses_node_add_edge(node, bridge, 0, bridge->pins->size - 1, &edge); \ - if (ret < 0) { \ - ses_node_free(node); \ - goto error; \ - } \ - edge->index = n_edges++; \ - if (prev) { \ - ret = ses_node_ref_edge(node, edge); \ - if (ret < 0) { \ - ses_node_free(node); \ - goto error; \ - } \ - } \ + ses_node_free(node); \ + return -EINVAL; \ } - BRIDGE_EDGE_ADD_UNIQUE(); + EDGE_ADD_UNIQUE(child, 0); + edge->node1 = node; + + } else if (child->parent_p1 == i - 1) { + + EDGE_ADD_UNIQUE(child, child->pins->size - 1); + edge->node0 = node; + } + } + } + + if (path->bridges) { + for (k = 0; k < path->bridges->size; k++) { + bridge = path->bridges->data[k]; + + if (bridge->parent_p0 == i) { + + EDGE_ADD_UNIQUE(bridge, 0); edge->node1 = node; } else if (bridge->parent_p1 == i - 1) { - BRIDGE_EDGE_ADD_UNIQUE(); + EDGE_ADD_UNIQUE(bridge, bridge->pins->size - 1); + edge->node0 = node; + } + } + } + + if (path->connections) { + for (k = 0; k < path->connections->size; k++) { + conn = path->connections->data[k]; + + scf_logd("path: %d, conn: %d, i: %d, parent_p0: %d, parent_p1: %d\n", + path->index, conn->index, i, conn->parent_p0, conn->parent_p1); + + if (path == conn->conn0 && conn->parent_p0 == i) { + + EDGE_ADD_UNIQUE(conn, 0); + edge->node1 = node; + + } else if (path == conn->conn1 && conn->parent_p1 == i - 1) { + + EDGE_ADD_UNIQUE(conn, conn->pins->size - 1); edge->node0 = node; } } } - ret = scf_vector_add(vec, node); + if (!node) + continue; + + ret = ses_node_add_edge(node, path, i, j, &edge); if (ret < 0) { ses_node_free(node); - goto error; + return ret; + } + edge->index = (*n_edges)++; + edge->node1 = node; + edge->n_NPNs= n; + n = 0; + + if (prev) { + ret = ses_node_ref_edge(prev, edge); + if (ret < 0) { + ses_node_free(node); + return ret; + } + edge->node0 = prev; + } + + if (npn_c) { + npn_c->npn_b = edge; + npn_c->npn_index = (*n_NPNs)++; + npn_c = NULL; + } + + ret = scf_vector_add(nodes, node); + if (ret < 0) { + ses_node_free(node); + return ret; } - node->index = n_nodes++; node->vip_i = i; + node->path = path; prev = node; + node = NULL; j = i - 1; } if (j > vip_m) { - if (!node) { - node = ses_node_alloc(); - if (!node) { - ret = -ENOMEM; - goto error; - } + if (!prev) { + prev = ses_node_alloc(); + if (!prev) + return -ENOMEM; - ret = scf_vector_add(vec, node); + ret = scf_vector_add(nodes, prev); if (ret < 0) { - ses_node_free(node); - goto error; + ses_node_free(prev); + return ret; } - node->index = n_nodes++; - node->vip_i = j; + prev->vip_i = j; + prev->path = path; } - ret = ses_node_add_edge(node, path, vip_m, j, &edge); + ret = ses_node_add_edge(prev, path, vip_m, j, &edge); if (ret < 0) - goto error; - edge->index = n_edges++; - edge->node0 = node; + return ret; + edge->index = (*n_edges)++; + edge->node0 = prev; + edge->n_NPNs= n; + n = 0; + + if (npn_c) { + npn_c->npn_b = edge; + npn_c->npn_index = (*n_NPNs)++; + npn_c = NULL; + } } - *nodes = vec; return 0; +} -error: - scf_vector_clear(vec, (void (*)(void*) )ses_node_free); - scf_vector_free(vec); - return ret; +int __ses_nodes_path(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t** nodes) +{ + scf_vector_t* vec = scf_vector_alloc(); + if (!vec) + return -ENOMEM; + + int n_edges = 0; + int n_NPNs = 0; + + int ret = __ses_nodes_path2(f, path, vip_m, vip_n, vec, &n_edges, &n_NPNs); + if (ret < 0) { + scf_vector_clear(vec, (void (*)(void*) )ses_node_free); + scf_vector_free(vec); + return ret; + } + + ses_node_t* node; + ses_edge_t* edge; + int i; + int j; + + for (i = 0; i < vec->size; ) { + node = vec->data[i]; + + if (node->edges->size <= 1) { + assert(0 == scf_vector_del(vec, node)); + + for (j = 0; j < node->edges->size; j++) { + edge = node->edges->data[j]; + + if (edge->node0 == node) + edge->node0 = NULL; + if (edge->node1 == node) + edge->node1 = NULL; + } + + ses_node_free(node); + node = NULL; + } else { + node->index = i; + i++; + } + } + + *nodes = vec; + return 0; } /* @@ -243,19 +382,21 @@ error: */ 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) { - ses_node_t* node; - ses_edge_t* edge; + ses_node_t* node; + ses_edge_t* edge; - ScfEline* el; - ScfEpin* pm = path->pins->data[vip_m]; - ScfEpin* pn = path->pins->data[vip_n]; - ScfEpin* p0; - ScfEpin* p1; + ScfEcomponent* c; + ScfEline* el; + ScfEpin* pm = path->pins->data[vip_m]; + ScfEpin* pn = path->pins->data[vip_n]; + ScfEpin* p0; + ScfEpin* p1; int ret = 0; int i; int j; + int t = 0; int m = 0; int n = nodes->size; @@ -268,20 +409,27 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, if (!edge->vflag) { m++; edge->vflag = 1; + + if (edge->npn_b) + t++; } } } int N = n + m; - scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, n_nodes: %d, n_edges: %d, N: %d\n", pm->cid, pm->id, pm->v, pn->cid, pn->id, pn->v, n, m, N); + 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); - double* A = calloc(N * N + N + N, sizeof(double)); + double* A = calloc(N * N + N + N + (N + N + N * N + N * N), sizeof(double)); if (!A) return -ENOMEM; double* b = A + N * N; double* X = b + N; + double* W = X + N; + double* S = W + N; + double* V = S + N; + double* U = V + N * N; double cv; double r; @@ -295,17 +443,11 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, for (j = 0; j < node->edges->size; j++) { edge = node->edges->data[j]; - if (edge->path == path) { - if (edge->vip_m < node->vip_i) - A[i * N + n + edge->index] = 1; - else - A[i * N + n + edge->index] = -1; - } else { - if (edge->path->parent_p0 < node->vip_i) - A[i * N + n + edge->index] = 1; - else - A[i * N + n + edge->index] = -1; - } + if (edge->node1 == node) + A[i * N + n + edge->index] = -1; + + else if (edge->node0 == node) + A[i * N + n + edge->index] = 1; } } @@ -323,20 +465,51 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, __ses_path_capacitors(f, edge->path, edge->vip_m, edge->vip_n, &cv); + 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; + + 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 (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->pr = _pr0; + p0->sr = _sr0; + p1->pr = _pr1; + p1->sr = _sr1; - p0 = edge->path->pins->data[edge->vip_m]; - p1 = edge->path->pins->data[edge->vip_n]; + 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); - b[n + edge->index] = cv; - A[(n + edge->index) * N + n + edge->index] = -r; + if (edge->n_NPNs > 0) { + b[n + edge->index] = cv + edge->n_NPNs * SCF_EDA_V_NPN_ON; +#if 0 + } else if (edge->npn_b) { + A[(n + edge->index) * N + n + edge->index] = 1; + A[(n + edge->index) * N + n + edge->npn_b->index] = -edge->npn_hfe; + b[n + edge->index] = 0; + continue; +#endif + } else { + b[n + edge->index] = cv; + A[(n + edge->index) * N + n + edge->index] = -r; + } if (edge->path == path) { @@ -370,40 +543,77 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, } } - 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; - } + int n_amplifiers; - gsl_linalg_LU_decomp(&_A.matrix, _P, &s); - gsl_linalg_LU_solve (&_A.matrix, _P, &_b.vector, &_X.vector); + do { + n_amplifiers = 0; + memcpy(U, A, sizeof(double) * N * N); +#if 1 + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) + printf("%8lg ", A[i * N + j]); + printf("\n"); + } + printf("\n"); -#if 0 - for (i = 0; i < N; i++) { for (j = 0; j < N; j++) - printf("%5lg ", A[i * N + j]); - printf("\n"); - } - scf_logi("b:\n"); - gsl_vector_fprintf(stdout, &_b.vector, "%lg"); + printf("%lg\n", b[j]); #endif - scf_logi("X:\n"); - gsl_vector_fprintf(stdout, &_X.vector, "%lg"); + 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"); + + 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->npn_b) { + double Ic = X[n + edge->index]; + double Ib = X[n + edge->npn_b->index]; + + double dI = Ib * edge->npn_hfe - Ic; + + if (dI < -1e-9) { + 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; + + A[(n + edge->index) * N + n + edge->index] = -1; + A[(n + edge->index) * N + n + edge->npn_b->index] = edge->npn_hfe; + b[n + edge->index] = 0; + + n_amplifiers++; + } + } + } + } + } while (n_amplifiers > 0); for (i = 0; i < nodes->size; i++) { node = nodes->data[i]; - p0 = path->pins->data[node->vip_i]; + p0 = node->path->pins->data[node->vip_i]; el = f->elines[p0->lid]; el->v = X[i]; + + scf_logi("c%ldp%ld, e%ld->v: %lg, node->index: %d\n", p0->cid, p0->id, el->id, el->v, node->index); } #if 1 @@ -413,18 +623,31 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, 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]; - - scf_logi("c%ldp%ld--c%ldp%ld, edge->vflag: %d\n", p0->cid, p0->id, p1->cid, p1->id, edge->vflag); - if (edge->vflag) continue; edge->vflag = 1; + p0 = edge->path->pins->data[edge->vip_m]; + p1 = edge->path->pins->data[edge->vip_n]; + + c = f->components[p0->cid]; + p0->v = f->elines[p0->lid]->v; p1->v = f->elines[p1->lid]->v; + 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) { + ses_ui_r(&edge->r, 0, p0->v - p1->v, 0, edge->a, 0); + + p0->dr = edge->r - p0->r; + p0->a = edge->a; + p1->a = edge->a; + 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; @@ -432,8 +655,6 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, } #endif error: - gsl_permutation_free(_P); -P_failed: free(A); return ret; } diff --git a/ses_path.c b/ses_path.c index 7061ec5..f2628e6 100644 --- a/ses_path.c +++ b/ses_path.c @@ -49,6 +49,9 @@ void ses_path_free(ses_path_t* path) scf_vector_free (path->bridges); } + if (path->connections) + scf_vector_free(path->connections); + scf_logd("path: %d\n", path->index); free(path); @@ -91,6 +94,19 @@ ses_path_t* ses_path_ref(ses_path_t* src) return dst; } +ses_path_t* ses_path_same_net(ses_path_t* path0, ses_path_t* path1) +{ + while (path0->parent) + path0 = path0->parent; + + while (path1->parent) + path1 = path1->parent; + + if (path0 == path1) + return path0; + return NULL; +} + void ses_path_print(ses_path_t* path) { if (!path) @@ -100,6 +116,7 @@ void ses_path_print(ses_path_t* path) ScfEpin* p; int i; + int j; if (!path->parent) printf("\033[31mpath : %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, \033[0m", @@ -112,6 +129,20 @@ void ses_path_print(ses_path_t* path) } printf("\n"); + if (path->connections) { + for (i = 0; i < path->connections->size; i++) { + path2 = path->connections->data[i]; + + if (path2->parent == path) { + printf("\033[34mconnection: %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, parent: %d, \033[0m", + path2->index, path2->n_diodes, path2->n_NPNs, path2->n_capacitors, path2->infos->size, path->index); + + ses_path_print(path2); + } else + printf("connection: %d\n", path2->index); + } + } + if (path->childs) { for (i = 0; i < path->childs->size; i++) { path2 = path->childs->data[i]; diff --git a/ses_step_jr.c b/ses_step_jr.c index 6619e8d..c27668a 100644 --- a/ses_step_jr.c +++ b/ses_step_jr.c @@ -69,6 +69,16 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path) int i; int j; + if (path->connections) { + for (i = 0; i < path->connections->size; i++) { + child = path->connections->data[i]; + + int ret = __ses_path_jr(f, child); + if (ret < 0) + return ret; + } + } + if (path->bridges) { for (i = 0; i < path->bridges->size; i++) { child = path->bridges->data[i]; diff --git a/ses_step_simplify.c b/ses_step_simplify.c index 0352d1c..fead9bf 100644 --- a/ses_step_simplify.c +++ b/ses_step_simplify.c @@ -1,32 +1,6 @@ #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]; @@ -264,9 +238,11 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr) 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)); + snprintf(text, sizeof(text) - 1, "%lgM", (int)(c->r / 10000) / 100.0); + else if (c->r > 999) + snprintf(text, sizeof(text) - 1, "%lgk", (int)(c->r / 10) / 100.0); else - snprintf(text, sizeof(text) - 1, "%dk", (int)(c->r / 1000.0)); + snprintf(text, sizeof(text) - 1, "%dΩ", (int)c->r); cairo_move_to (cr, c->x + 4, c->y - 5); cairo_show_text(cr, text); @@ -547,7 +523,7 @@ 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", count); - if (count % 100 < 5) +// if (count % 100 < 5) ses_simplify_draw(f, file, f->x, f->y, f->w, f->h); return 0; } diff --git a/ses_step_topo.c b/ses_step_topo.c index c4faecc..8717581 100644 --- a/ses_step_topo.c +++ b/ses_step_topo.c @@ -1134,6 +1134,181 @@ static int _topo_paths(ScfEfunction* f, ScfEline* el, scf_vector_t* paths) return 0; } +static int _topo_bridge_piers(ScfEfunction* f, scf_vector_t* paths) +{ + ses_path_t* pier; + ses_path_t* bridge; + + 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; + ScfEpin* p2; + ScfEpin* p3; + + int i; + int j; + int k; + + for (i = paths->size - 1; i >= 0; i--) { + pier = paths->data[i]; + + 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; + + for (j = paths->size - 1; j >= 0; j--) { + bridge = paths->data[j]; + + if (pier == bridge) + continue; + + p2 = bridge->pins->data[0]; + p3 = bridge->pins->data[bridge->pins->size - 1]; + + if (p2->lid == Bp->lid || p3->lid == Bn->lid) + continue; + + for (k = 0; k < bridge->pins->size; k++) { + p2 = bridge->pins->data[k]; + + if (p2->lid == p0->lid) { + pier->parent_p0 = (k + 1) & ~0x1; + goto found; + + } else if (p2->lid == p1->lid) { + pier->parent_p1 = k; + goto found; + } + } + } + + continue; +found: + if (!bridge->bridges) { + bridge->bridges = scf_vector_alloc(); + if (!bridge->bridges) + return -ENOMEM; + } + + int ret = scf_vector_add(bridge->bridges, pier); + if (ret < 0) + return ret; + + assert(0 == scf_vector_del(paths, pier)); + + pier->parent = bridge; + } + + 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) { + conn->connections = scf_vector_alloc(); + if (!conn->connections) + return -ENOMEM; + } + + return scf_vector_add_unique(conn->connections, path); +} + +static int _topo_bridge_connections(ScfEfunction* f, scf_vector_t* paths) +{ + 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 = paths->size - 1; i >= 0; i--) { + path = 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; + + int k0 = __topo_bridge_connection(paths, path, p0, &path->conn0); + if (k0 < 0) + return -EINVAL; + + int k1 = __topo_bridge_connection(paths, path, p1, &path->conn1); + if (k1 < 0) + return -EINVAL; + + path->parent = ses_path_same_net(path->conn0, path->conn1); + if (path->parent) { + path->parent_p0 = (k0 + 1) & ~0x1; + path->parent_p1 = k1; + + 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; + + assert(0 == scf_vector_del(paths, path)); + } + } + + return 0; +} + static int __ses_topo_layers(ScfEfunction* f, scf_vector_t* paths) { ses_path_t* path; @@ -1165,7 +1340,7 @@ static int __ses_topo_layers(ScfEfunction* f, scf_vector_t* paths) return ret; } while (size > paths->size); - return 0; + return _topo_bridge_piers(f, paths); } int __ses_topo_paths(ScfEfunction* f, scf_vector_t* paths) @@ -1224,6 +1399,10 @@ static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* if (ret < 0) return ret; + ret = _topo_bridge_connections(f, ctx->paths); + if (ret < 0) + return ret; + int i; for (i = 0; i < ctx->paths->size; i++) { path = ctx->paths->data[i]; diff --git a/ses_step_va_capacitor.c b/ses_step_va_capacitor.c index 3e00424..e15a7ba 100644 --- a/ses_step_va_capacitor.c +++ b/ses_step_va_capacitor.c @@ -56,27 +56,15 @@ int __ses_flow_va(ScfEfunction* f, ses_flow_t* flow, double* rp, double* rn, int __ses_path_jr(f, fpath); if (rp) { - el = f->elines[p0->lid]; - tmp = el->v; - int ret = __ses_path_va2(f, fpath, flow->vip_m, flow->vip_i, *rp, changed, ns, count); if (ret < 0) return ret; - - if (el->vconst) - el->v = tmp; } if (rn) { - el = f->elines[p1->lid]; - tmp = el->v; - int ret = __ses_path_va2(f, fpath, flow->vip_i + 1, flow->vip_n, *rn, changed, ns, count); if (ret < 0) return ret; - - if (el->vconst) - el->v = tmp; } #endif return 0; @@ -230,18 +218,14 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat double cv; double Dv = bridge->n_NPNs * SCF_EDA_V_NPN_ON + bridge->n_diodes * SCF_EDA_V_Diode_ON; double ja; - double tmp0; - double tmp1; __ses_path_jr(f, bridge); el = f->elines[p0->lid]; p0->v = el->v; - tmp0 = el->v; el = f->elines[p1->lid]; p1->v = el->v; - tmp1 = el->v; ses_flow_print(flow0); ses_flow_jr(flow0, f); @@ -272,6 +256,8 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat } scf_logi("-----------\n\n"); + bridge->vflag = 1; + } else if (p1->lid == Bn->lid) { fpath = flow0->paths->data[flow0->paths->size - 1]; @@ -301,14 +287,7 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat scf_loge("\n"); goto error; } - - el = f->elines[p0->lid]; - if (el->vconst) - el->v = tmp0; - - el = f->elines[p1->lid]; - if (el->vconst) - el->v = tmp1; + bridge->vflag = 1; ret = __ses_flow_va(f, flow0, &flow0->pos_r, &flow0->neg_r, changed, ns, count); if (ret < 0) @@ -347,19 +326,12 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat el = f->elines[p1->lid]; el->v = p1->v; - ret = __ses_path_va(f, bridge, changed, ns, count); + 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; } - - el = f->elines[p0->lid]; - if (el->vconst) - el->v = tmp0; - - el = f->elines[p1->lid]; - if (el->vconst) - el->v = tmp1; + bridge->vflag = 1; ret = __ses_flow_va(f, flow1, &flow1->pos_r, &flow1->neg_r, changed, ns, count); if (ret < 0) @@ -392,14 +364,7 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat scf_loge("\n"); goto error; } - - el = f->elines[p0->lid]; - if (el->vconst) - el->v = tmp0; - - el = f->elines[p1->lid]; - if (el->vconst) - el->v = tmp1; + bridge->vflag = 1; } else { fpath = flow1->paths->data[0]; @@ -439,14 +404,7 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat scf_loge("\n"); goto error; } - - el = f->elines[p0->lid]; - if (el->vconst) - el->v = tmp0; - - el = f->elines[p1->lid]; - if (el->vconst) - el->v = tmp1; + bridge->vflag = 1; ret = __ses_flow_va(f, flow1, &flow1->pos_r, &flow1->neg_r, changed, ns, count); if (ret < 0) diff --git a/ses_step_va_meshs.c b/ses_step_va_nodes.c similarity index 73% rename from ses_step_va_meshs.c rename to ses_step_va_nodes.c index 658a4a0..e450f7b 100644 --- a/ses_step_va_meshs.c +++ b/ses_step_va_nodes.c @@ -1,6 +1,6 @@ #include"ses_core.h" -int __ses_path_va_meshs(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths, int64_t ns, int64_t count) +int __ses_path_va_nodes(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths, int64_t ns, int64_t count) { if (!path) return -EINVAL; @@ -24,7 +24,6 @@ int __ses_path_va_meshs(ScfEfunction* f, ses_path_t* path, int* changed, scf_vec p1->pr = path->pr; scf_logi("---------------\n"); -// int ret = __ses_meshs_path_solve(f, path, 0, path->pins->size - 1, changed, ns, count); int ret = __ses_nodes_path_solve(f, path, 0, path->pins->size - 1, changed, ns, count); if (ret < 0) { @@ -40,12 +39,12 @@ int __ses_path_va_meshs(ScfEfunction* f, ses_path_t* path, int* changed, scf_vec return 0; } -static int ses_path_va_meshs(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths, int64_t ns, int64_t count) +static int ses_path_va_nodes(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths, int64_t ns, int64_t count) { - return __ses_path_va_meshs(f, path, changed, paths, ns, count); + return __ses_path_va_nodes(f, path, changed, paths, ns, count); } -static int _va_meshs_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) +static int _va_nodes_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) { ses_path_t* path; ScfEcomponent* B = f->components[0]; @@ -68,7 +67,7 @@ static int _va_meshs_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx scf_logi("i: %d, path->index: %d\n", i, path->index); - int ret = ses_path_va_meshs(f, path, &changed, ctx->paths, ns, count); + int ret = ses_path_va_nodes(f, path, &changed, ctx->paths, ns, count); if (ret < 0) return ret; } @@ -77,9 +76,9 @@ static int _va_meshs_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx return 0; } -ses_step_t ses_step_va_meshs = +ses_step_t ses_step_va_nodes = { - .name = "va_meshs", + .name = "va_nodes", - .handler = _va_meshs_handler, + .handler = _va_nodes_handler, }; diff --git a/ses_steps.c b/ses_steps.c index d9afffb..161450f 100644 --- a/ses_steps.c +++ b/ses_steps.c @@ -20,7 +20,7 @@ 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_meshs; +extern ses_step_t ses_step_va_nodes; extern ses_step_t ses_step_va_capacitor; extern ses_step_t ses_step_a_stat; @@ -59,7 +59,7 @@ static ses_step_t* ses_steps_2[] = { &ses_step_open, // &ses_step_simplify2, - &ses_step_va_meshs, + &ses_step_va_nodes, &ses_step_va_capacitor, // &ses_step_a_stat, diff --git a/ses_utils.c b/ses_utils.c index 0c898ae..a9231e9 100644 --- a/ses_utils.c +++ b/ses_utils.c @@ -71,7 +71,7 @@ void ses_edge_print(ses_edge_t* edge) if (j < edge->vip_n) printf("c%ldp%ld, ", p->cid, p->id); else - printf("c%ldp%ld; ", p->cid, p->id); + printf("c%ldp%ld ", p->cid, p->id); } } else { @@ -81,9 +81,26 @@ void ses_edge_print(ses_edge_t* edge) if (j > edge->vip_n) printf("c%ldp%ld, ", p->cid, p->id); else - printf("c%ldp%ld; ", p->cid, p->id); + printf("c%ldp%ld ", p->cid, p->id); } } + + printf("("); + if (edge->node1) + printf("%d", edge->node1->index); + else + printf(" "); + printf("-->"); + + if (edge->node0) + printf("%d", edge->node0->index); + else + printf(" "); + printf(")"); + + if (edge->npn_b) + printf(" b[%d]", edge->npn_b->index); + printf("; "); } ses_mesh_t* ses_mesh_alloc() @@ -197,7 +214,7 @@ void ses_node_print(ses_node_t* node) ses_edge_print(edge); } - printf("\n"); + printf("\n\n"); } void ses_nodes_print(scf_vector_t* nodes) diff --git a/test/Makefile b/test/Makefile index 47e90db..637b052 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,4 +1,5 @@ -CFILES += main.c +#CFILES += main.c +CFILES += test.c CFILES += ../scf_eda_pack.c CFILES += ../pack/scf_pack.c -- 2.25.1