__ses_get_crosses()
authoryu.dongliang <18588496441@163.com>
Tue, 31 Oct 2023 17:20:42 +0000 (01:20 +0800)
committeryu.dongliang <18588496441@163.com>
Tue, 31 Oct 2023 17:20:42 +0000 (01:20 +0800)
ses_core.h
ses_layout.c
ses_utils.c

index 3ba07f2566b51590bc5c4cab8bae8c0b50df33a7..0ebcb98aed7f594cc6f27516a35d49de3508812e 100644 (file)
@@ -13,7 +13,7 @@ typedef struct ses_ctx_s     ses_ctx_t;
 
 struct ses_edge_s
 {
-       scf_vector_t*  conflicts;
+       scf_vector_t*  crosses;
 
        ScfEpin*       p0;
        ScfEpin*       p1;
@@ -117,7 +117,7 @@ void        ses_flow_v_pos(ses_flow_t* flow, double a, double ja);
 void        ses_flow_v_neg(ses_flow_t* flow, double a, double ja);
 void        ses_flow_jr   (ses_flow_t* flow);
 
-ses_edge_t* ses_edge_alloc();
+ses_edge_t* ses_edge_alloc(ScfEpin*    p0, ScfEpin* p1);
 void        ses_edge_free (ses_edge_t* edge);
 
 ses_ctx_t*  ses_ctx_alloc();
index b41f696082fa0364df07978450b9464bf524b04f..1dd9df3be0a443d35d414d909c45e309071f6447 100644 (file)
@@ -716,6 +716,152 @@ static inline void __ses_flip_pos(ScfEcomponent* c)
        }
 }
 
+static inline int edge_cmp(const void* v0, const void* v1)
+{
+       const ses_edge_t* edge0 = v0;
+       const ses_edge_t* edge1 = v1;
+
+       if (edge0->p0 == edge1->p0 && edge0->p1 == edge1->p1)
+               return 0;
+       return -1;
+}
+
+static inline ses_edge_t* __ses_edge_add(scf_vector_t* edges, ScfEpin* p0, ScfEpin* p1)
+{
+       ses_edge_t  tmp  = {NULL, p0, p1};
+       ses_edge_t* edge = scf_vector_find_cmp(edges, &tmp, edge_cmp);
+
+       if (!edge) {
+               edge = ses_edge_alloc(p0, p1);
+               if (!edge)
+                       return NULL;
+
+               if (scf_vector_add(edges, edge) < 0) {
+                       ses_edge_free(edge);
+                       return NULL;
+               }
+       }
+
+       return edge;
+}
+
+static inline int edge_cmp_crosses(const void* v0, const void* v1)
+{
+       const ses_edge_t* edge0 = *(const ses_edge_t**)v0;
+       const ses_edge_t* edge1 = *(const ses_edge_t**)v1;
+
+       if (edge0->crosses->size > edge1->crosses->size)
+               return -1;
+       if (edge0->crosses->size < edge1->crosses->size)
+               return 1;
+       return 0;
+}
+
+static int __ses_get_crosses(ScfEfunction* f, int d, scf_vector_t* edges)
+{
+       ses_edge_t*    edge0;
+       ses_edge_t*    edge1;
+
+       ScfEcomponent* c0;
+       ScfEcomponent* c1;
+       ScfEpin*       p0;
+       ScfEpin*       p1;
+       ScfEpin*       p2;
+       ScfEpin*       p3;
+
+       size_t i;
+       size_t j;
+       size_t k;
+       size_t m;
+       size_t n;
+       size_t q;
+
+       for (i = 0; i < f->n_components - 1; i++) {
+               c0 =        f->components[i];
+
+               for (j = 0; j < c0->n_pins - 1; j++) {
+                       p0 =        c0->pins[j];
+
+                       for (k = j + 1; k < c0->n_pins; k++) {
+                               p1 =            c0->pins[k];
+
+                               if (p0->y - p1->y <= d && p0->y - p1->y >= -d)
+                                       continue;
+
+                               int y0 = p0->y < p1->y ? p0->y : p1->y;
+                               int y1 = p0->y < p1->y ? p1->y : p0->y;
+
+                               for (m = i + 1; m < f->n_components; m++) {
+                                       c1 =            f->components[m];
+
+                                       for (n = 0; n < c1->n_pins - 1; n++) {
+                                               p2 =        c1->pins[n];
+
+                                               if ((p0->x > 0 && p2->x < 0) || (p0->x < 0 && p2->x > 0))
+                                                       break;
+
+                                               for (q = n + 1; q < c1->n_pins; q++) {
+                                                       p3 =            c1->pins[q];
+
+                                                       if (p2->y - p3->y <= d && p2->y - p3->y >= -d)
+                                                               continue;
+
+                                                       int y2 = p2->y < p3->y ? p2->y : p3->y;
+                                                       int y3 = p2->y < p3->y ? p3->y : p2->y;
+
+                                                       if ((y0 < y2 && y2 < y1 && y1 < y3) || (y2 < y0 && y0 < y3 && y3 < y1)) {
+
+                                                               edge0 = __ses_edge_add(edges, p0, p1);
+                                                               if (!edge0)
+                                                                       return -ENOMEM;
+
+                                                               edge1 = __ses_edge_add(edges, p2, p3);
+                                                               if (!edge1)
+                                                                       return -ENOMEM;
+
+                                                               if (!scf_vector_find_cmp(edge0->crosses, edge1, edge_cmp)) {
+                                                                       if (scf_vector_add(edge0->crosses, edge1) < 0)
+                                                                               return -ENOMEM;
+                                                               }
+
+                                                               if (!scf_vector_find_cmp(edge1->crosses, edge0, edge_cmp)) {
+                                                                       if (scf_vector_add(edge1->crosses, edge0) < 0)
+                                                                               return -ENOMEM;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       scf_vector_qsort(edges, edge_cmp_crosses);
+
+#if 1
+       size_t n_crosses = 0;
+
+       for (i = 0; i < edges->size; i++) {
+               edge0     = edges->data[i];
+
+               scf_logw("i: %ld, c%ldp%ld--c%ldp%ld\n", i, edge0->p0->cid, edge0->p0->id, edge0->p1->cid, edge0->p1->id);
+
+               for (j = 0; j < edge0->crosses->size; j++) {
+                       edge1     = edge0->crosses->data[j];
+
+                       scf_logi("j: %ld, c%ldp%ld--c%ldp%ld\n", j, edge1->p0->cid, edge1->p0->id, edge1->p1->cid, edge1->p1->id);
+               }
+               printf("\n");
+
+               n_crosses += edge0->crosses->size;
+       }
+
+       scf_loge("n_crosses: %ld\n\n", n_crosses);
+#endif
+
+       return 0;
+}
+
 static void __ses_de_cross(ScfEfunction* f, int d)
 {
        ScfEcomponent* c0;
@@ -1127,8 +1273,24 @@ int ses_layout_function(ScfEfunction* f, int d)
 
        qsort(f->elines, f->n_elines, sizeof(ScfEline*), eline_cmp_id);
 
+       scf_vector_t* crosses0 = scf_vector_alloc();
+       scf_vector_t* crosses1 = scf_vector_alloc();
+
+       scf_loge("\n");
+       __ses_get_crosses(f, d, crosses0);
+
        __ses_de_cross(f, d);
 
+       scf_loge("\n");
+       __ses_get_crosses(f, d, crosses1);
+
+       scf_vector_clear(crosses0, ( void (*)(void*) )ses_edge_free);
+       scf_vector_clear(crosses1, ( void (*)(void*) )ses_edge_free);
+       scf_vector_free(crosses0);
+       scf_vector_free(crosses1);
+       crosses0 = NULL;
+       crosses1 = NULL;
+
        __ses_setc_xy(f, d);
        __ses_xchg_cx(f, d);
        __ses_xchg_ce(f, d);
index de61d5f6356d05733c1fd93421dd5a995ad4729c..e97c3fff86bf2007d7c63b50e3ec052ab0265305 100644 (file)
@@ -1,25 +1,27 @@
 #include"ses_core.h"
 
-ses_edge_t* ses_edge_alloc()
+ses_edge_t* ses_edge_alloc(ScfEpin* p0, ScfEpin* p1)
 {
        ses_edge_t* edge = calloc(1, sizeof(ses_edge_t));
        if (!edge)
                return NULL;
 
-       edge->conflicts = scf_vector_alloc();
-       if (!edge->conflicts) {
+       edge->crosses = scf_vector_alloc();
+       if (!edge->crosses) {
                free(edge);
                return NULL;
        }
 
+       edge->p0 = p0;
+       edge->p1 = p1;
        return edge;
 }
 
 void ses_edge_free(ses_edge_t* edge)
 {
        if (edge) {
-               if (edge->conflicts)
-                       scf_vector_free(edge->conflicts);
+               if (edge->crosses)
+                       scf_vector_free(edge->crosses);
 
                free(edge);
        }