a few more short north and south wires, autotester
This commit is contained in:
parent
988180051c
commit
0fa0e7f3c3
4
README
4
README
|
@ -19,7 +19,7 @@ Libraries
|
||||||
|
|
||||||
- libfpga-test autotest suite
|
- libfpga-test autotest suite
|
||||||
- libfpga-cores reusable cores
|
- libfpga-cores reusable cores
|
||||||
- libfpga-design larger design elements on top of libfpga-control
|
- libfpga-stdlib standard design elements on top of libfpga-control
|
||||||
- libfpga-control programmatic access to libfpga-model
|
- libfpga-control programmatic access to libfpga-model
|
||||||
- libfpga-model memory-only representation of an FPGA
|
- libfpga-model memory-only representation of an FPGA
|
||||||
- libfpga-floorplan reads and writes .fp floorplan files
|
- libfpga-floorplan reads and writes .fp floorplan files
|
||||||
|
@ -63,7 +63,7 @@ TODO (as of 2012-08, expected time to delivery: months to years
|
||||||
* configuration of bram and macc blocks, bram initialization data
|
* configuration of bram and macc blocks, bram initialization data
|
||||||
* routing switches
|
* routing switches
|
||||||
* many more cases in model of switches and inter-tile connections
|
* many more cases in model of switches and inter-tile connections
|
||||||
* write standard design elements for libfpga-design library
|
* write standard design elements for libfpga-stdlib library
|
||||||
* support lm32 or openrisc core, either via libfpga or iverilog backend
|
* support lm32 or openrisc core, either via libfpga or iverilog backend
|
||||||
* ipv6 or vnc in hardware?
|
* ipv6 or vnc in hardware?
|
||||||
* iverilog fpga backend
|
* iverilog fpga backend
|
||||||
|
|
277
autotest.c
277
autotest.c
|
@ -201,8 +201,7 @@ static int test_logic_net(struct test_state* tstate, int logic_y, int logic_x,
|
||||||
|
|
||||||
// add port
|
// add port
|
||||||
rc = fpga_net_add_port(tstate->model, net_idx, logic_y, logic_x,
|
rc = fpga_net_add_port(tstate->model, net_idx, logic_y, logic_x,
|
||||||
fpga_dev_idx(tstate->model, logic_y, logic_x, DEV_LOGIC,
|
DEV_LOGIC, type_idx, port);
|
||||||
type_idx), port);
|
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
// add (one) switch in logic tile
|
// add (one) switch in logic tile
|
||||||
|
@ -277,7 +276,7 @@ static int test_logic_net_l2(struct test_state* tstate, int y, int x,
|
||||||
rc = fpga_switch_to_yx(&switch_to);
|
rc = fpga_switch_to_yx(&switch_to);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
if (dbg)
|
if (dbg)
|
||||||
printf_switch_to_result(&switch_to);
|
printf_switch_to_yx_result(&switch_to);
|
||||||
|
|
||||||
switch_tile = YX_TILE(tstate->model, switch_to.dest_y, switch_to.dest_x);
|
switch_tile = YX_TILE(tstate->model, switch_to.dest_y, switch_to.dest_x);
|
||||||
rc = fpga_swset_fromto(tstate->model, switch_to.dest_y,
|
rc = fpga_swset_fromto(tstate->model, switch_to.dest_y,
|
||||||
|
@ -379,7 +378,7 @@ static int test_logic_net_l1(struct test_state* tstate, int y, int x,
|
||||||
rc = fpga_switch_to_yx(&switch_to);
|
rc = fpga_switch_to_yx(&switch_to);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
if (tstate->dry_run)
|
if (tstate->dry_run)
|
||||||
printf_switch_to_result(&switch_to);
|
printf_switch_to_yx_result(&switch_to);
|
||||||
|
|
||||||
rc = fpga_swset_fromto(tstate->model, switch_to.dest_y,
|
rc = fpga_swset_fromto(tstate->model, switch_to.dest_y,
|
||||||
switch_to.dest_x, switch_to.dest_connpt, from_to, &set_l1);
|
switch_to.dest_x, switch_to.dest_connpt, from_to, &set_l1);
|
||||||
|
@ -414,8 +413,259 @@ fail:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_switches(struct test_state* tstate, int y, int x,
|
||||||
|
str16_t start_switch, net_idx_t net, swidx_t* done_list, int* done_list_len)
|
||||||
|
{
|
||||||
|
struct sw_set sw_set, w4_set;
|
||||||
|
const char* switch_str;
|
||||||
|
str16_t switch_str_i;
|
||||||
|
int i, j, k, rc;
|
||||||
|
|
||||||
|
rc = fpga_swset_fromto(tstate->model, y, x, start_switch, SW_TO, &sw_set);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
if (tstate->dry_run)
|
||||||
|
fpga_swset_print(tstate->model, y, x, &sw_set, SW_TO);
|
||||||
|
|
||||||
|
for (i = 0; i < sw_set.len; i++) {
|
||||||
|
switch_str_i = fpga_switch_str_i(tstate->model, y, x,
|
||||||
|
sw_set.sw[i], SW_FROM);
|
||||||
|
switch_str = strarray_lookup(&tstate->model->str, switch_str_i);
|
||||||
|
if (!switch_str) FAIL(EINVAL);
|
||||||
|
if (switch_str[2] == '4') {
|
||||||
|
// base for len-4 wire
|
||||||
|
if (tstate->dry_run)
|
||||||
|
fprintf_net(stdout, tstate->model, net);
|
||||||
|
rc = diff_printf(tstate);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
// add len-4 wire
|
||||||
|
rc = fpga_net_add_sw(tstate->model, net, y, x,
|
||||||
|
&sw_set.sw[i], 1);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
// enum dests of len-4 wire
|
||||||
|
rc = fpga_swset_fromto(tstate->model, y, x,
|
||||||
|
switch_str_i, SW_FROM, &w4_set);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
if (tstate->dry_run)
|
||||||
|
fpga_swset_print(tstate->model, y, x,
|
||||||
|
&w4_set, SW_FROM);
|
||||||
|
|
||||||
|
for (j = 0; j < w4_set.len; j++) {
|
||||||
|
// do not point to our base twice
|
||||||
|
if (w4_set.sw[j] == sw_set.sw[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// duplicate check and done_list
|
||||||
|
for (k = 0; k < *done_list_len; k++) {
|
||||||
|
if (done_list[k] == w4_set.sw[j])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (k < *done_list_len)
|
||||||
|
continue;
|
||||||
|
done_list[(*done_list_len)++] = w4_set.sw[j];
|
||||||
|
if (tstate->dry_run)
|
||||||
|
printf("done_list %s at %i\n",
|
||||||
|
fpga_switch_print(tstate->model,
|
||||||
|
y, x, done_list[(*done_list_len)-1]),
|
||||||
|
(*done_list_len)-1);
|
||||||
|
|
||||||
|
// base for len-4 target
|
||||||
|
if (tstate->dry_run)
|
||||||
|
fprintf_net(stdout, tstate->model, net);
|
||||||
|
rc = diff_printf(tstate);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
// add len-4 target
|
||||||
|
rc = fpga_net_add_sw(tstate->model, net, y, x,
|
||||||
|
&w4_set.sw[j], 1);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
if (tstate->dry_run)
|
||||||
|
fprintf_net(stdout, tstate->model, net);
|
||||||
|
rc = diff_printf(tstate);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
rc = fpga_net_remove_sw(tstate->model, net, y, x,
|
||||||
|
&w4_set.sw[j], 1);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
rc = fpga_net_remove_sw(tstate->model, net, y, x,
|
||||||
|
&sw_set.sw[i], 1);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_routing_sw_from_south(struct test_state* tstate,
|
||||||
|
swidx_t* done_list, int* done_list_len)
|
||||||
|
{
|
||||||
|
struct switch_to_yx switch_to;
|
||||||
|
int iob_y, iob_x, iob_type_idx, rc;
|
||||||
|
struct fpga_device* iob_dev;
|
||||||
|
net_idx_t net;
|
||||||
|
|
||||||
|
rc = fpga_find_iob(tstate->model, "P48", &iob_y, &iob_x, &iob_type_idx);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
rc = fdev_iob_output(tstate->model, iob_y, iob_x, iob_type_idx);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
iob_dev = fdev_p(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx);
|
||||||
|
if (!iob_dev) FAIL(EINVAL);
|
||||||
|
|
||||||
|
rc = fpga_net_new(tstate->model, &net);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
rc = fpga_net_add_port(tstate->model, net, iob_y, iob_x,
|
||||||
|
DEV_IOB, iob_type_idx, IOB_IN_O);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
switch_to.yx_req = YX_DEV_OLOGIC;
|
||||||
|
switch_to.flags = SWTO_YX_DEF;
|
||||||
|
switch_to.model = tstate->model;
|
||||||
|
switch_to.y = iob_y;
|
||||||
|
switch_to.x = iob_x;
|
||||||
|
switch_to.start_switch = iob_dev->pinw[IOB_IN_O];
|
||||||
|
switch_to.from_to = SW_TO;
|
||||||
|
rc = fpga_switch_to_yx(&switch_to);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
if (tstate->dry_run)
|
||||||
|
printf_switch_to_yx_result(&switch_to);
|
||||||
|
rc = fpga_net_add_sw(tstate->model, net, switch_to.y,
|
||||||
|
switch_to.x, switch_to.set.sw, switch_to.set.len);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
switch_to.yx_req = YX_ROUTING_TILE;
|
||||||
|
switch_to.flags = SWTO_YX_DEF;
|
||||||
|
switch_to.model = tstate->model;
|
||||||
|
switch_to.y = switch_to.dest_y;
|
||||||
|
switch_to.x = switch_to.dest_x;
|
||||||
|
switch_to.start_switch = switch_to.dest_connpt;
|
||||||
|
switch_to.from_to = SW_TO;
|
||||||
|
rc = fpga_switch_to_yx(&switch_to);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
rc = fpga_net_add_sw(tstate->model, net, switch_to.y,
|
||||||
|
switch_to.x, switch_to.set.sw, switch_to.set.len);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
if (tstate->dry_run)
|
||||||
|
printf_switch_to_yx_result(&switch_to);
|
||||||
|
|
||||||
|
switch_to.yx_req = YX_ROUTING_TO_FABLOGIC;
|
||||||
|
switch_to.flags = SWTO_YX_CLOSEST;
|
||||||
|
switch_to.model = tstate->model;
|
||||||
|
switch_to.y = switch_to.dest_y;
|
||||||
|
switch_to.x = switch_to.dest_x;
|
||||||
|
switch_to.start_switch = switch_to.dest_connpt;
|
||||||
|
switch_to.from_to = SW_TO;
|
||||||
|
rc = fpga_switch_to_yx(&switch_to);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
if (tstate->dry_run)
|
||||||
|
printf_switch_to_yx_result(&switch_to);
|
||||||
|
rc = fpga_net_add_sw(tstate->model, net, switch_to.y,
|
||||||
|
switch_to.x, switch_to.set.sw, switch_to.set.len);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
rc = test_switches(tstate, switch_to.dest_y, switch_to.dest_x,
|
||||||
|
switch_to.dest_connpt, net, done_list, done_list_len);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
fdev_delete(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx);
|
||||||
|
fpga_net_delete(tstate->model, net);
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_routing_sw_from_north(struct test_state* tstate,
|
||||||
|
swidx_t* done_list, int* done_list_len)
|
||||||
|
{
|
||||||
|
struct fpga_device* dev;
|
||||||
|
struct switch_to_rel swto;
|
||||||
|
struct sw_conns conns;
|
||||||
|
const char* str;
|
||||||
|
net_idx_t net;
|
||||||
|
int y, x, i, rc;
|
||||||
|
|
||||||
|
y = 67;
|
||||||
|
x = 13;
|
||||||
|
for (i = '1'; i <= '6'; i++) {
|
||||||
|
rc = fdev_logic_set_lut(tstate->model, y, x,
|
||||||
|
DEV_LOGM, LUT_A, 6, pf("A%c", i), ZTERM);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
rc = fdev_set_required_pins(tstate->model, y, x,
|
||||||
|
DEV_LOGIC, DEV_LOGM);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
if (tstate->dry_run)
|
||||||
|
fdev_print_required_pins(tstate->model,
|
||||||
|
y, x, DEV_LOGIC, DEV_LOGM);
|
||||||
|
dev = fdev_p(tstate->model, y, x, DEV_LOGIC, DEV_LOGM);
|
||||||
|
if (!dev) FAIL(EINVAL);
|
||||||
|
if (!dev->pinw_req_in) FAIL(EINVAL);
|
||||||
|
|
||||||
|
rc = fpga_net_new(tstate->model, &net);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
rc = fpga_net_add_port(tstate->model, net, y, x,
|
||||||
|
DEV_LOGIC, DEV_LOGM, dev->pinw_req_for_cfg[0]);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
swto.model = tstate->model;
|
||||||
|
swto.start_y = y;
|
||||||
|
swto.start_x = x;
|
||||||
|
swto.start_switch = fdev_logic_pinstr_i(tstate->model,
|
||||||
|
dev->pinw_req_for_cfg[0]|LD1, LOGIC_M);
|
||||||
|
swto.from_to = SW_TO;
|
||||||
|
swto.rel_y = 0;
|
||||||
|
swto.rel_x = -1;
|
||||||
|
swto.target_connpt = STRIDX_NO_ENTRY;
|
||||||
|
rc = fpga_switch_to_rel(&swto);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
if (!swto.set.len) FAIL(EINVAL);
|
||||||
|
if (tstate->dry_run)
|
||||||
|
printf_switch_to_rel_result(&swto);
|
||||||
|
rc = fpga_net_add_sw(tstate->model, net, swto.start_y,
|
||||||
|
swto.start_x, swto.set.sw, swto.set.len);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
rc = construct_sw_conns(&conns, tstate->model, swto.dest_y, swto.dest_x,
|
||||||
|
swto.dest_connpt, SW_TO, /*max_depth*/ 1);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
while (fpga_switch_conns(&conns) != NO_CONN) {
|
||||||
|
if (conns.dest_x != swto.dest_x
|
||||||
|
|| conns.dest_y != swto.dest_y+1)
|
||||||
|
continue;
|
||||||
|
str = strarray_lookup(&tstate->model->str, conns.dest_str_i);
|
||||||
|
if (!str) { HERE(); continue; }
|
||||||
|
if (strlen(str) < 5
|
||||||
|
|| str[2] != '1' || str[3] != 'B')
|
||||||
|
continue;
|
||||||
|
rc = fpga_net_add_sw(tstate->model, net, swto.dest_y,
|
||||||
|
swto.dest_x, conns.chain.set.sw, conns.chain.set.len);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
if (tstate->dry_run)
|
||||||
|
fprintf_net(stdout, tstate->model, net);
|
||||||
|
|
||||||
|
rc = test_switches(tstate, conns.dest_y, conns.dest_x,
|
||||||
|
conns.dest_str_i, net, done_list, done_list_len);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
rc = fpga_net_remove_sw(tstate->model, net, swto.dest_y,
|
||||||
|
swto.dest_x, conns.chain.set.sw, conns.chain.set.len);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
destruct_sw_conns(&conns);
|
||||||
|
fdev_delete(tstate->model, y, x, DEV_LOGIC, DEV_LOGM);
|
||||||
|
fpga_net_delete(tstate->model, net);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
// goal: use all switches in a routing switchbox
|
// goal: use all switches in a routing switchbox
|
||||||
static int test_logic_switches(struct test_state* tstate)
|
static int test_routing_switches(struct test_state* tstate)
|
||||||
{
|
{
|
||||||
int idx_enum[] = { DEV_LOGM, DEV_LOGX };
|
int idx_enum[] = { DEV_LOGM, DEV_LOGX };
|
||||||
int y, x, i, j, k, r, rc;
|
int y, x, i, j, k, r, rc;
|
||||||
|
@ -426,7 +676,6 @@ static int test_logic_switches(struct test_state* tstate)
|
||||||
|
|
||||||
y = 68;
|
y = 68;
|
||||||
x = 13;
|
x = 13;
|
||||||
|
|
||||||
done_sw_len = 0;
|
done_sw_len = 0;
|
||||||
for (r = 0; r <= 1; r++) {
|
for (r = 0; r <= 1; r++) {
|
||||||
// two rounds:
|
// two rounds:
|
||||||
|
@ -494,6 +743,11 @@ static int test_logic_switches(struct test_state* tstate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
done_sw_len = 0;
|
||||||
|
rc = test_routing_sw_from_south(tstate, done_sw_list, &done_sw_len);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
rc = test_routing_sw_from_north(tstate, done_sw_list, &done_sw_len);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -528,7 +782,7 @@ static int test_iologic_switches2(struct test_state* tstate, int iob_y, int iob_
|
||||||
rc = fpga_switch_to_yx(&switch_to);
|
rc = fpga_switch_to_yx(&switch_to);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
if (tstate->dry_run)
|
if (tstate->dry_run)
|
||||||
printf_switch_to_result(&switch_to);
|
printf_switch_to_yx_result(&switch_to);
|
||||||
|
|
||||||
if (construct_sw_chain(&chain, tstate->model, switch_to.dest_y,
|
if (construct_sw_chain(&chain, tstate->model, switch_to.dest_y,
|
||||||
switch_to.dest_x, switch_to.dest_connpt, from_to,
|
switch_to.dest_x, switch_to.dest_connpt, from_to,
|
||||||
|
@ -547,8 +801,7 @@ static int test_iologic_switches2(struct test_state* tstate, int iob_y, int iob_
|
||||||
|
|
||||||
// add iob port
|
// add iob port
|
||||||
rc = fpga_net_add_port(tstate->model, net_idx, iob_y, iob_x,
|
rc = fpga_net_add_port(tstate->model, net_idx, iob_y, iob_x,
|
||||||
fpga_dev_idx(tstate->model, iob_y, iob_x, DEV_IOB,
|
DEV_IOB, iob_type_idx, IOB_IN_O);
|
||||||
iob_type_idx), IOB_IN_O);
|
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
// add switch in iob tile
|
// add switch in iob tile
|
||||||
|
@ -643,7 +896,7 @@ int main(int argc, char** argv)
|
||||||
char param[1024], cmdline_test[1024];
|
char param[1024], cmdline_test[1024];
|
||||||
int i, param_skip, rc;
|
int i, param_skip, rc;
|
||||||
const char* available_tests[] =
|
const char* available_tests[] =
|
||||||
{ "logic_cfg", "logic_sw", "io_sw", 0 };
|
{ "logic_cfg", "routing_sw", "io_sw", 0 };
|
||||||
|
|
||||||
// flush after every line is better for the autotest
|
// flush after every line is better for the autotest
|
||||||
// output, tee, etc.
|
// output, tee, etc.
|
||||||
|
@ -755,8 +1008,8 @@ int main(int argc, char** argv)
|
||||||
rc = test_logic_config(&tstate);
|
rc = test_logic_config(&tstate);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
}
|
}
|
||||||
if (!strcmp(cmdline_test, "logic_sw")) {
|
if (!strcmp(cmdline_test, "routing_sw")) {
|
||||||
rc = test_logic_switches(&tstate);
|
rc = test_routing_switches(&tstate);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
}
|
}
|
||||||
if (!strcmp(cmdline_test, "io_sw")) {
|
if (!strcmp(cmdline_test, "io_sw")) {
|
||||||
|
|
135
control.c
135
control.c
|
@ -334,6 +334,54 @@ const char* fdev_logic_pinstr(pinw_idx_t idx, int ld1_type)
|
||||||
return buf[last_buf];
|
return buf[last_buf];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
str16_t fdev_logic_pinstr_i(struct fpga_model* model, pinw_idx_t idx, int ld1_type)
|
||||||
|
{
|
||||||
|
int str_i;
|
||||||
|
|
||||||
|
str_i = strarray_find(&model->str, fdev_logic_pinstr(idx, ld1_type));
|
||||||
|
if (OUT_OF_U16(str_i))
|
||||||
|
{ HERE(); return STRIDX_NO_ENTRY; }
|
||||||
|
return str_i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fdev_logic_inbit(pinw_idx_t idx, int ld1_type)
|
||||||
|
{
|
||||||
|
if (idx & LD1) {
|
||||||
|
idx &= ~LD1;
|
||||||
|
if (idx >= LI_A1 && idx <= LI_C6)
|
||||||
|
return M_A1 + (idx/6)*8+idx%6;
|
||||||
|
if (idx >= LI_D1 && idx <= LI_D6)
|
||||||
|
return M_D1 + (idx-LI_D1);
|
||||||
|
switch (idx) {
|
||||||
|
case LI_AX: return M_AX;
|
||||||
|
case LI_BX: return M_BX;
|
||||||
|
case LI_CE: return M_CE;
|
||||||
|
case LI_CX: return M_CX;
|
||||||
|
case LI_DX: return M_DX;
|
||||||
|
case LI_AI: return M_AI;
|
||||||
|
case LI_BI: return M_BI;
|
||||||
|
case LI_CI: return M_CI;
|
||||||
|
case LI_DI: return M_DI;
|
||||||
|
case LI_WE: return M_WE;
|
||||||
|
}
|
||||||
|
HERE();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (idx >= LI_A1 && idx <= LI_C6)
|
||||||
|
return X_A1 + (idx/6)*7+idx%6;
|
||||||
|
else if (idx >= LI_D1 && idx <= LI_D6)
|
||||||
|
return X_D1 + (idx-LI_D1);
|
||||||
|
else switch (idx) {
|
||||||
|
case LI_AX: return X_AX;
|
||||||
|
case LI_BX: return X_BX;
|
||||||
|
case LI_CE: return X_CE;
|
||||||
|
case LI_CX: return X_CX;
|
||||||
|
case LI_DX: return X_DX;
|
||||||
|
}
|
||||||
|
HERE();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static int reset_required_pins(struct fpga_device* dev)
|
static int reset_required_pins(struct fpga_device* dev)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -1453,7 +1501,7 @@ fail:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printf_switch_to_result(struct switch_to_yx* p)
|
void printf_switch_to_yx_result(struct switch_to_yx* p)
|
||||||
{
|
{
|
||||||
printf("switch_to_yx() from y%02i x%02i connpt %s (%s)\n",
|
printf("switch_to_yx() from y%02i x%02i connpt %s (%s)\n",
|
||||||
p->y, p->x, strarray_lookup(&p->model->str, p->start_switch),
|
p->y, p->x, strarray_lookup(&p->model->str, p->start_switch),
|
||||||
|
@ -1465,6 +1513,46 @@ void printf_switch_to_result(struct switch_to_yx* p)
|
||||||
fmt_swset(p->model, p->y, p->x, &p->set, p->from_to));
|
fmt_swset(p->model, p->y, p->x, &p->set, p->from_to));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fpga_switch_to_rel(struct switch_to_rel* p)
|
||||||
|
{
|
||||||
|
struct sw_conns conns;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = construct_sw_conns(&conns, p->model, p->start_y, p->start_x,
|
||||||
|
p->start_switch, p->from_to, SW_SET_SIZE);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
p->set.len = 0;
|
||||||
|
while (fpga_switch_conns(&conns) != NO_CONN) {
|
||||||
|
if (conns.dest_y != p->start_y + p->rel_y
|
||||||
|
|| conns.dest_x != p->start_x + p->rel_x)
|
||||||
|
continue;
|
||||||
|
if (p->target_connpt != STRIDX_NO_ENTRY
|
||||||
|
&& conns.dest_str_i != p->target_connpt)
|
||||||
|
continue;
|
||||||
|
p->set = conns.chain.set;
|
||||||
|
p->dest_y = conns.dest_y;
|
||||||
|
p->dest_x = conns.dest_x;
|
||||||
|
p->dest_connpt = conns.dest_str_i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
destruct_sw_conns(&conns);
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printf_switch_to_rel_result(struct switch_to_rel* p)
|
||||||
|
{
|
||||||
|
printf("switch_to_rel() from y%02i x%02i connpt %s (%s)\n",
|
||||||
|
p->start_y, p->start_x, strarray_lookup(&p->model->str, p->start_switch),
|
||||||
|
p->from_to == SW_FROM ? "SW_FROM" : "SW_TO");
|
||||||
|
printf(" %s y%02i x%02i %s via %s\n",
|
||||||
|
p->from_to == SW_FROM ? "to" : "from",
|
||||||
|
p->dest_y, p->dest_x,
|
||||||
|
strarray_lookup(&p->model->str, p->dest_connpt),
|
||||||
|
fmt_swset(p->model, p->start_y, p->start_x, &p->set, p->from_to));
|
||||||
|
}
|
||||||
|
|
||||||
#define NET_ALLOC_INCREMENT 64
|
#define NET_ALLOC_INCREMENT 64
|
||||||
|
|
||||||
static int fpga_net_useidx(struct fpga_model* model, net_idx_t new_idx)
|
static int fpga_net_useidx(struct fpga_model* model, net_idx_t new_idx)
|
||||||
|
@ -1551,7 +1639,8 @@ struct fpga_net* fpga_net_get(struct fpga_model* model, net_idx_t net_i)
|
||||||
}
|
}
|
||||||
|
|
||||||
int fpga_net_add_port(struct fpga_model* model, net_idx_t net_i,
|
int fpga_net_add_port(struct fpga_model* model, net_idx_t net_i,
|
||||||
int y, int x, dev_idx_t dev_idx, pinw_idx_t pinw_idx)
|
int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx,
|
||||||
|
pinw_idx_t pinw_idx)
|
||||||
{
|
{
|
||||||
struct fpga_net* net;
|
struct fpga_net* net;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -1565,7 +1654,8 @@ int fpga_net_add_port(struct fpga_model* model, net_idx_t net_i,
|
||||||
net->el[net->len].y = y;
|
net->el[net->len].y = y;
|
||||||
net->el[net->len].x = x;
|
net->el[net->len].x = x;
|
||||||
net->el[net->len].idx = pinw_idx | NET_IDX_IS_PINW;
|
net->el[net->len].idx = pinw_idx | NET_IDX_IS_PINW;
|
||||||
net->el[net->len].dev_idx = dev_idx;
|
net->el[net->len].dev_idx = fpga_dev_idx(model, y, x, type, type_idx);
|
||||||
|
if (net->el[net->len].dev_idx == NO_DEV) FAIL(EINVAL);
|
||||||
net->len++;
|
net->len++;
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
|
@ -1599,6 +1689,45 @@ fail:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fpga_net_remove_sw(struct fpga_model* model, net_idx_t net_i,
|
||||||
|
int y, int x, const swidx_t* switches, int num_sw)
|
||||||
|
{
|
||||||
|
struct fpga_net* net;
|
||||||
|
int i, j, rc;
|
||||||
|
|
||||||
|
if (net_i > model->highest_used_net)
|
||||||
|
FAIL(EINVAL);
|
||||||
|
net = &model->nets[net_i-1];
|
||||||
|
if (!net->len) {
|
||||||
|
HERE();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i < num_sw; i++) {
|
||||||
|
for (j = 0; j < net->len; j++) {
|
||||||
|
if (net->el[j].y == y
|
||||||
|
&& net->el[j].x == x
|
||||||
|
&& net->el[j].idx == switches[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (j >= net->len) {
|
||||||
|
// for now we expect the 'to-be-removed'
|
||||||
|
// switches to be in the net
|
||||||
|
HERE();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!fpga_switch_is_used(model, y, x, switches[i]))
|
||||||
|
HERE();
|
||||||
|
fpga_switch_disable(model, y, x, switches[i]);
|
||||||
|
if (net->len > j+1)
|
||||||
|
memmove(&net->el[j], &net->el[j+1],
|
||||||
|
(net->len-j-1)*sizeof(net->el[0]));
|
||||||
|
net->len--;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
void fpga_net_free_all(struct fpga_model* model)
|
void fpga_net_free_all(struct fpga_model* model)
|
||||||
{
|
{
|
||||||
free(model->nets);
|
free(model->nets);
|
||||||
|
|
35
control.h
35
control.h
|
@ -38,9 +38,13 @@ dev_type_idx_t fdev_typeidx(struct fpga_model* model, int y, int x,
|
||||||
pinw_idx_t fdev_pinw_str2idx(int devtype, const char* str, int len);
|
pinw_idx_t fdev_pinw_str2idx(int devtype, const char* str, int len);
|
||||||
// returns 0 when idx not found for the given devtype
|
// returns 0 when idx not found for the given devtype
|
||||||
const char* fdev_pinw_idx2str(int devtype, pinw_idx_t idx);
|
const char* fdev_pinw_idx2str(int devtype, pinw_idx_t idx);
|
||||||
|
|
||||||
// ld1_type can be LOGIC_M or LOGIC_L to specify whether
|
// ld1_type can be LOGIC_M or LOGIC_L to specify whether
|
||||||
// we are in a XM or XL column.
|
// we are in a XM or XL column. You can |LD1 to idx for
|
||||||
|
// the second logic device (L or M).
|
||||||
const char* fdev_logic_pinstr(pinw_idx_t idx, int ld1_type);
|
const char* fdev_logic_pinstr(pinw_idx_t idx, int ld1_type);
|
||||||
|
str16_t fdev_logic_pinstr_i(struct fpga_model* model, pinw_idx_t idx, int ld1_type);
|
||||||
|
int fdev_logic_inbit(pinw_idx_t idx, int ld1_type);
|
||||||
|
|
||||||
// lut_a2d is LUT_A to LUT_D value, lut_5or6 is int 5 or int 6.
|
// lut_a2d is LUT_A to LUT_D value, lut_5or6 is int 5 or int 6.
|
||||||
int fdev_logic_set_lut(struct fpga_model* model, int y, int x, int type_idx,
|
int fdev_logic_set_lut(struct fpga_model* model, int y, int x, int type_idx,
|
||||||
|
@ -247,7 +251,30 @@ struct switch_to_yx
|
||||||
};
|
};
|
||||||
|
|
||||||
int fpga_switch_to_yx(struct switch_to_yx* p);
|
int fpga_switch_to_yx(struct switch_to_yx* p);
|
||||||
void printf_switch_to_result(struct switch_to_yx* p);
|
void printf_switch_to_yx_result(struct switch_to_yx* p);
|
||||||
|
|
||||||
|
struct switch_to_rel
|
||||||
|
{
|
||||||
|
// input:
|
||||||
|
struct fpga_model* model;
|
||||||
|
int start_y;
|
||||||
|
int start_x;
|
||||||
|
str16_t start_switch;
|
||||||
|
int from_to;
|
||||||
|
int rel_y;
|
||||||
|
int rel_x;
|
||||||
|
str16_t target_connpt; // can be STRIDX_NO_ENTRY
|
||||||
|
|
||||||
|
// output:
|
||||||
|
struct sw_set set;
|
||||||
|
int dest_y;
|
||||||
|
int dest_x;
|
||||||
|
str16_t dest_connpt;
|
||||||
|
};
|
||||||
|
|
||||||
|
// if no switches are found, the returned set.len will be 0.
|
||||||
|
int fpga_switch_to_rel(struct switch_to_rel* p);
|
||||||
|
void printf_switch_to_rel_result(struct switch_to_rel* p);
|
||||||
|
|
||||||
//
|
//
|
||||||
// nets
|
// nets
|
||||||
|
@ -289,9 +316,11 @@ void fpga_net_delete(struct fpga_model* model, net_idx_t net_idx);
|
||||||
int fpga_net_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next);
|
int fpga_net_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next);
|
||||||
struct fpga_net* fpga_net_get(struct fpga_model* model, net_idx_t net_i);
|
struct fpga_net* fpga_net_get(struct fpga_model* model, net_idx_t net_i);
|
||||||
int fpga_net_add_port(struct fpga_model* model, net_idx_t net_i,
|
int fpga_net_add_port(struct fpga_model* model, net_idx_t net_i,
|
||||||
int y, int x, dev_idx_t dev_idx, pinw_idx_t pinw_idx);
|
int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx, pinw_idx_t pinw_idx);
|
||||||
int fpga_net_add_sw(struct fpga_model* model, net_idx_t net_i,
|
int fpga_net_add_sw(struct fpga_model* model, net_idx_t net_i,
|
||||||
int y, int x, const swidx_t* switches, int num_sw);
|
int y, int x, const swidx_t* switches, int num_sw);
|
||||||
|
int fpga_net_remove_sw(struct fpga_model* model, net_idx_t net_i,
|
||||||
|
int y, int x, const swidx_t* switches, int num_sw);
|
||||||
void fpga_net_free_all(struct fpga_model* model);
|
void fpga_net_free_all(struct fpga_model* model);
|
||||||
|
|
||||||
void fprintf_net(FILE* f, struct fpga_model* model, net_idx_t net_i);
|
void fprintf_net(FILE* f, struct fpga_model* model, net_idx_t net_i);
|
||||||
|
|
|
@ -775,7 +775,6 @@ static void read_net_line(struct fpga_model* model, const char* line, int start)
|
||||||
enum fpgadev_type dev_type;
|
enum fpgadev_type dev_type;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
net_idx_t net_idx;
|
net_idx_t net_idx;
|
||||||
dev_idx_t dev_idx;
|
|
||||||
pinw_idx_t pinw_idx;
|
pinw_idx_t pinw_idx;
|
||||||
int sw_is_bidir;
|
int sw_is_bidir;
|
||||||
|
|
||||||
|
@ -872,14 +871,12 @@ static void read_net_line(struct fpga_model* model, const char* line, int start)
|
||||||
{ HERE(); return; }
|
{ HERE(); return; }
|
||||||
dev_type = fdev_str2type(&line[dev_str_beg], dev_str_end-dev_str_beg);
|
dev_type = fdev_str2type(&line[dev_str_beg], dev_str_end-dev_str_beg);
|
||||||
if (dev_type == DEV_NONE) { HERE(); return; }
|
if (dev_type == DEV_NONE) { HERE(); return; }
|
||||||
dev_idx = fpga_dev_idx(model, y_coord, x_coord, dev_type,
|
|
||||||
to_i(&line[dev_type_idx_str_beg],
|
|
||||||
dev_type_idx_str_end-dev_type_idx_str_beg));
|
|
||||||
if (dev_idx == NO_DEV) { HERE(); return; }
|
|
||||||
pinw_idx = fdev_pinw_str2idx(dev_type, &line[pin_name_beg],
|
pinw_idx = fdev_pinw_str2idx(dev_type, &line[pin_name_beg],
|
||||||
pin_name_end-pin_name_beg);
|
pin_name_end-pin_name_beg);
|
||||||
if (pinw_idx == PINW_NO_IDX) { HERE(); return; }
|
if (pinw_idx == PINW_NO_IDX) { HERE(); return; }
|
||||||
if (fpga_net_add_port(model, net_idx, y_coord, x_coord, dev_idx, pinw_idx))
|
if (fpga_net_add_port(model, net_idx, y_coord, x_coord, dev_type,
|
||||||
|
to_i(&line[dev_type_idx_str_beg], dev_type_idx_str_end
|
||||||
|
-dev_type_idx_str_beg), pinw_idx))
|
||||||
HERE();
|
HERE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
419
model_conns.c
419
model_conns.c
|
@ -1767,153 +1767,210 @@ static int run_direction_wires(struct fpga_model* model)
|
||||||
int x, y, i, j, _row_num, _row_pos, rc;
|
int x, y, i, j, _row_num, _row_pos, rc;
|
||||||
struct w_net net;
|
struct w_net net;
|
||||||
|
|
||||||
// SS4
|
// todo: EL1, ER1, WR1, WL1
|
||||||
|
|
||||||
|
// SR1
|
||||||
for (x = 0; x < model->x_width; x++) {
|
for (x = 0; x < model->x_width; x++) {
|
||||||
if (!is_atx(X_ROUTING_COL, model, x))
|
if (!is_atx(X_ROUTING_COL, model, x))
|
||||||
continue;
|
continue;
|
||||||
// some wiring at the top
|
for (y = TOP_OUTER_IO; y <= model->y_height-BOT_OUTER_IO; y++) {
|
||||||
net.last_inc = 3;
|
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y))
|
||||||
for (i = 1; i < 5; i++) { // go through "BAMCE"
|
|
||||||
net.pts[0].start_count = 0;
|
|
||||||
net.pts[0].y = TOP_TERM(model);
|
|
||||||
net.pts[0].x = x;
|
|
||||||
net.pts[0].name = pf("SS4%c%%i", s_4wire[i]);
|
|
||||||
for (j = i; j < 5; j++) {
|
|
||||||
net.pts[j-i+1].start_count = 0;
|
|
||||||
net.pts[j-i+1].y = TOP_TERM(model)+(j-i+1);
|
|
||||||
net.pts[j-i+1].x = x;
|
|
||||||
net.pts[j-i+1].name = pf("SS4%c%%i", s_4wire[j]);
|
|
||||||
}
|
|
||||||
net.pts[j-i+1].name = "";
|
|
||||||
if ((rc = add_conn_net(model, PREF_BI_F, &net))) goto xout;
|
|
||||||
if ((rc = wire_SS4E_N3(model, &net))) goto xout;
|
|
||||||
}
|
|
||||||
// rest going down to bottom termination
|
|
||||||
for (y = 0; y < model->y_height; y++) {
|
|
||||||
is_in_row(model, y, &_row_num, &_row_pos);
|
|
||||||
if (is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)
|
|
||||||
&& y > BOT_TERM(model)-5)
|
|
||||||
break;
|
|
||||||
if (_row_pos < 0 || _row_pos == 8)
|
|
||||||
continue;
|
continue;
|
||||||
|
if (is_aty(Y_INNER_BOTTOM, model, y+1)) {
|
||||||
net.last_inc = 3;
|
if (!is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
||||||
j = 0;
|
{ struct w_net n = {
|
||||||
for (i = 0; i < 5; i++) { // go through "BAMCE"
|
3,
|
||||||
net.pts[j].start_count = 0;
|
{{ "SR1B%i", 0, y, x },
|
||||||
net.pts[j].y = y+j;
|
{ "SR1B%i", 0, y+1, x },
|
||||||
net.pts[j].x = x;
|
{ "" }}};
|
||||||
if (y+j == BOT_TERM(model)) {
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
EXIT(!i);
|
if ((rc = add_conn_bi_pref(model, y, x, "SR1E_N3", y+1, x, "SR1E_N3"))) goto xout;
|
||||||
net.pts[j].name = pf("SS4%c%%i", s_4wire[i-1]);
|
|
||||||
j++;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (IS_CENTER_Y(y+j, model)
|
continue;
|
||||||
|| pos_in_row(y+j, model) == HCLK_POS) {
|
}
|
||||||
EXIT(!i);
|
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y+1)) {
|
||||||
net.pts[j].name = pf("SS4%c%%i", s_4wire[i-1]);
|
{ struct w_net n = {
|
||||||
j++;
|
3,
|
||||||
net.pts[j].start_count = 0;
|
{{ "SR1B%i", 0, y, x },
|
||||||
net.pts[j].y = y+j;
|
{ "SR1B%i", 0, y+1, x },
|
||||||
net.pts[j].x = x;
|
{ "SR1E%i", 0, y+2, x },
|
||||||
}
|
{ "" }}};
|
||||||
net.pts[j].name = pf("SS4%c%%i", s_4wire[i]);
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
j++;
|
{ struct w_net n = {
|
||||||
|
0,
|
||||||
|
{{ "SR1E_N3", 0, y, x },
|
||||||
|
{ "SR1E_N3", 0, y+1, x },
|
||||||
|
{ "SR1E3", 0, y+2, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
|
if ((rc = add_conn_bi_pref(model, y+1, x, "SR1E_N3", y, x, "SR1B3"))) goto xout;
|
||||||
|
if ((rc = add_conn_bi_pref(model, y+1, x, "SR1B3", y, x, "SR1E_N3"))) goto xout;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
{ struct w_net n = {
|
||||||
|
3,
|
||||||
|
{{ "SR1B%i", 0, y, x },
|
||||||
|
{ "SR1E%i", 0, y+1, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
|
if ((rc = add_conn_bi_pref(model, y+1, x, "SR1E3", y, x, "SR1E_N3"))) goto xout;
|
||||||
|
if (is_aty(Y_INNER_TOP, model, y-1)) {
|
||||||
|
{ struct w_net n = {
|
||||||
|
3,
|
||||||
|
{{ "SR1E%i", 0, y-1, x },
|
||||||
|
{ "SR1E%i", 0, y, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
|
if ((rc = add_conn_bi_pref(model, y, x, "SR1E3", y-1, x, "SR1E_N3"))) goto xout;
|
||||||
}
|
}
|
||||||
net.pts[j].name = "";
|
|
||||||
if ((rc = add_conn_net(model, PREF_BI_F, &net))) goto xout;
|
|
||||||
if ((rc = wire_SS4E_N3(model, &net))) goto xout;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NN4
|
// NL1
|
||||||
for (x = 0; x < model->x_width; x++) {
|
for (x = 0; x < model->x_width; x++) {
|
||||||
if (!is_atx(X_ROUTING_COL, model, x))
|
if (!is_atx(X_ROUTING_COL, model, x))
|
||||||
continue;
|
continue;
|
||||||
for (y = 0; y < model->y_height; y++) {
|
for (y = TOP_OUTER_IO; y <= model->y_height-BOT_OUTER_IO; y++) {
|
||||||
is_in_row(model, y, &_row_num, &_row_pos);
|
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y))
|
||||||
if (_row_pos >= 0 && _row_pos != 8) {
|
continue;
|
||||||
net.last_inc = 3;
|
if (is_aty(Y_INNER_TOP, model, y-1)) {
|
||||||
j = 0;
|
{ struct w_net n = {
|
||||||
for (i = 0; i < 5; i++) { // go through "BAMCE"
|
3,
|
||||||
net.pts[j].start_count = 0;
|
{{ "NL1B%i", 0, y-1, x },
|
||||||
net.pts[j].y = y-j;
|
{ "NL1B%i", 0, y, x },
|
||||||
net.pts[j].x = x;
|
{ "" }}};
|
||||||
if (y-j == TOP_INNER_ROW) {
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
EXIT(!i);
|
if ((rc = add_conn_bi_pref(model, y, x, "NL1E_S0", y-1, x, "NL1E_S0"))) goto xout;
|
||||||
net.pts[j].name = pf("NN4%c%%i", s_4wire[i-1]);
|
continue;
|
||||||
j++;
|
}
|
||||||
break;
|
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y-1)) {
|
||||||
}
|
{ struct w_net n = {
|
||||||
net.pts[j].name = pf("NN4%c%%i", s_4wire[i]);
|
3,
|
||||||
if (IS_CENTER_Y(y-j, model)
|
{{ "NL1E%i", 0, y-2, x },
|
||||||
|| pos_in_row(y-j, model) == HCLK_POS) {
|
{ "NL1E%i", 0, y-1, x },
|
||||||
EXIT(!i);
|
{ "NL1B%i", 0, y, x },
|
||||||
i--;
|
{ "" }}};
|
||||||
}
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
j++;
|
{ struct w_net n = {
|
||||||
}
|
0,
|
||||||
net.pts[j].name = "";
|
{{ "NL1E0", 0, y-2, x },
|
||||||
if ((rc = add_conn_net(model, PREF_BI_F, &net))) goto xout;
|
{ "NL1E_S0", 0, y-1, x },
|
||||||
|
{ "NL1E_S0", 0, y, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
|
if ((rc = add_conn_bi_pref(model, y-1, x, "NL1E_S0", y, x, "NL1B0"))) goto xout;
|
||||||
|
if ((rc = add_conn_bi_pref(model, y-1, x, "NL1E0", y, x, "NL1E_S0"))) goto xout;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
{ struct w_net n = {
|
||||||
|
3,
|
||||||
|
{{ "NL1E%i", 0, y-1, x },
|
||||||
|
{ "NL1B%i", 0, y, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
|
if ((rc = add_conn_bi_pref(model, y-1, x, "NL1E0", y, x, "NL1E_S0"))) goto xout;
|
||||||
|
if (is_aty(Y_INNER_BOTTOM, model, y+1) && !is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
||||||
|
{ struct w_net n = {
|
||||||
|
3,
|
||||||
|
{{ "NL1E%i", 0, y, x },
|
||||||
|
{ "NL1E%i", 0, y+1, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
|
if ((rc = add_conn_bi_pref(model, y, x, "NL1E0", y+1, x, "NL1E_S0"))) goto xout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
}
|
||||||
net.last_inc = 3;
|
|
||||||
for (i = 1; i < 5; i++) { // go through "BAMCE"
|
// SL1
|
||||||
net.pts[0].start_count = 0;
|
for (x = 0; x < model->x_width; x++) {
|
||||||
net.pts[0].y = BOT_TERM(model);
|
if (!is_atx(X_ROUTING_COL, model, x))
|
||||||
net.pts[0].x = x;
|
continue;
|
||||||
net.pts[0].name = pf("NN4%c%%i", s_4wire[i]);
|
for (y = TOP_OUTER_IO; y <= model->y_height-BOT_OUTER_IO; y++) {
|
||||||
for (j = i; j < 5; j++) {
|
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y))
|
||||||
net.pts[j-i+1].start_count = 0;
|
continue;
|
||||||
net.pts[j-i+1].y = BOT_TERM(model)-(j-i+1);
|
if (is_aty(Y_INNER_BOTTOM, model, y+1)) {
|
||||||
net.pts[j-i+1].x = x;
|
if (!is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
||||||
net.pts[j-i+1].name = pf("NN4%c%%i", s_4wire[j]);
|
{ struct w_net n = {
|
||||||
|
3,
|
||||||
|
{{ "SL1B%i", 0, y, x },
|
||||||
|
{ "SL1B%i", 0, y+1, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
}
|
}
|
||||||
net.pts[j-i+1].name = "";
|
continue;
|
||||||
if ((rc = add_conn_net(model, PREF_BI_F, &net))) goto xout;
|
}
|
||||||
|
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y+1)) {
|
||||||
|
{ struct w_net n = {
|
||||||
|
3,
|
||||||
|
{{ "SL1B%i", 0, y, x },
|
||||||
|
{ "SL1B%i", 0, y+1, x },
|
||||||
|
{ "SL1E%i", 0, y+2, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
{ struct w_net n = {
|
||||||
|
3,
|
||||||
|
{{ "SL1B%i", 0, y, x },
|
||||||
|
{ "SL1E%i", 0, y+1, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
|
if (is_aty(Y_INNER_TOP, model, y-1)) {
|
||||||
|
{ struct w_net n = {
|
||||||
|
3,
|
||||||
|
{{ "SL1E%i", 0, y-1, x },
|
||||||
|
{ "SL1E%i", 0, y, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NR1
|
||||||
|
for (x = 0; x < model->x_width; x++) {
|
||||||
|
if (!is_atx(X_ROUTING_COL, model, x))
|
||||||
|
continue;
|
||||||
|
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;
|
||||||
|
if (is_aty(Y_INNER_TOP, model, y-1)) {
|
||||||
|
{ struct w_net n = {
|
||||||
|
3,
|
||||||
|
{{ "NR1B%i", 0, y, x },
|
||||||
|
{ "NR1B%i", 0, y-1, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y-1)) {
|
||||||
|
{ struct w_net n = {
|
||||||
|
3,
|
||||||
|
{{ "NR1B%i", 0, y, x },
|
||||||
|
{ "NR1E%i", 0, y-1, x },
|
||||||
|
{ "NR1E%i", 0, y-2, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
{ struct w_net n = {
|
||||||
|
3,
|
||||||
|
{{ "NR1B%i", 0, y, x },
|
||||||
|
{ "NR1E%i", 0, y-1, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
|
if (is_aty(Y_INNER_BOTTOM, model, y+1) && !is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
||||||
|
{ struct w_net n = {
|
||||||
|
3,
|
||||||
|
{{ "NR1E%i", 0, y, x },
|
||||||
|
{ "NR1E%i", 0, y+1, x },
|
||||||
|
{ "" }}};
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = 0; y < model->y_height; y++) {
|
for (y = 0; y < model->y_height; y++) {
|
||||||
for (x = 0; x < model->x_width; x++) {
|
for (x = 0; x < model->x_width; x++) {
|
||||||
// NR1
|
|
||||||
if (is_atyx(YX_ROUTING_TILE, model, y, x)) {
|
|
||||||
if (is_aty(Y_INNER_TOP, model, y-1)) {
|
|
||||||
{ struct w_net n = {
|
|
||||||
3,
|
|
||||||
{{ "NR1B%i", 0, y, x },
|
|
||||||
{ "NR1B%i", 0, y-1, x },
|
|
||||||
{ "" }}};
|
|
||||||
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
|
||||||
} else if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, model, y-1)) {
|
|
||||||
{ struct w_net n = {
|
|
||||||
3,
|
|
||||||
{{ "NR1B%i", 0, y, x },
|
|
||||||
{ "NR1E%i", 0, y-1, x },
|
|
||||||
{ "NR1E%i", 0, y-2, x },
|
|
||||||
{ "" }}};
|
|
||||||
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
|
||||||
} else {
|
|
||||||
{ struct w_net n = {
|
|
||||||
3,
|
|
||||||
{{ "NR1B%i", 0, y, x },
|
|
||||||
{ "NR1E%i", 0, y-1, x },
|
|
||||||
{ "" }}};
|
|
||||||
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
|
||||||
if (is_aty(Y_INNER_BOTTOM, model, y+1) && !is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
|
||||||
{ struct w_net n = {
|
|
||||||
3,
|
|
||||||
{{ "NR1E%i", 0, y, x },
|
|
||||||
{ "NR1E%i", 0, y+1, x },
|
|
||||||
{ "" }}};
|
|
||||||
if ((rc = add_conn_net(model, PREF_BI_F, &n))) goto xout; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NN2
|
// NN2
|
||||||
if (is_atyx(YX_ROUTING_TILE, model, y, x)) {
|
if (is_atyx(YX_ROUTING_TILE, model, y, x)) {
|
||||||
if (is_aty(Y_INNER_TOP, model, y-1)) {
|
if (is_aty(Y_INNER_TOP, model, y-1)) {
|
||||||
|
@ -2067,6 +2124,116 @@ static int run_direction_wires(struct fpga_model* model)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SS4
|
||||||
|
for (x = 0; x < model->x_width; x++) {
|
||||||
|
if (!is_atx(X_ROUTING_COL, model, x))
|
||||||
|
continue;
|
||||||
|
// some wiring at the top
|
||||||
|
net.last_inc = 3;
|
||||||
|
for (i = 1; i < 5; i++) { // go through "BAMCE"
|
||||||
|
net.pts[0].start_count = 0;
|
||||||
|
net.pts[0].y = TOP_TERM(model);
|
||||||
|
net.pts[0].x = x;
|
||||||
|
net.pts[0].name = pf("SS4%c%%i", s_4wire[i]);
|
||||||
|
for (j = i; j < 5; j++) {
|
||||||
|
net.pts[j-i+1].start_count = 0;
|
||||||
|
net.pts[j-i+1].y = TOP_TERM(model)+(j-i+1);
|
||||||
|
net.pts[j-i+1].x = x;
|
||||||
|
net.pts[j-i+1].name = pf("SS4%c%%i", s_4wire[j]);
|
||||||
|
}
|
||||||
|
net.pts[j-i+1].name = "";
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &net))) goto xout;
|
||||||
|
if ((rc = wire_SS4E_N3(model, &net))) goto xout;
|
||||||
|
}
|
||||||
|
// rest going down to bottom termination
|
||||||
|
for (y = 0; y < model->y_height; y++) {
|
||||||
|
is_in_row(model, y, &_row_num, &_row_pos);
|
||||||
|
if (is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)
|
||||||
|
&& y > BOT_TERM(model)-5)
|
||||||
|
break;
|
||||||
|
if (_row_pos < 0 || _row_pos == 8)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
net.last_inc = 3;
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < 5; i++) { // go through "BAMCE"
|
||||||
|
net.pts[j].start_count = 0;
|
||||||
|
net.pts[j].y = y+j;
|
||||||
|
net.pts[j].x = x;
|
||||||
|
if (y+j == BOT_TERM(model)) {
|
||||||
|
EXIT(!i);
|
||||||
|
net.pts[j].name = pf("SS4%c%%i", s_4wire[i-1]);
|
||||||
|
j++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (IS_CENTER_Y(y+j, model)
|
||||||
|
|| pos_in_row(y+j, model) == HCLK_POS) {
|
||||||
|
EXIT(!i);
|
||||||
|
net.pts[j].name = pf("SS4%c%%i", s_4wire[i-1]);
|
||||||
|
j++;
|
||||||
|
net.pts[j].start_count = 0;
|
||||||
|
net.pts[j].y = y+j;
|
||||||
|
net.pts[j].x = x;
|
||||||
|
}
|
||||||
|
net.pts[j].name = pf("SS4%c%%i", s_4wire[i]);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
net.pts[j].name = "";
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &net))) goto xout;
|
||||||
|
if ((rc = wire_SS4E_N3(model, &net))) goto xout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NN4
|
||||||
|
for (x = 0; x < model->x_width; x++) {
|
||||||
|
if (!is_atx(X_ROUTING_COL, model, x))
|
||||||
|
continue;
|
||||||
|
for (y = 0; y < model->y_height; y++) {
|
||||||
|
is_in_row(model, y, &_row_num, &_row_pos);
|
||||||
|
if (_row_pos >= 0 && _row_pos != 8) {
|
||||||
|
net.last_inc = 3;
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < 5; i++) { // go through "BAMCE"
|
||||||
|
net.pts[j].start_count = 0;
|
||||||
|
net.pts[j].y = y-j;
|
||||||
|
net.pts[j].x = x;
|
||||||
|
if (y-j == TOP_INNER_ROW) {
|
||||||
|
EXIT(!i);
|
||||||
|
net.pts[j].name = pf("NN4%c%%i", s_4wire[i-1]);
|
||||||
|
j++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
net.pts[j].name = pf("NN4%c%%i", s_4wire[i]);
|
||||||
|
if (IS_CENTER_Y(y-j, model)
|
||||||
|
|| pos_in_row(y-j, model) == HCLK_POS) {
|
||||||
|
EXIT(!i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
net.pts[j].name = "";
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &net))) goto xout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
|
||||||
|
net.last_inc = 3;
|
||||||
|
for (i = 1; i < 5; i++) { // go through "BAMCE"
|
||||||
|
net.pts[0].start_count = 0;
|
||||||
|
net.pts[0].y = BOT_TERM(model);
|
||||||
|
net.pts[0].x = x;
|
||||||
|
net.pts[0].name = pf("NN4%c%%i", s_4wire[i]);
|
||||||
|
for (j = i; j < 5; j++) {
|
||||||
|
net.pts[j-i+1].start_count = 0;
|
||||||
|
net.pts[j-i+1].y = BOT_TERM(model)-(j-i+1);
|
||||||
|
net.pts[j-i+1].x = x;
|
||||||
|
net.pts[j-i+1].name = pf("NN4%c%%i", s_4wire[j]);
|
||||||
|
}
|
||||||
|
net.pts[j-i+1].name = "";
|
||||||
|
if ((rc = add_conn_net(model, PREF_BI_F, &net))) goto xout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
xout:
|
xout:
|
||||||
return rc;
|
return rc;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user