more dirwire modeling
This commit is contained in:
parent
25bb28cfd4
commit
c9c55822be
7
LINKS
7
LINKS
|
@ -68,5 +68,10 @@ services
|
|||
CMP
|
||||
www.lfoundry.com analog and mixed signal
|
||||
- pcb
|
||||
http://www.oshpark.com used for 2 and 4-layers
|
||||
http://www.pcbcart.com Chinese corp in Hangzhou
|
||||
- ref Andrew Zonenberg:
|
||||
http://www.oshpark.com used for 2 and 4-layers
|
||||
http://www.4pcb.com Advanced Circuits
|
||||
http://www.sunstone.com Sunstone Circuits
|
||||
http://www.saecircuits.com SAE Circuits
|
||||
http://www.rjrinc.com RJR Circuits
|
||||
|
|
|
@ -162,6 +162,7 @@ enum fpga_tile_type
|
|||
// TOP_INNER_ROW to TOP_INNER_TERM?
|
||||
#define TOP_OUTER_ROW 0
|
||||
#define TOP_INNER_ROW 1
|
||||
#define TOP_FIRST_REGULAR 2
|
||||
#define TOP_OUTER_IO 2
|
||||
#define TOP_INNER_IO 3
|
||||
#define HALF_ROW 8
|
||||
|
@ -180,6 +181,7 @@ enum fpga_tile_type
|
|||
// to BOT_INNER_TERM?
|
||||
#define BOT_OUTER_ROW 1
|
||||
#define BOT_INNER_ROW 2
|
||||
#define BOT_LAST_REGULAR_O 3
|
||||
#define BOT_OUTER_IO 3
|
||||
#define BOT_INNER_IO 4
|
||||
#define RIGHT_OUTER_O 1
|
||||
|
@ -303,6 +305,11 @@ int is_atx(int check, struct fpga_model* model, int x);
|
|||
#define YX_DEV_IOB 0x0040
|
||||
#define YX_CENTER_MIDBUF 0x0080
|
||||
#define YX_OUTER_TERM 0x0100
|
||||
#define YX_INNER_TERM 0x0200
|
||||
// outside_of_routing is true for anything outside of the outer
|
||||
// boundary of the regular routing area.
|
||||
#define YX_OUTSIDE_OF_ROUTING 0x0400
|
||||
#define YX_ROUTING_BOUNDARY 0x0800
|
||||
|
||||
int is_atyx(int check, struct fpga_model* model, int y, int x);
|
||||
|
||||
|
|
|
@ -1720,10 +1720,110 @@ xout:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int net_includes_routing(struct fpga_model *model, const struct w_net *net)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < net->num_pts; i++)
|
||||
if (is_atyx(YX_ROUTING_TILE, model, net->pt[i].y, net->pt[i].x))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int y_to_regular(struct fpga_model *model, int y)
|
||||
{
|
||||
if (y < TOP_FIRST_REGULAR)
|
||||
return TOP_FIRST_REGULAR;
|
||||
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y))
|
||||
return y-1;
|
||||
if (y > model->y_height-BOT_LAST_REGULAR_O)
|
||||
return model->y_height-BOT_LAST_REGULAR_O;
|
||||
return y;
|
||||
}
|
||||
|
||||
static char dirwire_next_bamce(enum wire_type wire, char bamce)
|
||||
{
|
||||
if (W_IS_LEN4(wire)) {
|
||||
// len-4 goes from B to A to M to C to E
|
||||
if (bamce == 'B') return 'A';
|
||||
if (bamce == 'A') return 'M';
|
||||
if (bamce == 'M') return 'C';
|
||||
if (bamce == 'C') return 'E';
|
||||
if (bamce == 'E') return 'B';
|
||||
} else if (W_IS_LEN2(wire)) {
|
||||
// len-2 goes from B to M to E
|
||||
if (bamce == 'B') return 'M';
|
||||
if (bamce == 'M') return 'E';
|
||||
if (bamce == 'E') return 'B';
|
||||
} else if (W_IS_LEN1(wire)) {
|
||||
// len-1 goes from B to E
|
||||
if (bamce == 'B') return 'E';
|
||||
if (bamce == 'E') return 'B';
|
||||
}
|
||||
HERE();
|
||||
return bamce;
|
||||
}
|
||||
|
||||
static void dirwire_next_hop(struct fpga_model *model, enum wire_type wire, char bamce, int *y, int *x)
|
||||
{
|
||||
if (wire == W_NN4 || wire == W_NN2 || wire == W_NL1 || wire == W_NR1)
|
||||
(*y)--;
|
||||
else if (wire == W_SS4 || wire == W_SS2 || wire == W_SL1 || wire == W_SR1)
|
||||
(*y)++;
|
||||
else if (wire == W_EE4 || wire == W_EE2 || wire == W_EL1 || wire == W_ER1)
|
||||
(*x)++;
|
||||
else if (wire == W_WW4 || wire == W_WW2 || wire == W_WL1 || wire == W_WR1)
|
||||
(*x)--;
|
||||
else if (wire == W_NW4 || wire == W_NW2) {
|
||||
if (bamce == 'B' || bamce == 'A')
|
||||
(*y)--;
|
||||
else if (bamce == 'M') {
|
||||
if (is_aty(Y_INNER_BOTTOM|Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, *y))
|
||||
(*y)--;
|
||||
else
|
||||
(*x)--;
|
||||
} else if (bamce == 'C' || bamce == 'E')
|
||||
(*x)--;
|
||||
else HERE();
|
||||
} else if (wire == W_NE4 || wire == W_NE2) {
|
||||
if (bamce == 'B' || bamce == 'A')
|
||||
(*y)--;
|
||||
else if (bamce == 'M') {
|
||||
if (is_aty(Y_INNER_BOTTOM|Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, *y))
|
||||
(*y)--;
|
||||
else
|
||||
(*x)++;
|
||||
} else if (bamce == 'C' || bamce == 'E')
|
||||
(*x)++;
|
||||
else HERE();
|
||||
} else if (wire == W_SW4 || wire == W_SW2) {
|
||||
if (bamce == 'B' || bamce == 'A')
|
||||
(*y)++;
|
||||
else if (bamce == 'M') {
|
||||
if (is_aty(Y_INNER_TOP, model, *y))
|
||||
(*y)++;
|
||||
else
|
||||
(*x)--;
|
||||
} else if (bamce == 'C' || bamce == 'E')
|
||||
(*x)--;
|
||||
else HERE();
|
||||
} else if (wire == W_SE4 || wire == W_SE2) {
|
||||
if (bamce == 'B' || bamce == 'A')
|
||||
(*y)++;
|
||||
else if (bamce == 'M') {
|
||||
if (is_aty(Y_INNER_TOP, model, *y))
|
||||
(*y)++;
|
||||
else
|
||||
(*x)++;
|
||||
} else if (bamce == 'C' || bamce == 'E')
|
||||
(*x)++;
|
||||
else HERE();
|
||||
} else HERE();
|
||||
}
|
||||
|
||||
static int set_BAMCE_point(struct fpga_model *model, struct w_net *net,
|
||||
enum wire_type wire, char bamce, int num_0to3, int *cur_y, int *cur_x)
|
||||
{
|
||||
int y_dist_to_dev, row_pos, i, rc;
|
||||
int y_dist_to_dev, row_pos, i;
|
||||
|
||||
while (1) {
|
||||
net->pt[net->num_pts].start_count = 0;
|
||||
|
@ -1731,16 +1831,21 @@ static int set_BAMCE_point(struct fpga_model *model, struct w_net *net,
|
|||
net->pt[net->num_pts].x = *cur_x;
|
||||
if (is_atx(X_FABRIC_BRAM_COL|X_FABRIC_MACC_COL, model, *cur_x)) {
|
||||
row_pos = regular_row_pos(*cur_y, model);
|
||||
if (row_pos == -1) FAIL(EINVAL);
|
||||
if (row_pos == -1) {
|
||||
net->pt[net->num_pts].name = pf("%s%c%i", wire_base(wire), bamce, num_0to3);
|
||||
} else {
|
||||
y_dist_to_dev = 3-(row_pos%4);
|
||||
if (y_dist_to_dev) {
|
||||
net->pt[net->num_pts].y += y_dist_to_dev;
|
||||
net->pt[net->num_pts].name = pf("%s%c%i_%i", wire_base(wire), bamce, num_0to3, y_dist_to_dev);
|
||||
} else
|
||||
net->pt[net->num_pts].name = pf("%s%c%i", wire_base(wire), bamce, num_0to3);
|
||||
}
|
||||
} else if (is_atx(X_CENTER_CMTPLL_COL, model, *cur_x)) {
|
||||
row_pos = regular_row_pos(*cur_y, model);
|
||||
if (row_pos == -1) FAIL(EINVAL);
|
||||
if (row_pos == -1)
|
||||
net->pt[net->num_pts].name = pf("%s%c%i", wire_base(wire), bamce, num_0to3);
|
||||
else {
|
||||
y_dist_to_dev = 7-row_pos;
|
||||
if (y_dist_to_dev > 0) {
|
||||
net->pt[net->num_pts].y += y_dist_to_dev;
|
||||
|
@ -1751,6 +1856,7 @@ static int set_BAMCE_point(struct fpga_model *model, struct w_net *net,
|
|||
net->pt[net->num_pts].y += y_dist_to_dev - /*hclk*/ 1;
|
||||
net->pt[net->num_pts].name = pf("%s%c%i_%i", wire_base(wire), bamce, num_0to3, 16+y_dist_to_dev);
|
||||
}
|
||||
}
|
||||
} else if (is_atx(X_LEFT_MCB|X_RIGHT_MCB, model, *cur_x)) {
|
||||
if (*cur_y > XC6_MCB_YPOS-6 && *cur_y <= XC6_MCB_YPOS+6 ) {
|
||||
net->pt[net->num_pts].y = XC6_MCB_YPOS;
|
||||
|
@ -1767,73 +1873,22 @@ static int set_BAMCE_point(struct fpga_model *model, struct w_net *net,
|
|||
if (i >= sizeof(mui_pos)/sizeof(*mui_pos))
|
||||
net->pt[net->num_pts].name = pf("%s%c%i", wire_base(wire), bamce, num_0to3);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
if (is_atx(X_INNER_LEFT, model, *cur_x) && wire == W_SE2 && bamce == 'E' && num_0to3 == 3)
|
||||
net->pt[net->num_pts].name = "SE2M3";
|
||||
else
|
||||
net->pt[net->num_pts].name = pf("%s%c%i", wire_base(wire), bamce, num_0to3);
|
||||
}
|
||||
net->num_pts++;
|
||||
|
||||
if (wire == W_EE4 || wire == W_EE2 || wire == W_EL1 || wire == W_ER1) {
|
||||
// stop conditions:
|
||||
// 1. for 'E' endpoint: if current pos is routing
|
||||
// 2. for others: if next is non-first routing or outer border
|
||||
if (bamce == 'E' && is_atx(X_ROUTING_COL, model, (*cur_x))) {
|
||||
if (wire == W_EL1 && num_0to3 == 0) {
|
||||
// add EL1E_S0
|
||||
net->pt[net->num_pts].start_count = 0;
|
||||
net->pt[net->num_pts].y = (*cur_y)+1;
|
||||
net->pt[net->num_pts].x = *cur_x;
|
||||
if (is_aty(Y_INNER_BOTTOM, model, (*cur_y)+1)) {
|
||||
// no EL1E0 termination in bram cols
|
||||
if (!is_atx(X_FABRIC_BRAM_ROUTING_COL, model, *cur_x)) {
|
||||
net->pt[net->num_pts].name = "EL1E0";
|
||||
net->num_pts++;
|
||||
}
|
||||
} else if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, (*cur_y)+1)) {
|
||||
net->pt[net->num_pts].name = "EL1E0";
|
||||
net->num_pts++;
|
||||
net->pt[net->num_pts].start_count = 0;
|
||||
net->pt[net->num_pts].y = (*cur_y)+2;
|
||||
net->pt[net->num_pts].x = *cur_x;
|
||||
net->pt[net->num_pts].name = "EL1E_S0";
|
||||
net->num_pts++;
|
||||
} else {
|
||||
net->pt[net->num_pts].name = "EL1E_S0";
|
||||
net->num_pts++;
|
||||
}
|
||||
} else if (wire == W_ER1 && num_0to3 == 3) {
|
||||
net->pt[net->num_pts].start_count = 0;
|
||||
net->pt[net->num_pts].y = (*cur_y)-1;
|
||||
net->pt[net->num_pts].x = *cur_x;
|
||||
if (is_aty(Y_INNER_TOP, model, (*cur_y)-1)) {
|
||||
net->pt[net->num_pts].name = "ER1E3";
|
||||
net->num_pts++;
|
||||
} else if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, (*cur_y)-1)) {
|
||||
net->pt[net->num_pts].name = "ER1E_N3";
|
||||
net->num_pts++;
|
||||
net->pt[net->num_pts].start_count = 0;
|
||||
net->pt[net->num_pts].y = (*cur_y)-2;
|
||||
net->pt[net->num_pts].x = *cur_x;
|
||||
net->pt[net->num_pts].name = "ER1E_N3";
|
||||
net->num_pts++;
|
||||
} else {
|
||||
net->pt[net->num_pts].name = "ER1E_N3";
|
||||
net->num_pts++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
(*cur_x)++;
|
||||
if (bamce != 'E' && is_atx(X_FABRIC_ROUTING_COL|X_CENTER_ROUTING_COL|X_RIGHT_IO_ROUTING_COL, model, *cur_x))
|
||||
break;
|
||||
} else if (wire == W_WW4 || wire == W_WW2 || wire == W_WL1 || wire == W_WR1) {
|
||||
if (is_atx(X_ROUTING_COL, model, *cur_x)) {
|
||||
if (bamce == 'E') {
|
||||
if ((wire == W_WW4 || wire == W_WR1) && num_0to3 == 0) {
|
||||
if (is_atyx(YX_ROUTING_TILE, model, *cur_y, *cur_x)) {
|
||||
if ((wire == W_EL1 || wire == W_NE2 || wire == W_NW4 || wire == W_NW2 || wire == W_WW4 || wire == W_WR1) && num_0to3 == 0) {
|
||||
// add _S0
|
||||
net->pt[net->num_pts].start_count = 0;
|
||||
net->pt[net->num_pts].y = (*cur_y)+1;
|
||||
net->pt[net->num_pts].x = *cur_x;
|
||||
if (is_aty(Y_INNER_BOTTOM, model, (*cur_y)+1)) {
|
||||
// no WW4E0 termination in bram cols
|
||||
if (!is_atx(X_FABRIC_BRAM_ROUTING_COL, model, *cur_x)) {
|
||||
net->pt[net->num_pts].name = pf("%sE0", wire_base(wire));
|
||||
net->num_pts++;
|
||||
|
@ -1850,7 +1905,27 @@ static int set_BAMCE_point(struct fpga_model *model, struct w_net *net,
|
|||
net->pt[net->num_pts].name = pf("%sE_S0", wire_base(wire));
|
||||
net->num_pts++;
|
||||
}
|
||||
} else if ((wire == W_WW2 || wire == W_WL1) && num_0to3 == 3) {
|
||||
} else if ((wire == W_NN2 || wire == W_NL1) && num_0to3 == 0) {
|
||||
// add _S0
|
||||
net->pt[net->num_pts].start_count = 0;
|
||||
net->pt[net->num_pts].y = (*cur_y)+1;
|
||||
net->pt[net->num_pts].x = *cur_x;
|
||||
if (is_aty(Y_INNER_BOTTOM, model, (*cur_y)+1)) {
|
||||
net->pt[net->num_pts].name = pf("%sE_S0", wire_base(wire));
|
||||
net->num_pts++;
|
||||
} else if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, (*cur_y)+1)) {
|
||||
net->pt[net->num_pts].name = pf("%sE_S0", wire_base(wire));
|
||||
net->num_pts++;
|
||||
net->pt[net->num_pts].start_count = 0;
|
||||
net->pt[net->num_pts].y = (*cur_y)+2;
|
||||
net->pt[net->num_pts].x = *cur_x;
|
||||
net->pt[net->num_pts].name = pf("%sE_S0", wire_base(wire));
|
||||
net->num_pts++;
|
||||
} else {
|
||||
net->pt[net->num_pts].name = pf("%sE_S0", wire_base(wire));
|
||||
net->num_pts++;
|
||||
}
|
||||
} else if ((wire == W_SW4 || wire == W_SW2 || wire == W_ER1 || wire == W_WW2 || wire == W_WL1) && num_0to3 == 3) {
|
||||
// add _N3
|
||||
net->pt[net->num_pts].start_count = 0;
|
||||
net->pt[net->num_pts].y = (*cur_y)-1;
|
||||
|
@ -1870,51 +1945,7 @@ static int set_BAMCE_point(struct fpga_model *model, struct w_net *net,
|
|||
net->pt[net->num_pts].name = pf("%sE_N3", wire_base(wire));
|
||||
net->num_pts++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
(*cur_x)--;
|
||||
// when reaching the inner termination, wire
|
||||
// up one more into the termination
|
||||
if (!is_atx(X_INNER_LEFT, model, (*cur_x)))
|
||||
break;
|
||||
} else
|
||||
(*cur_x)--;
|
||||
} else if (wire == W_NN4 || wire == W_NN2 || wire == W_NL1 || wire == W_NR1) {
|
||||
if (is_aty(Y_REGULAR_ROW, model, *cur_y)) {
|
||||
if (bamce == 'E') {
|
||||
if ((wire == W_NN2 || wire == W_NL1) && num_0to3 == 0) {
|
||||
// add _S0
|
||||
net->pt[net->num_pts].start_count = 0;
|
||||
net->pt[net->num_pts].y = (*cur_y)+1;
|
||||
net->pt[net->num_pts].x = *cur_x;
|
||||
if (is_aty(Y_INNER_BOTTOM, model, (*cur_y)+1)) {
|
||||
net->pt[net->num_pts].name = pf("%sE_S0", wire_base(wire));
|
||||
net->num_pts++;
|
||||
} else if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, (*cur_y)+1)) {
|
||||
net->pt[net->num_pts].name = pf("%sE_S0", wire_base(wire));
|
||||
net->num_pts++;
|
||||
net->pt[net->num_pts].start_count = 0;
|
||||
net->pt[net->num_pts].y = (*cur_y)+2;
|
||||
net->pt[net->num_pts].x = *cur_x;
|
||||
net->pt[net->num_pts].name = pf("%sE_S0", wire_base(wire));
|
||||
net->num_pts++;
|
||||
} else {
|
||||
net->pt[net->num_pts].name = pf("%sE_S0", wire_base(wire));
|
||||
net->num_pts++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
(*cur_y)--;
|
||||
if (!is_aty(Y_INNER_TOP, model, (*cur_y)))
|
||||
break;
|
||||
} else
|
||||
(*cur_y)--;
|
||||
} else if (wire == W_SS4 || wire == W_SS2 || wire == W_SL1 || wire == W_SR1) {
|
||||
if (bamce == 'E') {
|
||||
if (is_aty(Y_REGULAR_ROW, model, *cur_y)) {
|
||||
if ((wire == W_SS2 || wire == W_SS4 || wire == W_SR1) && num_0to3 == 3) {
|
||||
} else if ((wire == W_SS4 || wire == W_SS2 || wire == W_SR1) && num_0to3 == 3) {
|
||||
// add _N3
|
||||
net->pt[net->num_pts].start_count = 0;
|
||||
net->pt[net->num_pts].y = (*cur_y)-1;
|
||||
|
@ -1937,112 +1968,22 @@ static int set_BAMCE_point(struct fpga_model *model, struct w_net *net,
|
|||
}
|
||||
break;
|
||||
}
|
||||
(*cur_y)++;
|
||||
dirwire_next_hop(model, wire, bamce, cur_y, cur_x);
|
||||
} else {
|
||||
(*cur_y)++;
|
||||
if (!is_aty(Y_INNER_TOP, model, (*cur_y)-1)
|
||||
&& is_aty(Y_REGULAR_ROW, model, *cur_y))
|
||||
int prior_x_major = model->x_major[*cur_x];
|
||||
int prior_y_regular = y_to_regular(model, *cur_y);
|
||||
dirwire_next_hop(model, wire, bamce, cur_y, cur_x);
|
||||
if (net_includes_routing(model, net)) {
|
||||
if (prior_x_major != model->x_major[*cur_x])
|
||||
break;
|
||||
if (prior_y_regular != y_to_regular(model, *cur_y))
|
||||
break;
|
||||
}
|
||||
} else FAIL(EINVAL);
|
||||
}
|
||||
if (is_atyx(YX_OUTER_TERM, model, *cur_y, *cur_x))
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int add_dirwire_net(struct fpga_model *model, add_conn_f add_conn_func, const struct w_net *net)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
rc = add_conn_net(model, add_conn_func, net);
|
||||
if (rc) FAIL(rc);
|
||||
// wire _S0 from top termination
|
||||
for (i = 0; i < net->num_pts; i++) {
|
||||
if (is_atx(X_ROUTING_COL, model, net->pt[i].x)
|
||||
&& is_aty(Y_INNER_TOP, model, net->pt[i].y-1)) {
|
||||
if (!strcmp(net->pt[i].name, "WW4E0")) {
|
||||
rc = add_conn_func(model, net->pt[i].y, net->pt[i].x, "WW4E_S0",
|
||||
net->pt[i].y-1, net->pt[i].x, "WW4E_S0");
|
||||
if (rc) FAIL(rc);
|
||||
break;
|
||||
}
|
||||
if (!strcmp(net->pt[i].name, "EL1E0")) {
|
||||
rc = add_conn_func(model, net->pt[i].y, net->pt[i].x, "EL1E_S0",
|
||||
net->pt[i].y-1, net->pt[i].x, "EL1E_S0");
|
||||
if (rc) FAIL(rc);
|
||||
break;
|
||||
}
|
||||
if (!strcmp(net->pt[i].name, "WR1E0")) {
|
||||
rc = add_conn_func(model, net->pt[i].y, net->pt[i].x, "WR1E_S0",
|
||||
net->pt[i].y-1, net->pt[i].x, "WR1E_S0");
|
||||
if (rc) FAIL(rc);
|
||||
break;
|
||||
}
|
||||
if (!strcmp(net->pt[i].name, "NN2E0")) {
|
||||
rc = add_conn_func(model, net->pt[i].y, net->pt[i].x, "NN2E_S0",
|
||||
net->pt[i].y-1, net->pt[i].x, "NN2E_S0");
|
||||
if (rc) FAIL(rc);
|
||||
break;
|
||||
}
|
||||
if (!strcmp(net->pt[i].name, "NL1E0")) {
|
||||
rc = add_conn_func(model, net->pt[i].y, net->pt[i].x, "NL1E_S0",
|
||||
net->pt[i].y-1, net->pt[i].x, "NL1E_S0");
|
||||
if (rc) FAIL(rc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// wire _N3 from bottom termination
|
||||
for (i = 0; i < net->num_pts; i++) {
|
||||
// in all routing cols but bram routing
|
||||
if (is_atx(X_FABRIC_LOGIC_ROUTING_COL|X_FABRIC_MACC_ROUTING_COL
|
||||
|X_CENTER_ROUTING_COL|X_LEFT_IO_ROUTING_COL
|
||||
|X_RIGHT_IO_ROUTING_COL, model, net->pt[i].x)
|
||||
&& is_aty(Y_INNER_BOTTOM, model, net->pt[i].y+1)) {
|
||||
if (!strcmp(net->pt[i].name, "WW2E3")) {
|
||||
rc = add_conn_func(model, net->pt[i].y, net->pt[i].x, "WW2E_N3",
|
||||
net->pt[i].y+1, net->pt[i].x, "WW2E_N3");
|
||||
if (rc) FAIL(rc);
|
||||
break;
|
||||
}
|
||||
if (!strcmp(net->pt[i].name, "ER1E3")) {
|
||||
rc = add_conn_func(model, net->pt[i].y, net->pt[i].x, "ER1E_N3",
|
||||
net->pt[i].y+1, net->pt[i].x, "ER1E_N3");
|
||||
if (rc) FAIL(rc);
|
||||
break;
|
||||
}
|
||||
if (!strcmp(net->pt[i].name, "WL1E3")) {
|
||||
rc = add_conn_func(model, net->pt[i].y, net->pt[i].x, "WL1E_N3",
|
||||
net->pt[i].y+1, net->pt[i].x, "WL1E_N3");
|
||||
if (rc) FAIL(rc);
|
||||
break;
|
||||
}
|
||||
if (!strcmp(net->pt[i].name, "SS4E3")) {
|
||||
rc = add_conn_func(model, net->pt[i].y, net->pt[i].x, "SS4E_N3",
|
||||
net->pt[i].y+1, net->pt[i].x, "SS4E_N3");
|
||||
if (rc) FAIL(rc);
|
||||
break;
|
||||
}
|
||||
if (!strcmp(net->pt[i].name, "SS2E3")) {
|
||||
rc = add_conn_func(model, net->pt[i].y, net->pt[i].x, "SS2E_N3",
|
||||
net->pt[i].y+1, net->pt[i].x, "SS2E_N3");
|
||||
if (rc) FAIL(rc);
|
||||
break;
|
||||
}
|
||||
if (!strcmp(net->pt[i].name, "SR1E3")) {
|
||||
rc = add_conn_func(model, net->pt[i].y, net->pt[i].x, "SR1E_N3",
|
||||
net->pt[i].y+1, net->pt[i].x, "SR1E_N3");
|
||||
if (rc) FAIL(rc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int run_dirwire(struct fpga_model *model, int start_y, int start_x,
|
||||
|
@ -2065,47 +2006,17 @@ static int run_dirwire(struct fpga_model *model, int start_y, int start_x,
|
|||
|
||||
if (cur_bamce == 'E' || outer_term_hit) {
|
||||
if (net.num_pts < 2) FAIL(EINVAL);
|
||||
if ((rc = add_dirwire_net(model, PREF_BI_F, &net))) FAIL(rc);
|
||||
if ((rc = add_conn_net(model, PREF_BI_F, &net))) FAIL(rc);
|
||||
net.num_pts = 0;
|
||||
if (outer_term_hit)
|
||||
break;
|
||||
if (is_atx(X_FABRIC_BRAM_ROUTING_COL, model, cur_x)
|
||||
&& ((wire == W_SS4 && cur_y >= model->y_height-BOT_INNER_ROW-4)
|
||||
|| (wire == W_SS2 && cur_y >= model->y_height-BOT_INNER_ROW-2)
|
||||
|| ((wire == W_SL1 || wire == W_SR1) && cur_y >= model->y_height-BOT_INNER_ROW-1)))
|
||||
|| ((wire == W_SS2 || wire == W_SE4 || wire == W_SW4) && cur_y >= model->y_height-BOT_INNER_ROW-2)
|
||||
|| ((wire == W_SL1 || wire == W_SR1 || wire == W_SE2 || wire == W_SW2) && cur_y >= model->y_height-BOT_INNER_ROW-1)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (W_IS_LEN4(wire)) {
|
||||
// len-4 goes from B to A to M to C to E
|
||||
if (cur_bamce == 'B')
|
||||
cur_bamce = 'A';
|
||||
else if (cur_bamce == 'A')
|
||||
cur_bamce = 'M';
|
||||
else if (cur_bamce == 'M')
|
||||
cur_bamce = 'C';
|
||||
else if (cur_bamce == 'C')
|
||||
cur_bamce = 'E';
|
||||
else if (cur_bamce == 'E')
|
||||
cur_bamce = 'B';
|
||||
else FAIL(EINVAL);
|
||||
} else if (W_IS_LEN2(wire)) {
|
||||
// len-2 goes from B to M to E
|
||||
if (cur_bamce == 'B')
|
||||
cur_bamce = 'M';
|
||||
else if (cur_bamce == 'M')
|
||||
cur_bamce = 'E';
|
||||
else if (cur_bamce == 'E')
|
||||
cur_bamce = 'B';
|
||||
else FAIL(EINVAL);
|
||||
} else if (W_IS_LEN1(wire)) {
|
||||
// len-1 goes from B to E
|
||||
if (cur_bamce == 'B')
|
||||
cur_bamce = 'E';
|
||||
else if (cur_bamce == 'E')
|
||||
cur_bamce = 'B';
|
||||
else FAIL(EINVAL);
|
||||
} else FAIL(EINVAL);
|
||||
cur_bamce = dirwire_next_bamce(wire, cur_bamce);
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
|
@ -2125,28 +2036,31 @@ fail:
|
|||
return rc;
|
||||
}
|
||||
|
||||
//
|
||||
// A EE4-wire goes through the chip from left to right like this:
|
||||
//
|
||||
// E/B A M C E/B A M C E/B
|
||||
// C E/B A M C E/B A M C
|
||||
// M C E/B A M C E/B A M
|
||||
// A M C E/B A M C E/B A
|
||||
//
|
||||
// set_BAMCE_point() adds net entries for one such point, run_dirwire()
|
||||
// runs one wire through the chip, run_dirwires() goes through
|
||||
// all rows vertically.
|
||||
//
|
||||
|
||||
static int run_dirwires(struct fpga_model* model)
|
||||
{
|
||||
int y, x, i, rc;
|
||||
|
||||
//
|
||||
// A EE4-wire goes through the chip from left to right like this:
|
||||
//
|
||||
// E/B A M C E/B A M C E/B
|
||||
// C E/B A M C E/B A M C
|
||||
// M C E/B A M C E/B A M
|
||||
// A M C E/B A M C E/B A
|
||||
//
|
||||
// set_BAMCE_point() adds net entries for one such point, run_dirwire()
|
||||
// runs one wire through the chip, run_dirwires() goes through
|
||||
// all rows vertically.
|
||||
//
|
||||
|
||||
//
|
||||
// EE4, EE2, EL1, ER1
|
||||
// WW4, WW2, WL1, WR1
|
||||
//
|
||||
|
||||
for (y = TOP_OUTER_IO; y <= model->y_height-BOT_OUTER_IO; y++) {
|
||||
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y))
|
||||
continue;
|
||||
|
||||
// EE4
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_EE4, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_EE4, 'C');
|
||||
|
@ -2155,22 +2069,15 @@ static int run_dirwires(struct fpga_model* model)
|
|||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_EE4, 'A');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// EE2
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_EE2, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_EE2, 'M');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// EL1
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_EL1, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// ER1
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_ER1, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// WW4
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_WW4, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_WW4, 'C');
|
||||
|
@ -2179,47 +2086,63 @@ static int run_dirwires(struct fpga_model* model)
|
|||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_WW4, 'A');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// WW2
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_WW2, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_WW2, 'M');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// WL1
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_WL1, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// WR1
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_WR1, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
for (x = LEFT_IO_ROUTING; x <= model->x_width-RIGHT_IO_ROUTING_O; x++) {
|
||||
if (!is_atx(X_ROUTING_COL, model, x))
|
||||
continue;
|
||||
if ((rc = add_conn_bi_pref(model, TOP_INNER_ROW, x, "WW4E_S0",
|
||||
TOP_FIRST_REGULAR, x, "WW4E_S0"))) FAIL(rc);
|
||||
if ((rc = add_conn_bi_pref(model, TOP_INNER_ROW, x, "EL1E_S0",
|
||||
TOP_FIRST_REGULAR, x, "EL1E_S0"))) FAIL(rc);
|
||||
if ((rc = add_conn_bi_pref(model, TOP_INNER_ROW, x, "WR1E_S0",
|
||||
TOP_FIRST_REGULAR, x, "WR1E_S0"))) FAIL(rc);
|
||||
|
||||
if (!is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
||||
if ((rc = add_conn_bi_pref(model, model->y_height-BOT_INNER_ROW, x, "WW2E_N3",
|
||||
model->y_height-BOT_LAST_REGULAR_O, x, "WW2E_N3"))) FAIL(rc);
|
||||
if ((rc = add_conn_bi_pref(model, model->y_height-BOT_INNER_ROW, x, "ER1E_N3",
|
||||
model->y_height-BOT_LAST_REGULAR_O, x, "ER1E_N3"))) FAIL(rc);
|
||||
if ((rc = add_conn_bi_pref(model, model->y_height-BOT_INNER_ROW, x, "WL1E_N3",
|
||||
model->y_height-BOT_LAST_REGULAR_O, x, "WL1E_N3"))) FAIL(rc);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// NN4, NN2, NL1, NR1
|
||||
// SS4, SS2, SL1, SR1
|
||||
//
|
||||
|
||||
for (x = LEFT_IO_ROUTING; x <= model->x_width-RIGHT_IO_ROUTING_O; x++) {
|
||||
if (!is_atx(X_ROUTING_COL, model, x))
|
||||
continue;
|
||||
|
||||
if (is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
||||
// NN4
|
||||
for (i = 0; i <= 3; i++) {
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW-1-i, x, W_NN4, 'B');
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
|
||||
// NN2
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW-1, x, W_NN2, 'B');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW-2, x, W_NN2, 'B');
|
||||
if (rc) FAIL(rc);
|
||||
if ((rc = add_conn_bi_pref(model,
|
||||
model->y_height-BOT_INNER_ROW-2, x, "NN2E0",
|
||||
model->y_height-BOT_INNER_ROW-1, x, "NN2E_S0"))) FAIL(rc);
|
||||
|
||||
// NL1
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW-1, x, W_NL1, 'B');
|
||||
if (rc) FAIL(rc);
|
||||
// NR1
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW-1, x, W_NR1, 'B');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
} else {
|
||||
// NN4
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NN4, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NN4, 'C');
|
||||
|
@ -2228,21 +2151,16 @@ static int run_dirwires(struct fpga_model* model)
|
|||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NN4, 'A');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// NN2
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NN2, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NN2, 'M');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// NL1
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NL1, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
// NR1
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NR1, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
// SS4
|
||||
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SS4, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SS4, 'M');
|
||||
|
@ -2251,20 +2169,226 @@ static int run_dirwires(struct fpga_model* model)
|
|||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SS4, 'A');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// SS2
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SS2, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SS2, 'M');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// SL1
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SL1, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
// SR1
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SR1, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
|
||||
for (x = LEFT_IO_ROUTING; x <= model->x_width-RIGHT_IO_ROUTING_O; x++) {
|
||||
if (!is_atx(X_ROUTING_COL, model, x))
|
||||
continue;
|
||||
if ((rc = add_conn_bi_pref(model, TOP_INNER_ROW, x, "NN2E_S0",
|
||||
TOP_FIRST_REGULAR, x, "NN2E_S0"))) FAIL(rc);
|
||||
if ((rc = add_conn_bi_pref(model, TOP_INNER_ROW, x, "NL1E_S0",
|
||||
TOP_FIRST_REGULAR, x, "NL1E_S0"))) FAIL(rc);
|
||||
if (!is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
||||
if ((rc = add_conn_bi_pref(model, model->y_height-BOT_INNER_ROW, x, "SS4E_N3",
|
||||
model->y_height-BOT_LAST_REGULAR_O, x, "SS4E_N3"))) FAIL(rc);
|
||||
if ((rc = add_conn_bi_pref(model, model->y_height-BOT_INNER_ROW, x, "SS2E_N3",
|
||||
model->y_height-BOT_LAST_REGULAR_O, x, "SS2E_N3"))) FAIL(rc);
|
||||
if ((rc = add_conn_bi_pref(model, model->y_height-BOT_INNER_ROW, x, "SR1E_N3",
|
||||
model->y_height-BOT_LAST_REGULAR_O, x, "SR1E_N3"))) FAIL(rc);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SE4, SE2, SW4, SW2
|
||||
//
|
||||
|
||||
for (x = LEFT_IO_ROUTING; x <= model->x_width-RIGHT_IO_ROUTING_O; x++) {
|
||||
if (!is_atx(X_ROUTING_COL, model, x))
|
||||
continue;
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SE4, 'M');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SE4, 'A');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SE2, 'M');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SW4, 'M');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SW4, 'A');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, TOP_INNER_ROW, x, W_SW2, 'M');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
if (!is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
||||
if ((rc = add_conn_bi_pref(model, model->y_height-BOT_INNER_ROW, x, "SW4E_N3",
|
||||
model->y_height-BOT_LAST_REGULAR_O, x, "SW4E_N3"))) FAIL(rc);
|
||||
if ((rc = add_conn_bi_pref(model, model->y_height-BOT_INNER_ROW, x, "SW2E_N3",
|
||||
model->y_height-BOT_LAST_REGULAR_O, x, "SW2E_N3"))) FAIL(rc);
|
||||
}
|
||||
}
|
||||
for (y = TOP_OUTER_IO; y <= model->y_height-BOT_OUTER_IO; y++) {
|
||||
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y))
|
||||
continue;
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_SE4, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_SE4, 'C');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_SE2, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_SW4, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_SW4, 'C');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_SW2, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
|
||||
//
|
||||
// NE4, NE2
|
||||
//
|
||||
|
||||
for (x = LEFT_IO_ROUTING; x <= model->x_width-RIGHT_IO_ROUTING_O; x++) {
|
||||
if (!is_atx(X_ROUTING_COL, model, x))
|
||||
continue;
|
||||
|
||||
if (is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
||||
// NE2B is one major right, NE4B is two majors right
|
||||
int plus_one_major, plus_two_majors;
|
||||
plus_one_major = x+1;
|
||||
while (plus_one_major != -1
|
||||
&& !is_atx(X_ROUTING_COL, model, plus_one_major)) {
|
||||
if (++plus_one_major >= model->x_width)
|
||||
plus_one_major = -1;
|
||||
}
|
||||
if (plus_one_major == -1)
|
||||
plus_two_majors = -1;
|
||||
else {
|
||||
plus_two_majors = plus_one_major + 1;
|
||||
while (plus_two_majors != -1
|
||||
&& !is_atx(X_ROUTING_COL, model, plus_two_majors)) {
|
||||
if (++plus_two_majors >= model->x_width)
|
||||
plus_two_majors = -1;
|
||||
}
|
||||
}
|
||||
if (plus_two_majors != -1) {
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW-1, plus_two_majors, W_NE4, 'B');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW-2, plus_two_majors, W_NE4, 'B');
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
if (plus_one_major != -1) {
|
||||
struct w_net net;
|
||||
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW-1, plus_one_major, W_NE2, 'B');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
net.last_inc = 2;
|
||||
net.num_pts = 0;
|
||||
for (i = x; i <= plus_one_major; i++) {
|
||||
net.pt[net.num_pts].start_count = 1;
|
||||
net.pt[net.num_pts].y = model->y_height-BOT_INNER_ROW-1;
|
||||
net.pt[net.num_pts].x = i;
|
||||
net.pt[net.num_pts].name = (i == plus_one_major) ? "NE2E%i" : "NE2M%i";
|
||||
net.num_pts++;
|
||||
}
|
||||
rc = add_conn_net(model, PREF_BI_F, &net);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
if ((rc = add_conn_bi_pref(model,
|
||||
model->y_height-BOT_INNER_ROW-1, plus_one_major, "NE2E0",
|
||||
model->y_height-BOT_INNER_ROW, plus_one_major, "NE2E0"))) FAIL(rc);
|
||||
}
|
||||
} else {
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NE4, 'M');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NE4, 'A');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NE2, 'M');
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
if ((rc = add_conn_bi_pref(model, TOP_INNER_ROW, x, "NE2E_S0",
|
||||
TOP_FIRST_REGULAR, x, "NE2E_S0"))) FAIL(rc);
|
||||
}
|
||||
for (y = TOP_OUTER_IO; y <= model->y_height-BOT_OUTER_IO; y++) {
|
||||
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y))
|
||||
continue;
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_NE4, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_NE4, 'C');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, LEFT_INNER_COL, W_NE2, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
|
||||
//
|
||||
// NW4, NW2
|
||||
//
|
||||
|
||||
for (x = LEFT_IO_ROUTING; x <= model->x_width-RIGHT_IO_ROUTING_O; x++) {
|
||||
if (!is_atx(X_ROUTING_COL, model, x))
|
||||
continue;
|
||||
|
||||
if (is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
||||
// NW2B is one major left, NW4B is two majors left
|
||||
int minus_one_major, minus_two_majors;
|
||||
minus_one_major = x-1;
|
||||
while (minus_one_major != -1
|
||||
&& !is_atx(X_ROUTING_COL, model, minus_one_major)) {
|
||||
if (--minus_one_major < LEFT_IO_ROUTING)
|
||||
minus_one_major = -1;
|
||||
}
|
||||
if (minus_one_major == -1)
|
||||
minus_two_majors = -1;
|
||||
else {
|
||||
minus_two_majors = minus_one_major - 1;
|
||||
while (minus_two_majors != -1
|
||||
&& !is_atx(X_ROUTING_COL, model, minus_two_majors)) {
|
||||
if (--minus_two_majors < LEFT_IO_ROUTING)
|
||||
minus_two_majors = -1;
|
||||
}
|
||||
}
|
||||
if (minus_two_majors != -1) {
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW-1, minus_two_majors, W_NW4, 'B');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW-2, minus_two_majors, W_NW4, 'B');
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
if ((rc = add_conn_bi_pref(model,
|
||||
model->y_height-BOT_INNER_ROW-2, minus_two_majors, "NW4E0",
|
||||
model->y_height-BOT_INNER_ROW-1, minus_two_majors, "NW4E_S0"))) FAIL(rc);
|
||||
if ((rc = add_conn_bi_pref(model,
|
||||
model->y_height-BOT_INNER_ROW-1, minus_two_majors, "NW4E0",
|
||||
model->y_height-BOT_INNER_ROW, minus_two_majors, "NW4E0"))) FAIL(rc);
|
||||
}
|
||||
if (minus_one_major != -1) {
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW-1, minus_one_major, W_NW2, 'B');
|
||||
if (rc) FAIL(rc);
|
||||
if ((rc = add_conn_bi_pref(model,
|
||||
model->y_height-BOT_INNER_ROW-1, minus_one_major, "NW2E0",
|
||||
model->y_height-BOT_INNER_ROW, minus_one_major, "NW2E0"))) FAIL(rc);
|
||||
}
|
||||
} else {
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NW4, 'M');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NW4, 'A');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, model->y_height-BOT_INNER_ROW, x, W_NW2, 'M');
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
if ((rc = add_conn_bi_pref(model, TOP_INNER_ROW, x, "NW4E_S0",
|
||||
TOP_FIRST_REGULAR, x, "NW4E_S0"))) FAIL(rc);
|
||||
if ((rc = add_conn_bi_pref(model, TOP_INNER_ROW, x, "NW2E_S0",
|
||||
TOP_FIRST_REGULAR, x, "NW2E_S0"))) FAIL(rc);
|
||||
}
|
||||
for (y = TOP_OUTER_IO; y <= model->y_height-BOT_OUTER_IO; y++) {
|
||||
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y))
|
||||
continue;
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_NW4, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_NW4, 'C');
|
||||
if (rc) FAIL(rc);
|
||||
rc = run_dirwire_0to3(model, y, model->x_width-RIGHT_INNER_O, W_NW2, 'E');
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
|
|
|
@ -634,8 +634,8 @@ int is_atyx(int check, struct fpga_model* model, int y, int x)
|
|||
// todo: YX_ROUTING_TILE could be implemented using X_ROUTING_COL and Y_REGULAR_ROW ?
|
||||
if (check & YX_ROUTING_TILE
|
||||
&& (model->tiles[x].flags & TF_FABRIC_ROUTING_COL
|
||||
|| x == LEFT_IO_ROUTING || x == model->x_width-5
|
||||
|| x == model->center_x-3)) {
|
||||
|| x == LEFT_IO_ROUTING || x == model->x_width-RIGHT_IO_ROUTING_O
|
||||
|| x == model->center_x-CENTER_ROUTING_O)) {
|
||||
int row_pos;
|
||||
is_in_row(model, y, 0 /* row_num */, &row_pos);
|
||||
if (row_pos >= 0 && row_pos != 8) return 1;
|
||||
|
@ -654,6 +654,18 @@ int is_atyx(int check, struct fpga_model* model, int y, int x)
|
|||
if (check & YX_OUTER_TERM
|
||||
&& (is_atx(X_OUTER_LEFT|X_OUTER_RIGHT, model, x)
|
||||
|| is_aty(Y_OUTER_TOP|Y_OUTER_BOTTOM, model, y))) return 1;
|
||||
if (check & YX_INNER_TERM
|
||||
&& (is_atx(X_INNER_LEFT|X_INNER_RIGHT, model, x)
|
||||
|| is_aty(Y_INNER_TOP|Y_INNER_BOTTOM, model, y))) return 1;
|
||||
if (check & YX_OUTSIDE_OF_ROUTING
|
||||
&& (x < LEFT_IO_ROUTING
|
||||
|| x > model->x_width-RIGHT_IO_ROUTING_O
|
||||
|| y <= TOP_INNER_ROW
|
||||
|| y >= model->y_height-BOT_INNER_ROW )) return 1;
|
||||
if (check & YX_ROUTING_BOUNDARY
|
||||
&& is_atyx(YX_ROUTING_TILE, model, y, x)
|
||||
&& (x == LEFT_IO_ROUTING || x == model->x_width-RIGHT_IO_ROUTING_O
|
||||
|| y == TOP_FIRST_REGULAR || y == model->y_height-BOT_LAST_REGULAR_O)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user