Index: trunk/src/plugins/rt_topo/crbs.c =================================================================== --- trunk/src/plugins/rt_topo/crbs.c (revision 1321) +++ trunk/src/plugins/rt_topo/crbs.c (revision 1322) @@ -41,9 +41,9 @@ static void crbs_coll_report_cb(grbs_t *grbs, grbs_2net_t *tn, grbs_2net_t *coll_tn, grbs_arc_t *coll_arc) { crbs_t *crbs = grbs->user_data; - crbs_2net_t *ctn = tn->user_data, *coll_ctn = coll_tn->user_data; + crbs_2net_t *coll_ctn = coll_tn->user_data; +/* crbs_2net_t *ctn = tn->user_data;*/ - printf("\n(COLLISION %s %s)\n", ctn->tn->net->hdr.oid, coll_ctn->tn->net->hdr.oid); htpi_set(&crbs->coll_nets, coll_ctn, 1); } Index: trunk/src/plugins/rt_topo/crbs.h =================================================================== --- trunk/src/plugins/rt_topo/crbs.h (revision 1321) +++ trunk/src/plugins/rt_topo/crbs.h (revision 1322) @@ -26,8 +26,9 @@ typedef struct { point_t *cstart, *cend; rt_topo_2net_t *tn; + grbs_2net_t *gtn; + unsigned int ripped_up; /* how many times this net got ripped up */ gdl_elem_t link; - unsigned int ripped_up; /* how many times this net got ripped up */ } crbs_2net_t; typedef struct crbs_point_s { @@ -50,6 +51,7 @@ void *first_mark, *target_mark; grbs_2net_t *routing_tn; htpi_t coll_nets; /* nets routing_tn has collided with; indexed with (crbs_2net_t *) */ + int max_ripup; /* how many times are we willing to rip up a 2net (total within a layer routing) */ } crbs_t; int rt_topo_crbs(rtrnd_t *ctx, rt_topo_laa2rbs_t *src); Index: trunk/src/plugins/rt_topo/crbs_route.c =================================================================== --- trunk/src/plugins/rt_topo/crbs_route.c (revision 1321) +++ trunk/src/plugins/rt_topo/crbs_route.c (revision 1322) @@ -343,8 +343,12 @@ crbs->target = ast.target = addr_new_point(crbs, ctn->cend, &addr_tmp[1]); #warning TODO: per net wire thickness - crbs->routing_tn = grbs_2net_new(&crbs->grbs, rt_topo_cfg.wire_thick, rt_topo_cfg.wire_clr); - crbs->routing_tn->user_data = ctn; + if (ctn->gtn == NULL) { + crbs->routing_tn = ctn->gtn = grbs_2net_new(&crbs->grbs, rt_topo_cfg.wire_thick, rt_topo_cfg.wire_clr); + crbs->routing_tn->user_data = ctn; + } + else + crbs->routing_tn = ctn->gtn; printf(" route_net: from P%ld to P%ld\n", ((crbs_point_t *)(ctn->cstart->data))->gpt->uid, @@ -425,14 +429,39 @@ return res; } -static void on_fail_ripup(crbs_t *crbs, crbs_2net_t *tn) +/* Returns 1 if ripped up something */ +static int on_fail_ripup(crbs_t *crbs, crbs_2net_t *tn) { htpi_entry_t *e; - printf(" !!!!!!!!Failed to route; checking what to rip up:\n"); + int best_r = crbs->max_ripup; + crbs_2net_t *best = NULL; + + printf(" Failed to route; checking what to rip up:\n"); + for(e = htpi_first(&crbs->coll_nets); e != NULL; e = htpi_next(&crbs->coll_nets, e)) { crbs_2net_t *ctn = e->key; printf(" %s (%d)\n", ctn->tn->net->hdr.oid, ctn->ripped_up); + if (ctn->ripped_up < best_r) { + best_r = ctn->ripped_up; + best = ctn; + } } + + if (best == NULL) + return 0; /* nothing to rip up */ + + printf(" ripping up %s\n", best->tn->net->hdr.oid); + + /* remove the offending 2net */ + best->ripped_up++; + grbs_path_remove_2net(&crbs->grbs, best->gtn); + best->gtn = NULL; + + /* re-schedule it to after tn */ + gdl_remove(&crbs->twonets, best, link); + gdl_insert_after(&crbs->twonets, tn, best, link); + + return 1; } static int rt_topo_crbs_layer_(rtrnd_t *ctx, crbs_t *crbs, rtrnd_layer_t *ly, long attempt, rtrnd_layer_t *ly_cdt, rtrnd_layer_t *ly_bnk) @@ -450,13 +479,16 @@ rtrnd_export(ctx, "svg", fn, NULL, &annot); /* route all nets */ - for(ttn = gdl_first(&crbs->twonets); ttn != NULL; ttn = gdl_next(&crbs->twonets, ttn)) { + for(ttn = gdl_first(&crbs->twonets); ttn != NULL; ) { printf("CRBS route net %s:\n", ttn->tn->net->hdr.oid); if (rt_topo_crbs_route_net(crbs, ttn) != 0) { - on_fail_ripup(crbs, ttn); - res = 1; - break; + if (on_fail_ripup(crbs, ttn)) + continue; /* ripped up another net, retry with ttn */ + /* else: coudln't find anything to rip up or ripup count is too high + already: give up routing this net */ + printf(" => Giving up routing %s\n", ttn->tn->net->hdr.oid); } + ttn = gdl_next(&crbs->twonets, ttn); } rtrnd_layer_init(&ly_neighb, "neighb"); @@ -495,6 +527,7 @@ strcpy(ly_bnk.color, "#6666aa"); /* convert input twonets to crbs twonets, making sure they have endpoints in the cdt */ + crbs.max_ripup = 0; for(t = gdl_first(tnl); t != NULL; t = t->link.next) { crbs_2net_t *ct = calloc(sizeof(crbs_2net_t), 1); ct->cstart = cdt_insert_point(&crbs.cdt, t->x[0], t->y[0]); @@ -501,6 +534,7 @@ ct->cend = cdt_insert_point(&crbs.cdt, t->x[1], t->y[1]); ct->tn = t; gdl_append(&crbs.twonets, ct, link); + crbs.max_ripup++; } rt_topo_crbs_cdt_draw(ctx, &ly_cdt, &crbs.cdt);