improved switches

This commit is contained in:
Wolfgang Spraul 2012-12-14 08:24:22 -05:00
parent 31b4e9fe11
commit 19d5719c57

View File

@ -1909,6 +1909,59 @@ static int extract_center_switches(struct extract_state *es)
RC_RETURN(es->model);
}
static int write_center_sw(struct fpga_bits *bits,
struct fpga_model *model, int y, int x)
{
struct fpga_tile *tile;
const char *from_str, *to_str;
int center_row, center_major, word;
int i, j, gclk_pin_from, gclk_pin_to;
uint8_t *minor_p;
RC_CHECK(model);
center_row = model->die->num_rows/2;
center_major = xc_die_center_major(model->die);
minor_p = get_first_minor(bits, center_row,
center_major) + XC6_CENTER_GCLK_MINOR*FRAME_SIZE;
tile = YX_TILE(model, y, x);
for (i = 0; i < tile->num_switches; i++) {
if (!(tile->switches[i] & SWITCH_USED))
continue;
from_str = fpga_switch_str(model, y, x, i, SW_FROM);
to_str = fpga_switch_str(model, y, x, i, SW_TO);
RC_ASSERT(model, from_str && to_str);
j = sscanf(from_str, "CLKC_CKLR%i", &gclk_pin_from);
if (j == 1) {
j = sscanf(to_str, "CLKC_GCLK%i", &gclk_pin_to);
RC_ASSERT(model, j == 1 && gclk_pin_to == gclk_pin_from);
word = frame_get_pinword(minor_p + 15*8+XC6_HCLK_BYTES);
word |= 1 << gclk_pin_from;
frame_set_pinword(minor_p + 15*8+XC6_HCLK_BYTES, word);
continue;
}
j = sscanf(from_str, "CLKC_CKTB%i", &gclk_pin_from);
if (j == 1) {
j = sscanf(to_str, "CLKC_GCLK%i", &gclk_pin_to);
RC_ASSERT(model, j == 1 && gclk_pin_to == gclk_pin_from);
word = frame_get_pinword(minor_p + 15*8+XC6_HCLK_BYTES + XC6_WORD_BYTES);
word |= 1 << gclk_pin_from;
frame_set_pinword(minor_p + 15*8+XC6_HCLK_BYTES + XC6_WORD_BYTES, word);
continue;
}
// todo: it's possible that other switches need bits
// todo: we can manually detect used switches that do not
// need bits, such as
// I0_GCLK_SITE0:15 -> O_GCLK_SITE0:15
// O_GCLK_SITE0:15 -> CLKC_GCLK_MAIN0:15
// CLKC_GCLK%i -> I0_GCLK_SITE%i
}
RC_RETURN(model);
}
static int extract_gclk_center_vert_sw(struct extract_state *es)
{
int word, cur_row, cur_minor, cur_pin, i, hclk_y;
@ -1957,6 +2010,86 @@ static int extract_gclk_center_vert_sw(struct extract_state *es)
RC_RETURN(es->model);
}
static int write_gclk_center_vert_sw(struct fpga_bits *bits,
struct fpga_model *model, int y, int x)
{
struct fpga_tile *tile;
const char *from_str, *to_str;
int i, j, gclk_pin_from, gclk_pin_to, cur_pin, cur_minor, minor_found, word;
uint8_t *ma0_bits;
RC_CHECK(model);
ma0_bits = get_first_minor(bits, which_row(y, model), XC6_NULL_MAJOR);
RC_ASSERT(model, ma0_bits);
tile = YX_TILE(model, y, x);
for (i = 0; i < tile->num_switches; i++) {
if (!(tile->switches[i] & SWITCH_USED))
continue;
from_str = fpga_switch_str(model, y, x, i, SW_FROM);
to_str = fpga_switch_str(model, y, x, i, SW_TO);
RC_ASSERT(model, from_str && to_str);
// left
j = sscanf(from_str, "CLKV_GCLKH_MAIN%i_FOLD", &gclk_pin_from);
if (j == 1) {
j = sscanf(to_str, "CLKV_GCLKH_L%i", &gclk_pin_to);
RC_ASSERT(model, j == 1 && gclk_pin_to == gclk_pin_from);
minor_found = -1;
for (cur_minor = 0; minor_found == -1 && cur_minor <= 2; cur_minor++) {
for (j = 0; j <= 16/3; j++) { // 0-5
cur_pin = cur_minor + j*3;
if (cur_pin > 15) break;
if (cur_pin == gclk_pin_from) {
minor_found = cur_minor;
break;
}
}
}
if (minor_found != -1) {
word = frame_get_pinword(ma0_bits + minor_found*FRAME_SIZE + 8*8+XC6_HCLK_BYTES);
word |= 1 << gclk_pin_from;
frame_set_pinword(ma0_bits + minor_found*FRAME_SIZE + 8*8+XC6_HCLK_BYTES, word);
continue;
}
HERE(); // fall-through to unsupported
}
// right
j = sscanf(from_str, "CLKV_GCLKH_MAIN%i_FOLD", &gclk_pin_from);
if (j == 1) {
j = sscanf(to_str, "CLKV_GCLKH_R%i", &gclk_pin_to);
RC_ASSERT(model, j == 1 && gclk_pin_to == gclk_pin_from);
minor_found = -1;
for (cur_minor = 0; minor_found == -1 && cur_minor <= 2; cur_minor++) {
for (j = 0; j <= 16/3; j++) { // 0-5
cur_pin = cur_minor + j*3;
if (cur_pin > 15) break;
if (cur_pin == gclk_pin_from) {
minor_found = cur_minor;
break;
}
}
}
if (minor_found != -1) {
word = frame_get_pinword(ma0_bits + minor_found*FRAME_SIZE + 8*8+XC6_HCLK_BYTES + 4);
word |= 1 << gclk_pin_from;
frame_set_pinword(ma0_bits + minor_found*FRAME_SIZE + 8*8+XC6_HCLK_BYTES + 4, word);
continue;
}
HERE(); // fall-through to unsupported
}
// todo: we can manually detect used switches that do not
// need bits, such as
// CLKV_GCLKH_L0:15 -> I_BUFH_LEFT_SITE0:15
// I_BUFH_LEFT_SITE0:15 -> O_BUFH_LEFT_SITE0:15
// O_BUFH_LEFT_SITE0:15 -> CLKV_BUFH_LEFT_L0:15
}
RC_RETURN(model);
}
static int extract_gclk_hclk_updown_sw(struct extract_state *es)
{
int word, cur_row, x, gclk_pin, hclk_y;
@ -2427,6 +2560,7 @@ static int write_switches(struct fpga_bits* bits, struct fpga_model* model)
// over time.
for (x = 0; x < model->x_width; x++) {
for (y = 0; y < model->y_height; y++) {
tile = YX_TILE(model, y, x);
if (is_atx(X_ROUTING_COL, model, x)
&& y >= TOP_IO_TILES
&& y < model->y_height-BOT_IO_TILES
@ -2450,8 +2584,23 @@ static int write_switches(struct fpga_bits* bits, struct fpga_model* model)
write_inner_term_sw(bits, model, y, x);
continue;
}
if (is_atyx(YX_CENTER, model, y, x)) {
write_center_sw(bits, model, y, x);
continue;
}
if (is_atx(X_CENTER_REGS_COL, model, x)) {
if (is_aty(Y_ROW_HORIZ_AXSYMM, model, y)) {
write_gclk_center_vert_sw(bits, model, y, x);
continue;
}
if (tile->flags & TF_CENTER_MIDBUF
|| (y < model->center_y
&& YX_TILE(model, y+1, x)->flags & TF_CENTER_MIDBUF)
|| (y > model->center_y
&& YX_TILE(model, y-1, x)->flags & TF_CENTER_MIDBUF))
continue;
}
// print unsupported switches
tile = YX_TILE(model, y, x);
for (i = 0; i < tile->num_switches; i++) {
if (!(tile->switches[i] & SWITCH_USED))
continue;