more routing

This commit is contained in:
Wolfgang Spraul 2012-12-19 02:53:21 -05:00
parent 339684cc68
commit 25cb653c2e
4 changed files with 181 additions and 16 deletions

View File

@ -117,43 +117,68 @@ int main(int argc, char** argv)
fnet_new(&model, &net);
fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_A6);
fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_B6);
fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_C6);
fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_D6);
fnet_vcc_gnd(&model, net, /*is_vcc*/ 1);
fnet_new(&model, &net);
fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_A6);
fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_B6);
fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_C6);
fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_D6);
fnet_vcc_gnd(&model, net, /*is_vcc*/ 1);
fnet_new(&model, &net);
fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_A6);
fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_B6);
fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_C6);
fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_D6);
fnet_vcc_gnd(&model, net, /*is_vcc*/ 1);
fnet_new(&model, &net);
fnet_add_port(&model, net, 58, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_A6);
fnet_add_port(&model, net, 58, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_B6);
fnet_add_port(&model, net, 58, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_C6);
fnet_add_port(&model, net, 58, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_D6);
fnet_vcc_gnd(&model, net, /*is_vcc*/ 1);
// carry chain
#if 0
fnet_new(&model, &net);
fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LO_COUT);
fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CIN);
fnet_route(&model, net);
fnet_new(&model, &net);
fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CIN);
fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LO_COUT);
fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CIN);
fnet_route(&model, net);
fnet_new(&model, &net);
fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CIN);
fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LO_COUT);
fnet_add_port(&model, net, 58, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CIN);
fnet_route(&model, net);
#endif
fnet_new(&model, &net);
fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CIN);
fnet_add_port(&model, net, 58, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LO_COUT);
fnet_route(&model, net);
// bit chain
{
int out_pin[] = {LO_AQ, LO_BQ, LO_CQ, LO_DQ};
int in_pin[] = {LI_A5, LI_B5, LI_C5, LI_D5};
int cur_y, i;
for (cur_y = 58; cur_y >= 55; cur_y--) {
for (i = 0; i < 4; i++) {
if (cur_y == 55 && i >= 2)
break;
fnet_new(&model, &net);
fnet_add_port(&model, net, cur_y, 13, DEV_LOGIC, DEV_LOG_M_OR_L, out_pin[i]);
fnet_add_port(&model, net, cur_y, 13, DEV_LOGIC, DEV_LOG_M_OR_L, in_pin[i]);
fnet_route(&model, net);
}
}
}
fnet_new(&model, &net);
fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LO_CQ);
fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_C5);
// fnet_add_port(&model, net, iob_led_y, iob_led_x, DEV_IOB,
// iob_led_type_idx, IOB_IN_O);
fnet_route(&model, net);
write_floorplan(stdout, &model, FP_DEFAULT);
return fpga_free_model(&model);

View File

@ -2765,7 +2765,7 @@ static int write_logic(struct fpga_bits* bits, struct fpga_model* model)
}
// Except for XC6_ML_CIN_USED (which is set by a switch elsewhere),
// everything else should be 0.
if (mi20 || mi23_M || (mi2526 & ~XC6_ML_CIN_USED)
if (mi20 || mi23_M || (mi2526 & ~(1ULL<<XC6_ML_CIN_USED))
|| lut_ML[LUT_A] || lut_ML[LUT_B] || lut_ML[LUT_C] || lut_ML[LUT_D]
|| lut_X[LUT_A] || lut_X[LUT_B] || lut_X[LUT_C] || lut_X[LUT_D]) {
HERE();

View File

@ -12,6 +12,7 @@
#undef DBG_SWITCH_CONNS
#undef DBG_SWITCH_TO_YX
#undef DBG_SWITCH_TO_REL
#undef DBG_SWITCH_2SETS
struct iob_site
{
@ -1843,6 +1844,29 @@ void destruct_sw_conns(struct sw_conns* conns)
memset(conns, 0, sizeof(*conns));
}
int fpga_multi_switch_lookup(struct fpga_model *model, int y, int x,
str16_t from_sw, str16_t to_sw, int max_depth, net_idx_t exclusive_net,
struct sw_set *sw_set)
{
struct sw_chain sw_chain;
sw_set->len = 0;
construct_sw_chain(&sw_chain, model, y, x, from_sw, SW_FROM, max_depth,
exclusive_net, /*block_list*/ 0, /*block_list_len*/ 0);
RC_CHECK(model);
while (fpga_switch_chain(&sw_chain) != NO_CONN) {
RC_ASSERT(model, sw_chain.set.len);
if (fpga_switch_str_i(model, y, x, sw_chain.set.sw[sw_chain.set.len-1],
SW_TO) == to_sw) {
*sw_set = sw_chain.set;
break;
}
}
destruct_sw_chain(&sw_chain);
RC_RETURN(model);
}
int fpga_switch_conns(struct sw_conns* conns)
{
str16_t end_of_chain_str;
@ -1898,6 +1922,26 @@ internal_error:
return NO_CONN;
}
int fpga_first_conn(struct fpga_model *model, int sw_y, int sw_x, str16_t sw_str,
int from_to, int max_depth, net_idx_t exclusive_net,
struct sw_set *sw_set, int *dest_y, int *dest_x, str16_t *dest_connpt)
{
struct sw_conns sw_conns;
construct_sw_conns(&sw_conns, model, sw_y, sw_x, sw_str, from_to,
max_depth, exclusive_net);
RC_CHECK(model);
if (fpga_switch_conns(&sw_conns) == NO_CONN)
RC_FAIL(model, EINVAL);
*sw_set = sw_conns.chain.set;
*dest_y = sw_conns.dest_y;
*dest_x = sw_conns.dest_x;
*dest_connpt = sw_conns.dest_str_i;
destruct_sw_conns(&sw_conns);
RC_RETURN(model);
}
void printf_swchain(struct fpga_model* model, int y, int x,
str16_t sw, int from_to, int max_depth, swidx_t* block_list,
int* block_list_len)
@ -2303,6 +2347,9 @@ int fnet_add_sw(struct fpga_model* model, net_idx_t net_i,
net = &model->nets[net_i-1];
for (i = 0; i < num_sw; i++) {
if (switches[i] == NO_SWITCH)
{ HERE(); continue; }
// check whether the switch is already in the net
for (j = 0; j < net->len; j++) {
if (net->el[j].y == y
@ -2477,6 +2524,11 @@ static int fpga_switch_2sets(struct fpga_model* model, int from_y, int from_x,
struct sw_set to_switches;
int i;
#ifdef DBG_SWITCH_2SETS
printf("fpga_switch_2sets() from y%i-x%i-%s to y%i-x%i-%s\n",
from_y, from_x, strarray_lookup(&model->str, from_pt),
to_y, to_x, strarray_lookup(&model->str, to_pt));
#endif
// only supports 1 switch on the end side right now
fpga_swset_fromto(model, to_y, to_x, to_pt, SW_TO, &to_switches);
RC_ASSERT(model, to_switches.len);
@ -2759,6 +2811,86 @@ static int fnet_route_logic_to_iob(struct fpga_model *model, net_idx_t net_i, in
RC_RETURN(model);
}
static int fnet_route_logic_carry(struct fpga_model *model, net_idx_t net_i, int out_i, int in_i)
{
struct fpga_net *net_p;
struct fpga_device *out_dev, *in_dev;
int xm_col, from_str_i, to_str_i;
swidx_t sw;
net_p = fnet_get(model, net_i);
RC_ASSERT(model, net_p);
out_dev = FPGA_DEV(model, net_p->el[out_i].y, net_p->el[out_i].x, net_p->el[out_i].dev_idx);
in_dev = FPGA_DEV(model, net_p->el[in_i].y, net_p->el[in_i].x, net_p->el[in_i].dev_idx);
RC_ASSERT(model, out_dev && in_dev);
RC_ASSERT(model, (net_p->el[in_i].x == net_p->el[out_i].x)
&& (net_p->el[in_i].y == regular_row_up(net_p->el[out_i].y, model)));
xm_col = has_device_type(model, net_p->el[out_i].y, net_p->el[out_i].x, DEV_LOGIC, LOGIC_M);
if (xm_col) {
from_str_i = strarray_find(&model->str, "M_COUT");
to_str_i = strarray_find(&model->str, "M_COUT_N");
} else { // xl
from_str_i = strarray_find(&model->str, "XL_COUT");
to_str_i = strarray_find(&model->str, "XL_COUT_N");
}
RC_ASSERT(model, from_str_i != STRIDX_NO_ENTRY && !OUT_OF_U16(from_str_i));
RC_ASSERT(model, to_str_i != STRIDX_NO_ENTRY && !OUT_OF_U16(to_str_i));
sw = fpga_switch_lookup(model, net_p->el[out_i].y, net_p->el[out_i].x,
from_str_i, to_str_i);
fnet_add_sw(model, net_i, net_p->el[out_i].y, net_p->el[out_i].x,
&sw, /*len*/ 1);
RC_RETURN(model);
}
static int fnet_route_logic_to_self(struct fpga_model *model,
net_idx_t net_i, int out_i, int in_i)
{
struct fpga_net *net_p;
int logic_y, logic_x, logic_dev_idx;
struct fpga_device *logic_dev;
struct sw_set sw_set;
int out_dest_y, out_dest_x, in_dest_y, in_dest_x;
str16_t out_dest_connpt, in_dest_connpt;
net_p = fnet_get(model, net_i);
RC_ASSERT(model, net_p);
logic_y = net_p->el[out_i].y;
logic_x = net_p->el[out_i].x;
logic_dev_idx = net_p->el[out_i].dev_idx;
RC_ASSERT(model, net_p->el[in_i].y == logic_y
&& net_p->el[in_i].x == logic_x
&& net_p->el[in_i].dev_idx == logic_dev_idx);
logic_dev = FPGA_DEV(model, logic_y, logic_x, logic_dev_idx);
RC_ASSERT(model, logic_dev);
fpga_first_conn(model, logic_y, logic_x,
logic_dev->pinw[net_p->el[out_i].idx & NET_IDX_MASK], SW_FROM,
/*max_depth*/ 2, net_i,
&sw_set, &out_dest_y, &out_dest_x, &out_dest_connpt);
RC_CHECK(model);
fnet_add_sw(model, net_i, logic_y, logic_x, sw_set.sw, sw_set.len);
fpga_first_conn(model, logic_y, logic_x,
logic_dev->pinw[net_p->el[in_i].idx & NET_IDX_MASK], SW_TO,
/*max_depth*/ 2, net_i,
&sw_set, &in_dest_y, &in_dest_x, &in_dest_connpt);
RC_ASSERT(model, out_dest_y == in_dest_y
&& out_dest_x == in_dest_x);
fnet_add_sw(model, net_i, logic_y, logic_x, sw_set.sw, sw_set.len);
fpga_multi_switch_lookup(model, out_dest_y, out_dest_x,
out_dest_connpt, in_dest_connpt, /*max_depth*/ 2, net_i,
&sw_set);
RC_ASSERT(model, sw_set.len);
fnet_add_sw(model, net_i, out_dest_y, out_dest_x, sw_set.sw, sw_set.len);
RC_RETURN(model);
}
static int fnet_route_to_inpin(struct fpga_model *model, net_idx_t net_i, int out_i, int in_i)
{
struct fpga_net *net_p;
@ -2784,9 +2916,11 @@ static int fnet_route_to_inpin(struct fpga_model *model, net_idx_t net_i, int ou
else if (in_dev->type == DEV_LOGIC) {
if (net_p->el[in_i].y == net_p->el[out_i].y
&& net_p->el[in_i].x == net_p->el[out_i].x) {
// fnet_route_logic_to_logic
fnet_route_logic_to_self(model, net_i, out_i, in_i);
} else {
// fnet_route_logic_carry
RC_ASSERT(model, (net_p->el[out_i].idx & NET_IDX_MASK) == LO_COUT
&& (net_p->el[in_i].idx & NET_IDX_MASK) == LI_CIN);
fnet_route_logic_carry(model, net_i, out_i, in_i);
}
} else RC_FAIL(model, ENOTSUP);
} else

View File

@ -138,8 +138,6 @@ typedef int swidx_t; // swidx_t is an index into the uint32_t switches array
// *) some wires that go 'everywhere' like GFAN (70)
#define SW_SET_SIZE 128
// todo: maybe it's better to stop using this structure and use two
// separate parameters instead (swidx_t* and len).
struct sw_set
{
swidx_t sw[SW_SET_SIZE];
@ -250,6 +248,10 @@ void destruct_sw_chain(struct sw_chain* chain);
// set.len is 0 when there are no more switches in the tree
int fpga_switch_chain(struct sw_chain* chain);
int fpga_multi_switch_lookup(struct fpga_model *model, int y, int x,
str16_t from_sw, str16_t to_sw, int max_depth, net_idx_t exclusive_net,
struct sw_set *sw_set);
struct sw_conns
{
struct sw_chain chain;
@ -270,6 +272,10 @@ void destruct_sw_conns(struct sw_conns* conns);
// NO_CONN (-1) if there is no other connection.
int fpga_switch_conns(struct sw_conns* conns);
int fpga_first_conn(struct fpga_model *model, int sw_y, int sw_x, str16_t sw_str,
int from_to, int max_depth, net_idx_t exclusive_net,
struct sw_set *sw_set, int *dest_y, int *dest_x, str16_t *dest_connpt);
// max_depth can be -1 for internal maximum (SW_SET_SIZE)
void printf_swchain(struct fpga_model* model, int y, int x,
str16_t sw, int from_to, int max_depth, swidx_t* block_list,