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;
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;
}
}
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;
}
/*
*/
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;
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;
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;
}
}
__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) {
}
}
- 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
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;
}
#endif
error:
- gsl_permutation_free(_P);
-P_failed:
free(A);
return ret;
}
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;
return ret;
} while (size > paths->size);
- return 0;
+ return _topo_bridge_piers(f, paths);
}
int __ses_topo_paths(ScfEfunction* f, scf_vector_t* paths)
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];