From 0e98220c7fa976502ea402db97cb30ddac78aa56 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Sun, 12 May 2024 19:57:17 +0800 Subject: [PATCH] add step 'mesh analysis' for va --- Makefile | 1 + ses_core.h | 9 +-- ses_mesh_analysis.c | 39 ++++++----- ses_step_va.c | 148 ++++++++++++++++++++++++++++++++++------ ses_step_va_capacitor.c | 34 ++++----- ses_step_va_meshs.c | 83 ++++++++++++++++++++++ ses_steps.c | 2 + 7 files changed, 253 insertions(+), 63 deletions(-) create mode 100644 ses_step_va_meshs.c diff --git a/Makefile b/Makefile index 12181bc..828f764 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,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_capacitor.c CFILES += ses_step_a_stat.c diff --git a/ses_core.h b/ses_core.h index 3b92650..e38ebf3 100644 --- a/ses_core.h +++ b/ses_core.h @@ -218,9 +218,10 @@ int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, se int ses_flow_find_pos (ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f); int ses_flow_find_neg (ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f); -int __ses_path_va_diode (ScfEfunction* f, ses_path_t* path); 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); 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); @@ -230,9 +231,9 @@ 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_path2 (ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int vip_i, scf_vector_t** meshs); +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); diff --git a/ses_mesh_analysis.c b/ses_mesh_analysis.c index ae44d9e..0a9f62e 100644 --- a/ses_mesh_analysis.c +++ b/ses_mesh_analysis.c @@ -28,7 +28,7 @@ int ses_mesh_add_edge(ses_mesh_t* mesh, ses_path_t* path, int m, int n, ses_edge return 0; } -int __ses_meshs_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int vip_i, scf_vector_t** meshs) +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; @@ -185,7 +185,7 @@ n + 1: I[1] 2n : Iright */ -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) +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; @@ -211,7 +211,7 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi double* b = A + N * N; double* X = b + N; double cv; - double pr; + double r; __ses_path_jr(f, path); @@ -223,19 +223,22 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi __ses_path_capacitors(f, edge->path, edge->vip_m, edge->vip_n, &cv); b[i] = cv + pn->v; - __ses_path_pr(f, edge->path, edge->vip_m, edge->vip_n, NULL, &pr); + 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 = pr; + 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, pr: %lg, cv: %lg\n", p0->cid, p0->id, p1->cid, p1->id, pr, cv); + 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] = -pr; + A[i * N + n + i] = -r; if (i < n - 1) - A[i * N + n + i + 1] = pr; + A[i * N + n + i + 1] = r; } mesh = meshs->data[meshs->size - 1]; @@ -246,9 +249,9 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi if (edge->vip_m > edge->vip_n) { if (0 == edge->vip_n && edge->vip_m == edge->path->pins->size - 1) - pr = edge->path->pr; + r = edge->path->pr; else - __ses_path_pr(f, edge->path, edge->vip_n, edge->vip_m, NULL, &pr); + __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; @@ -257,9 +260,9 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi b[n + i] = cv; if (0 == edge->vip_m && edge->vip_n == edge->path->pins->size - 1) - pr = edge->path->pr; + r = edge->path->pr; else - __ses_path_pr(f, edge->path, edge->vip_m, edge->vip_n, NULL, &pr); + __ses_path_sr(f, edge->path, edge->vip_m, edge->vip_n, &r); } if (i > 0) @@ -269,18 +272,18 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi if (i < n) { A[(n + i) * N + i] = -1; - A[(n + i) * N + n + i] = -pr; + A[(n + i) * N + n + i] = -r; } else b[n + i] += pm->v; - A[(n + i) * N + 2 * n] = -pr; + 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 = pr; + edge->r = r; - scf_logi("c%ldp%ld-c%ldp%ld, pr: %lg, cv: %lg, vip_m: %d, vip_n: %d\n", p0->cid, p0->id, p1->cid, p1->id, pr, cv, edge->vip_m, edge->vip_n); + 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); @@ -311,7 +314,7 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi el = f->elines[p0->lid]; el->v = X[i]; - ret = __ses_path_va2(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ns, count); + ret = __ses_path_va_branch(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ns, count); if (ret < 0) goto error; } @@ -324,7 +327,7 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi p0 = edge->path->pins->data[edge->vip_m]; p1 = edge->path->pins->data[edge->vip_n]; - ret = __ses_path_va2(f, edge->path, edge->vip_n, edge->vip_m, edge->r, changed, ns, count); + ret = __ses_path_va_branch(f, edge->path, edge->vip_n, edge->vip_m, edge->r, changed, ns, count); if (ret < 0) goto error; } diff --git a/ses_step_va.c b/ses_step_va.c index 8f5cbc2..cb1e84d 100644 --- a/ses_step_va.c +++ b/ses_step_va.c @@ -159,6 +159,128 @@ int __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, doubl 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 (!path) + return -EINVAL; + + if (path->pins->size < 2) { + scf_loge("\n"); + return -EINVAL; + } + + if (n - m < 1) + return 0; + +// if (path->vflag) +// return 0; + + ScfEcomponent* c; + ScfEline* el; + ScfEpin* p; + ScfEpin* p2; + ScfEpin* p0 = path->pins->data[m]; + ScfEpin* p1 = path->pins->data[n]; + + double cv = 0; + double a = 0; + double v = p0->v - p1->v; + + __ses_path_capacitors(f, path, m, n, &cv); + v -= cv; + + 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); + + double r = 0; + double dv = 0; + double dv0 = 0; + double dvc = 0; + + int i0 = m; + int i; + + for (i = m; i <= n; i++) { + p = path->pins->data[i]; + + c = f->components[p->cid]; + el = f->elines[p->lid]; + + scf_logd("c%ldp%ld, p->r: %lg, dr: %lg, sr: %lg, pr: %lg\n", p->cid, p->id, p->r, p->dr, p->sr, p->pr); + + __ses_path_split_v(f, path, i0, i, a); + + p->a = a; + p->v -= dv0 + dvc; + el->v = p->v; + + r += p->r + p->dr; + + if (i & 0x1) { + p2 = path->pins->data[i - 1]; + dv -= p->v; + r += c->r + c->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; + + 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", + c->id, c->v, p->v, p2->v, dv, p->a, c->a, ns, c->uf); + } + 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", + path->index, i, p->cid, p->id, p->v, dv, r, p->a, a, p->pr, el->id, el->v); + + if (SCF_EDA_Diode == c->type) { + + if (SCF_EDA_Diode_NEG == p->id) { + p2 = path->pins->data[i - 1]; + + *changed += __ses_status_check(f, c, p2, p, 1); + } + + } else if (SCF_EDA_NPN == c->type) { + + if (SCF_EDA_NPN_E == p->id) { + p2 = path->pins->data[i - 1]; + + if (SCF_EDA_NPN_B == p2->id) { + *changed += __ses_status_check(f, c, p2, p, 1); + + c->pins[SCF_EDA_NPN_C]->aconst = 1; + } + } + } + + 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); + } + } + printf("\n"); + + path->vflag = 1; + return 0; +} + int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count) { if (!path) @@ -174,22 +296,14 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i ses_path_t* child; ScfEcomponent* c; - ScfEcomponent* B = f->components[0]; - ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG]; ScfEline* el; ScfEpin* p; - ScfEpin* p0; - ScfEpin* p1; ScfEpin* p2; + ScfEpin* p0 = path->pins->data[m]; + ScfEpin* p1 = path->pins->data[n]; ScfEpin* cp0; ScfEpin* cp1; - int i; - int j; - - p0 = path->pins->data[m]; - p1 = path->pins->data[n]; - double cv = 0; double a = 0; double v = p0->v - p1->v; @@ -208,10 +322,11 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i double r = 0; double dv = 0; double dv0 = 0; - double dv1 = 0; double dvc = 0; int i0 = m; + int i; + int j; for (i = m; i <= n; i++) { p = path->pins->data[i]; @@ -223,7 +338,6 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i __ses_path_split_v(f, path, i0, i, a); p->v -= dv0 + dvc; - dv1 = 0; double tmp = p->v; @@ -262,9 +376,7 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i dv -= cv; ses_ur_i(&p->a, NULL, dv, 0, r, 0); -// c->v += p->a * sign * ns / 1e3 / c->uf; - c->a = p->a * sign; - + c->a = p->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", @@ -342,7 +454,6 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i } printf("\n"); - path->vflag = 1; return 0; } @@ -395,20 +506,17 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed, int64_t ns, i p1->sr = path->sr; 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_path_va2(f, path, 0, path->pins->size - 1, path->pr, changed, ns, count); if (ret < 0) { scf_loge("\n"); return ret; } -// scf_logi("---------------\n\n"); p0->sr = _sr0; p0->pr = _pr0; p1->sr = _sr1; p1->pr = _pr1; - return ret; + return 0; } static int _va_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx) diff --git a/ses_step_va_capacitor.c b/ses_step_va_capacitor.c index 9740da1..3e00424 100644 --- a/ses_step_va_capacitor.c +++ b/ses_step_va_capacitor.c @@ -467,40 +467,32 @@ error: 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_path_t* child; - - int ret; - int j; - if (!bridge || bridge->pins->size < 2) return -EINVAL; - ret = __ses_path_va_capacitor(f, paths, bridge, changed, ns, count); - if (ret < 0) - return ret; - - if (bridge->bridges) { - for (j = 0; j < bridge->bridges->size; j++) { - child = bridge->bridges->data[j]; - - ret = ses_path_va_capacitor(f, paths, child, changed, ns, count); - if (ret < 0) - return ret; - } - } - - return 0; + 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; + 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; diff --git a/ses_step_va_meshs.c b/ses_step_va_meshs.c new file mode 100644 index 0000000..40afa37 --- /dev/null +++ b/ses_step_va_meshs.c @@ -0,0 +1,83 @@ +#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) +{ + if (!path) + return -EINVAL; + + if (path->pins->size < 2) { + scf_loge("\n"); + return -EINVAL; + } + + ScfEpin* p0 = path->pins->data[0]; + ScfEpin* p1 = path->pins->data[path->pins->size - 1]; + + double _sr0 = p0->sr; + double _pr0 = p0->pr; + double _sr1 = p1->sr; + double _pr1 = p1->pr; + + p0->sr = 0; + p0->pr = 0; + p1->sr = path->sr; + p1->pr = path->pr; + + scf_logi("---------------\n"); + int ret = __ses_meshs_path_solve(f, path, 0, path->pins->size - 1, changed, ns, count); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + scf_logi("---------------\n\n"); + + p0->sr = _sr0; + p0->pr = _pr0; + p1->sr = _sr1; + p1->pr = _pr1; + 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) +{ + return __ses_path_va_meshs(f, path, changed, paths, ns, count); +} + +static int _va_meshs_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 changed = 0; + 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 ret = ses_path_va_meshs(f, path, &changed, ctx->paths, ns, count); + if (ret < 0) + return ret; + } + + ctx->changed += changed; + return 0; +} + +ses_step_t ses_step_va_meshs = +{ + .name = "va_meshs", + + .handler = _va_meshs_handler, +}; diff --git a/ses_steps.c b/ses_steps.c index 6d9f5e0..d9afffb 100644 --- a/ses_steps.c +++ b/ses_steps.c @@ -20,6 +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_capacitor; extern ses_step_t ses_step_a_stat; @@ -58,6 +59,7 @@ static ses_step_t* ses_steps_2[] = { &ses_step_open, // &ses_step_simplify2, + &ses_step_va_meshs, &ses_step_va_capacitor, // &ses_step_a_stat, -- 2.25.1