CFILES += ses_step_output.c
CFILES += ses_step_simplify.c
-CFILES += ses_step_simplify2.c
CFLAGS += -g -D_GNU_SOURCE
CFLAGS += -I./
printf("f: %s\n", f->name);
- ses_steps_analyse(f, 100, 76000);
+ ses_steps_analyse(f, 100, 3);
}
#endif
{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)
+++ /dev/null
-#include"ses_core.h"
-#include <gsl/gsl_linalg.h>
-
-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;
-}
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;
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) {
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;
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;
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");
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]);
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];
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];
}
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;
}
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:
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)
+++ /dev/null
-#include<cairo/cairo.h>
-#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,
-};
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);
}
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) {
}
}
+ if (off)
+ *ppath = off;
+
if (*ppath) {
scf_vector_del((*ppath)->pins, np);
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)
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) {
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;
+ }
}
}
}
if (ret < 0)
return ret;
+// _topo_print(ctx->paths);
+// scf_logi("----\n");
+
ret = __ses_topo_layers(f, ctx->paths);
if (ret < 0)
return ret;
+++ /dev/null
-#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,
-};