more clock routing

This commit is contained in:
Wolfgang Spraul 2012-12-13 05:30:34 -05:00
parent 340d011f06
commit 31b4e9fe11
8 changed files with 264 additions and 59 deletions

View File

@ -734,7 +734,8 @@ static int test_iologic_switches2(struct test_state* tstate, int iob_y, int iob_
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,
/*max_depth*/ -1, /*block_list*/ 0, /*block_list_len*/ 0)) /*max_depth*/ -1, SWCHAIN_DEFAULT,
/*block_list*/ 0, /*block_list_len*/ 0))
FAIL(EINVAL); FAIL(EINVAL);
while (fpga_switch_chain(&chain) != NO_CONN) { while (fpga_switch_chain(&chain) != NO_CONN) {
@ -1765,7 +1766,7 @@ static int test_clock_routing(struct test_state* tstate)
fdev_iob_input(tstate->model, iob_clk_y, iob_clk_x, fdev_iob_input(tstate->model, iob_clk_y, iob_clk_x,
iob_clk_type_idx, IO_LVCMOS33); iob_clk_type_idx, IO_LVCMOS33);
logic_y = 58; logic_y = 65; // down from hclk at 62
logic_x = 13; logic_x = 13;
logic_type_idx = DEV_LOG_M_OR_L; logic_type_idx = DEV_LOG_M_OR_L;
@ -1818,7 +1819,7 @@ static int test_clock_routing(struct test_state* tstate)
if (!is_aty(Y_ROW_HORIZ_AXSYMM, tstate->model, y)) if (!is_aty(Y_ROW_HORIZ_AXSYMM, tstate->model, y))
continue; continue;
logic_type_idx = DEV_LOG_M_OR_L; logic_type_idx = DEV_LOG_M_OR_L;
logic_y = y-3; logic_y = y-3; // up from hclk
for (logic_x = 13; logic_x <= 26; logic_x += 13) { for (logic_x = 13; logic_x <= 26; logic_x += 13) {
fdev_logic_a2d_lut(tstate->model, logic_y, logic_x, fdev_logic_a2d_lut(tstate->model, logic_y, logic_x,
logic_type_idx, LUT_A, 6, "A1", ZTERM); logic_type_idx, LUT_A, 6, "A1", ZTERM);

View File

@ -13,6 +13,7 @@ static uint8_t* get_first_minor(struct fpga_bits* bits, int row, int major)
{ {
int i, num_frames; int i, num_frames;
if (row < 0) { HERE(); return 0; }
num_frames = 0; num_frames = 0;
for (i = 0; i < major; i++) for (i = 0; i < major; i++)
num_frames += get_major_minors(XC6SLX9, i); num_frames += get_major_minors(XC6SLX9, i);
@ -593,6 +594,7 @@ static int extract_type2(struct extract_state* es)
// //
// find and enable reg-switch for gclk_pin[i] // find and enable reg-switch for gclk_pin[i]
// the writing equivalent is in write_inner_term_sw()
// //
fpga_find_iob(es->model, es->model->pkg->gclk_pin[i], fpga_find_iob(es->model, es->model->pkg->gclk_pin[i],
@ -1907,12 +1909,14 @@ static int extract_center_switches(struct extract_state *es)
RC_RETURN(es->model); RC_RETURN(es->model);
} }
static int extract_hclk_switches(struct extract_state *es) static int extract_gclk_center_vert_sw(struct extract_state *es)
{ {
int word, cur_row, cur_minor, cur_pin, i, hclk_y; int word, cur_row, cur_minor, cur_pin, i, hclk_y;
uint8_t *ma0_bits; uint8_t *ma0_bits;
RC_CHECK(es->model); RC_CHECK(es->model);
// Switches in the vertical center column that are routing gclk
// signals to the left and right side of the chip.
for (cur_row = 0; cur_row < es->model->die->num_rows; cur_row++) { for (cur_row = 0; cur_row < es->model->die->num_rows; cur_row++) {
hclk_y = row_to_hclk(cur_row, es->model); hclk_y = row_to_hclk(cur_row, es->model);
RC_ASSERT(es->model, hclk_y != -1); RC_ASSERT(es->model, hclk_y != -1);
@ -1946,13 +1950,95 @@ static int extract_hclk_switches(struct extract_state *es)
word &= ~(1<<cur_pin); word &= ~(1<<cur_pin);
} }
if (word) HERE(); if (word) HERE();
frame_set_pinword(ma0_bits + cur_minor*FRAME_SIZE + 8*8+XC6_HCLK_BYTES, word + 4); frame_set_pinword(ma0_bits + cur_minor*FRAME_SIZE + 8*8+XC6_HCLK_BYTES + 4, word);
} }
} }
} }
RC_RETURN(es->model); RC_RETURN(es->model);
} }
static int extract_gclk_hclk_updown_sw(struct extract_state *es)
{
int word, cur_row, x, gclk_pin, hclk_y;
uint8_t *mi0_bits;
RC_CHECK(es->model);
// Switches in each horizontal hclk row that are routing
// gclk signals and and down to the clocked devices.
// todo: clk access in left and right IO devs, center devs,
// bram and macc devs as well as special devs not tested
// yet (only XM logic devs tested).
for (cur_row = 0; cur_row < es->model->die->num_rows; cur_row++) {
hclk_y = row_to_hclk(cur_row, es->model);
RC_ASSERT(es->model, hclk_y != -1);
for (x = LEFT_IO_ROUTING; x <= es->model->x_width-RIGHT_IO_ROUTING_O; x++) {
if (!is_atx(X_ROUTING_COL, es->model, x))
continue;
mi0_bits = get_first_minor(es->bits, cur_row, es->model->x_major[x]);
// each minor (0:15) stores the configuration bits for one gclk
// pin (in the hclk bytes of the minor)
for (gclk_pin = 0; gclk_pin <= 15; gclk_pin++) {
word = frame_get_pinword(mi0_bits + gclk_pin*FRAME_SIZE + XC6_HCLK_POS);
if (word & (1<<XC6_HCLK_GCLK_UP_PIN)) {
add_yx_switch(es, hclk_y, x,
pf("HCLK_GCLK%i_INT", gclk_pin),
pf("HCLK_GCLK_UP%i", gclk_pin));
word &= ~(1<<XC6_HCLK_GCLK_UP_PIN);
}
if (word & (1<<XC6_HCLK_GCLK_DOWN_PIN)) {
add_yx_switch(es, hclk_y, x,
pf("HCLK_GCLK%i_INT", gclk_pin),
pf("HCLK_GCLK%i", gclk_pin));
word &= ~(1<<XC6_HCLK_GCLK_DOWN_PIN);
}
if (word) HERE();
frame_set_pinword(mi0_bits + gclk_pin*FRAME_SIZE + XC6_HCLK_POS, word);
}
}
}
RC_RETURN(es->model);
}
static int write_hclk_sw(struct fpga_bits *bits, struct fpga_model *model,
int y, int x)
{
uint8_t *mi0_bits;
struct fpga_tile *tile;
const char *from_str, *to_str;
int i, j, gclk_pin_from, gclk_pin_to, up, word;
RC_CHECK(model);
mi0_bits = get_first_minor(bits, which_row(y, model), model->x_major[x]);
RC_ASSERT(model, mi0_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);
j = sscanf(from_str, "HCLK_GCLK%i_INT", &gclk_pin_from);
RC_ASSERT(model, j == 1);
j = sscanf(to_str, "HCLK_GCLK%i", &gclk_pin_to);
if (j == 1)
up = 0; // down
else {
j = sscanf(to_str, "HCLK_GCLK_UP%i", &gclk_pin_to);
RC_ASSERT(model, j == 1);
up = 1;
}
RC_ASSERT(model, gclk_pin_from == gclk_pin_to);
word = frame_get_pinword(mi0_bits + gclk_pin_from*FRAME_SIZE + XC6_HCLK_POS);
word |= 1 << (up ? XC6_HCLK_GCLK_UP_PIN : XC6_HCLK_GCLK_DOWN_PIN);
frame_set_pinword(mi0_bits + gclk_pin_from*FRAME_SIZE + XC6_HCLK_POS, word);
}
RC_RETURN(model);
}
static int extract_switches(struct extract_state *es) static int extract_switches(struct extract_state *es)
{ {
int x, y; int x, y;
@ -1979,7 +2065,8 @@ static int extract_switches(struct extract_state *es)
} }
} }
extract_center_switches(es); extract_center_switches(es);
extract_hclk_switches(es); extract_gclk_center_vert_sw(es);
extract_gclk_hclk_updown_sw(es);
RC_RETURN(es->model); RC_RETURN(es->model);
} }
@ -2245,12 +2332,99 @@ fail:
return rc; return rc;
} }
static int write_inner_term_sw(struct fpga_bits *bits,
struct fpga_model *model, int y, int x)
{
struct fpga_tile *tile;
const char *from_str, *from_found, *to_str, *to_found;
int i, j, from_idx, to_idx;
RC_CHECK(model);
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);
if (strstr(from_str, "IBUF")
&& strstr(to_str, "CLKPIN"))
continue;
if ((from_found = strstr(from_str, "CLKPIN"))
&& (to_found = strstr(to_str, "CKPIN"))) {
struct switch_to_yx_l2 switch_to_yx_l2;
int iob_y, iob_x, iob_idx;
struct fpga_device *iob_dev;
from_idx = atoi(&from_found[6]);
to_idx = atoi(&to_found[5]);
RC_ASSERT(model, from_idx == to_idx);
// follow switches backwards to IOB
switch_to_yx_l2.l1.yx_req = YX_DEV_IOB;
switch_to_yx_l2.l1.flags = SWTO_YX_DEF;
switch_to_yx_l2.l1.model = model;
switch_to_yx_l2.l1.y = y;
switch_to_yx_l2.l1.x = x;
switch_to_yx_l2.l1.start_switch = fpga_switch_str_i(model, y, x, i, SW_TO);
switch_to_yx_l2.l1.from_to = SW_TO;
fpga_switch_to_yx_l2(&switch_to_yx_l2);
RC_ASSERT(model, switch_to_yx_l2.l1.set.len);
// find matching gclk pin
for (j = 0; j < model->pkg->num_gclk_pins; j++) {
if (!model->pkg->gclk_pin[j])
continue;
fpga_find_iob(model, model->pkg->gclk_pin[j],
&iob_y, &iob_x, &iob_idx);
RC_CHECK(model);
if (iob_y != switch_to_yx_l2.l1.dest_y
|| iob_x != switch_to_yx_l2.l1.dest_x)
continue;
iob_dev = fdev_p(model, iob_y, iob_x, DEV_IOB, iob_idx);
RC_ASSERT(model, iob_dev);
if (fpga_switch_lookup(model, iob_y, iob_x,
iob_dev->pinw[IOB_OUT_I],
switch_to_yx_l2.l1.dest_connpt) != NO_SWITCH)
break;
}
// set bit
if (j < model->pkg->num_gclk_pins) {
uint16_t u16;
int bits_off;
bits_off = IOB_DATA_START
+ model->pkg->gclk_type2_o[j]*XC6_WORD_BYTES
+ XC6_TYPE2_GCLK_REG_SW/XC6_WORD_BITS;
u16 = frame_get_u16(&bits->d[bits_off]);
u16 |= 1<<(XC6_TYPE2_GCLK_REG_SW%XC6_WORD_BITS);
frame_set_u16(&bits->d[bits_off], u16);
continue;
}
// fall-through to unsupported
}
fprintf(stderr, "#E %s:%i unsupported switch "
"y%i x%i %s -> %s\n", __FILE__, __LINE__,
y, x, from_str, to_str);
}
RC_RETURN(model);
}
static int write_switches(struct fpga_bits* bits, struct fpga_model* model) static int write_switches(struct fpga_bits* bits, struct fpga_model* model)
{ {
struct fpga_tile* tile; struct fpga_tile* tile;
int x, y, i, rc; int x, y, i;
RC_CHECK(model); RC_CHECK(model);
// We need to identify and take out each enabled switch, whether it
// leads to enabled bits or not. That way we can print unsupported
// switches at the end and keep our model alive and maintainable
// over time.
for (x = 0; x < model->x_width; x++) { for (x = 0; x < model->x_width; x++) {
for (y = 0; y < model->y_height; y++) { for (y = 0; y < model->y_height; y++) {
if (is_atx(X_ROUTING_COL, model, x) if (is_atx(X_ROUTING_COL, model, x)
@ -2258,20 +2432,25 @@ static int write_switches(struct fpga_bits* bits, struct fpga_model* model)
&& y < model->y_height-BOT_IO_TILES && y < model->y_height-BOT_IO_TILES
&& !is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, && !is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS,
model, y)) { model, y)) {
rc = write_routing_sw(bits, model, y, x); write_routing_sw(bits, model, y, x);
if (rc) FAIL(rc);
continue; continue;
} }
if (is_atyx(YX_DEV_ILOGIC, model, y, x)) { if (is_atyx(YX_DEV_ILOGIC, model, y, x)) {
rc = write_iologic_sw(bits, model, y, x); write_iologic_sw(bits, model, y, x);
if (rc) FAIL(rc);
continue; continue;
} }
// todo: there are probably switches in logic and
// iob that need bits, and switches in other
// tiles that need no bits...
if (is_atyx(YX_DEV_LOGIC|YX_DEV_IOB, model, y, x)) if (is_atyx(YX_DEV_LOGIC|YX_DEV_IOB, model, y, x))
continue; continue;
if (is_atx(X_ROUTING_COL, model, x)
&& is_aty(Y_ROW_HORIZ_AXSYMM, model, y)) {
write_hclk_sw(bits, model, y, x);
continue;
}
if (is_atyx(YX_INNER_TERM, model, y, x)) {
write_inner_term_sw(bits, model, y, x);
continue;
}
// print unsupported switches
tile = YX_TILE(model, y, x); tile = YX_TILE(model, y, x);
for (i = 0; i < tile->num_switches; i++) { for (i = 0; i < tile->num_switches; i++) {
if (!(tile->switches[i] & SWITCH_USED)) if (!(tile->switches[i] & SWITCH_USED))
@ -2283,9 +2462,7 @@ static int write_switches(struct fpga_bits* bits, struct fpga_model* model)
} }
} }
} }
return 0; RC_RETURN(model);
fail:
return rc;
} }
static int write_logic(struct fpga_bits* bits, struct fpga_model* model) static int write_logic(struct fpga_bits* bits, struct fpga_model* model)

View File

@ -9,6 +9,7 @@
#include "control.h" #include "control.h"
#undef DBG_ENUM_SWITCH #undef DBG_ENUM_SWITCH
#undef DBG_SWITCH_CONNS
#undef DBG_SWITCH_TO_YX #undef DBG_SWITCH_TO_YX
#undef DBG_SWITCH_TO_REL #undef DBG_SWITCH_TO_REL
@ -1580,13 +1581,14 @@ const char* fmt_swset(struct fpga_model* model, int y, int x,
int construct_sw_chain(struct sw_chain* chain, struct fpga_model* model, int construct_sw_chain(struct sw_chain* chain, struct fpga_model* model,
int y, int x, str16_t start_switch, int from_to, int max_depth, int y, int x, str16_t start_switch, int from_to, int max_depth,
swidx_t* block_list, int block_list_len) int flags, swidx_t* block_list, int block_list_len)
{ {
RC_CHECK(model); RC_CHECK(model);
#ifdef DBG_ENUM_SWITCH #ifdef DBG_ENUM_SWITCH
printf("construct_sw_chain() %s (%s)\n", printf("construct_sw_chain() %s (%s) flags %Xh\n",
strarray_lookup(&model->str, start_switch), strarray_lookup(&model->str, start_switch),
(from_to == SW_FROM) ? "SW_FROM" : "SW_TO"); (from_to == SW_FROM) ? "SW_FROM" : "SW_TO",
flags);
#endif #endif
memset(chain, 0, sizeof(*chain)); memset(chain, 0, sizeof(*chain));
chain->model = model; chain->model = model;
@ -1594,6 +1596,7 @@ int construct_sw_chain(struct sw_chain* chain, struct fpga_model* model,
chain->x = x; chain->x = x;
chain->from_to = from_to; chain->from_to = from_to;
chain->max_depth = (max_depth < 0) ? SW_SET_SIZE : max_depth; chain->max_depth = (max_depth < 0) ? SW_SET_SIZE : max_depth;
chain->flags = flags;
if (block_list) { if (block_list) {
chain->block_list = block_list; chain->block_list = block_list;
chain->block_list_len = block_list_len; chain->block_list_len = block_list_len;
@ -1665,7 +1668,8 @@ int fpga_switch_chain(struct sw_chain* ch)
if (idx == NO_SWITCH) if (idx == NO_SWITCH)
break; break;
ch->set.sw[ch->set.len-1] = idx; ch->set.sw[ch->set.len-1] = idx;
if (!fpga_switch_is_used(ch->model, ch->y, ch->x, idx) if ((!(ch->flags & SWCHAIN_EXCLUDING_USED)
|| !fpga_switch_is_used(ch->model, ch->y, ch->x, idx))
&& switch_list_contains(ch->model, ch->y, ch->x, && switch_list_contains(ch->model, ch->y, ch->x,
ch->block_list, ch->block_list_len, idx) ch->block_list, ch->block_list_len, idx)
== NO_SWITCH) == NO_SWITCH)
@ -1718,7 +1722,8 @@ int fpga_switch_chain(struct sw_chain* ch)
ch->model, ch->y, ch->x, ch->model, ch->y, ch->x,
child_from_to)); child_from_to));
#endif #endif
if (fpga_switch_is_used(ch->model, ch->y, ch->x, idx)) if (ch->flags & SWCHAIN_EXCLUDING_USED
&& fpga_switch_is_used(ch->model, ch->y, ch->x, idx))
level_down = 0; level_down = 0;
if (level_down) { if (level_down) {
@ -1784,7 +1789,8 @@ int fpga_switch_chain(struct sw_chain* ch)
ch->model, ch->y, ch->x, ch->model, ch->y, ch->x,
ch->set.sw[ch->set.len-1], ch->from_to); ch->set.sw[ch->set.len-1], ch->from_to);
if (ch->set.sw[ch->set.len-1] != NO_SWITCH) { if (ch->set.sw[ch->set.len-1] != NO_SWITCH) {
if (fpga_switch_is_used(ch->model, ch->y, if (ch->flags & SWCHAIN_EXCLUDING_USED
&& fpga_switch_is_used(ch->model, ch->y,
ch->x, ch->set.sw[ch->set.len-1])) { ch->x, ch->set.sw[ch->set.len-1])) {
#ifdef DBG_ENUM_SWITCH #ifdef DBG_ENUM_SWITCH
printf(" skipping used %s\n", printf(" skipping used %s\n",
@ -1822,7 +1828,8 @@ int construct_sw_conns(struct sw_conns* conns, struct fpga_model* model,
RC_CHECK(model); RC_CHECK(model);
memset(conns, 0, sizeof(*conns)); memset(conns, 0, sizeof(*conns));
construct_sw_chain(&conns->chain, model, y, x, start_switch, construct_sw_chain(&conns->chain, model, y, x, start_switch,
from_to, max_depth, /*block_list*/ 0, /*block_list_len*/ 0); from_to, max_depth, SWCHAIN_DEFAULT,
/*block_list*/ 0, /*block_list_len*/ 0);
RC_RETURN(model); RC_RETURN(model);
} }
@ -1838,11 +1845,18 @@ int fpga_switch_conns(struct sw_conns* conns)
if (!conns->chain.set.len) { HERE(); goto internal_error; } if (!conns->chain.set.len) { HERE(); goto internal_error; }
#ifdef DBG_SWITCH_TO_YX
printf("fpga_switch_conns() dest_i %i num_dests %i\n", conns->dest_i, conns->num_dests);
#endif
// on the first call, both dest_i and num_dests are 0 // on the first call, both dest_i and num_dests are 0
while (conns->dest_i >= conns->num_dests) { while (conns->dest_i >= conns->num_dests) {
fpga_switch_chain(&conns->chain); fpga_switch_chain(&conns->chain);
if (conns->chain.set.len == 0) if (conns->chain.set.len == 0) {
#ifdef DBG_SWITCH_TO_YX
printf(" no more switches\n");
#endif
return NO_CONN; return NO_CONN;
}
end_of_chain_str = fpga_switch_str_i(conns->chain.model, end_of_chain_str = fpga_switch_str_i(conns->chain.model,
conns->chain.y, conns->chain.x, conns->chain.y, conns->chain.x,
conns->chain.set.sw[conns->chain.set.len-1], conns->chain.set.sw[conns->chain.set.len-1],
@ -1853,9 +1867,18 @@ int fpga_switch_conns(struct sw_conns* conns)
fpga_connpt_find(conns->chain.model, conns->chain.y, fpga_connpt_find(conns->chain.model, conns->chain.y,
conns->chain.x, end_of_chain_str, conns->chain.x, end_of_chain_str,
&conns->connpt_dest_start, &conns->num_dests); &conns->connpt_dest_start, &conns->num_dests);
if (conns->num_dests) if (conns->num_dests) {
#ifdef DBG_SWITCH_TO_YX
printf(" %s: %i conns\n", strarray_lookup(&conns->chain.model->str,
end_of_chain_str), conns->num_dests);
#endif
break; break;
} }
#ifdef DBG_SWITCH_TO_YX
printf(" %s: no conns\n", strarray_lookup(
&conns->chain.model->str, end_of_chain_str));
#endif
}
fpga_conn_dest(conns->chain.model, conns->chain.y, conns->chain.x, fpga_conn_dest(conns->chain.model, conns->chain.y, conns->chain.x,
conns->connpt_dest_start + conns->dest_i, conns->connpt_dest_start + conns->dest_i,
&conns->dest_y, &conns->dest_x, &conns->dest_str_i); &conns->dest_y, &conns->dest_x, &conns->dest_str_i);
@ -1880,6 +1903,7 @@ void printf_swchain(struct fpga_model* model, int y, int x,
y, x, strarray_lookup(&model->str, sw), y, x, strarray_lookup(&model->str, sw),
block_list_len ? *block_list_len : 0); block_list_len ? *block_list_len : 0);
if (construct_sw_chain(&chain, model, y, x, sw, from_to, max_depth, if (construct_sw_chain(&chain, model, y, x, sw, from_to, max_depth,
SWCHAIN_DEFAULT,
block_list, block_list_len ? *block_list_len : 0)) block_list, block_list_len ? *block_list_len : 0))
{ HERE(); return; } { HERE(); return; }
while (fpga_switch_chain(&chain) != NO_CONN) { while (fpga_switch_chain(&chain) != NO_CONN) {

View File

@ -203,6 +203,9 @@ const char* fmt_swset(struct fpga_model* model, int y, int x,
// of switches in a tile, currently 3459 in a slx9 routing tile. // of switches in a tile, currently 3459 in a slx9 routing tile.
#define MAX_SWITCHBOX_SIZE 4000 #define MAX_SWITCHBOX_SIZE 4000
#define SWCHAIN_DEFAULT 0
#define SWCHAIN_EXCLUDING_USED 0x0001
struct sw_chain struct sw_chain
{ {
// start and recurring values: // start and recurring values:
@ -211,6 +214,7 @@ struct sw_chain
int x; int x;
int from_to; int from_to;
int max_depth; int max_depth;
int flags;
// //
// block_list works as if all switches from or to the ones // block_list works as if all switches from or to the ones
// on the block list are blocked, that is the recursion will // on the block list are blocked, that is the recursion will
@ -233,7 +237,7 @@ struct sw_chain
int construct_sw_chain(struct sw_chain* chain, struct fpga_model* model, int construct_sw_chain(struct sw_chain* chain, struct fpga_model* model,
int y, int x, str16_t start_switch, int from_to, int max_depth, int y, int x, str16_t start_switch, int from_to, int max_depth,
swidx_t* block_list, int block_list_len); int flags, swidx_t* block_list, int block_list_len);
void destruct_sw_chain(struct sw_chain* chain); void destruct_sw_chain(struct sw_chain* chain);
// Returns 0 if another switchset is returned in chain, or // Returns 0 if another switchset is returned in chain, or

View File

@ -292,10 +292,9 @@ int is_atx(int check, struct fpga_model* model, int x);
// outside_of_routing is true for anything outside of the outer // outside_of_routing is true for anything outside of the outer
// boundary of the regular routing area. // boundary of the regular routing area.
#define YX_OUTSIDE_OF_ROUTING 0x0400 #define YX_OUTSIDE_OF_ROUTING 0x0400
#define YX_ROUTING_BOUNDARY 0x0800 #define YX_X_CENTER_CMTPLL 0x0800
#define YX_X_CENTER_CMTPLL 0x1000 #define YX_Y_CENTER 0x1000
#define YX_Y_CENTER 0x2000 #define YX_CENTER 0x2000
#define YX_CENTER 0x4000
int is_atyx(int check, struct fpga_model* model, int y, int x); int is_atyx(int check, struct fpga_model* model, int y, int x);

View File

@ -732,10 +732,6 @@ int is_atyx(int check, struct fpga_model* model, int y, int x)
|| x > model->x_width-RIGHT_IO_ROUTING_O || x > model->x_width-RIGHT_IO_ROUTING_O
|| y <= TOP_INNER_ROW || y <= TOP_INNER_ROW
|| y >= model->y_height-BOT_INNER_ROW )) return 1; || 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;
if (check & YX_X_CENTER_CMTPLL if (check & YX_X_CENTER_CMTPLL
&& is_atx(X_CENTER_CMTPLL_COL, model, x)) return 1; && is_atx(X_CENTER_CMTPLL_COL, model, x)) return 1;
if (check & YX_Y_CENTER if (check & YX_Y_CENTER
@ -1905,6 +1901,29 @@ enum extra_wires fpga_str2wire(const char* str)
} }
} }
} }
if (!strcmp(_str, "GFAN0")) return GFAN0;
if (!strcmp(_str, "GFAN1")) return GFAN1;
if (!strcmp(_str, "CLK0")) return CLK0;
if (!strcmp(_str, "CLK1")) return CLK1;
if (!strcmp(_str, "SR0")) return SR0;
if (!strcmp(_str, "SR1")) return SR1;
if (!strcmp(_str, "GND_WIRE")) return GND_WIRE;
if (!strcmp(_str, "VCC_WIRE")) return VCC_WIRE;
if (!strcmp(_str, "FAN_B")) return FAN_B;
if (!strncmp(_str, "LOGICIN", 7)) {
if (!strcmp(&_str[7], "20")) return LOGICIN20;
if (!strcmp(&_str[7], "21")) return LOGICIN21;
if (!strcmp(&_str[7], "44")) return LOGICIN44;
if (!strcmp(&_str[7], "52")) return LOGICIN52;
if (!strcmp(&_str[7], "_N21")) return LOGICIN_N21;
if (!strcmp(&_str[7], "_N28")) return LOGICIN_N28;
if (!strcmp(&_str[7], "_N52")) return LOGICIN_N52;
if (!strcmp(&_str[7], "_N60")) return LOGICIN_N60;
if (!strcmp(&_str[7], "_S20")) return LOGICIN_S20;
if (!strcmp(&_str[7], "_S36")) return LOGICIN_S36;
if (!strcmp(&_str[7], "_S44")) return LOGICIN_S44;
if (!strcmp(&_str[7], "_S62")) return LOGICIN_S62;
}
if ((wtype = base2wire(_str))) { if ((wtype = base2wire(_str))) {
flags = 0; flags = 0;
if (_str[3] == 'B') if (_str[3] == 'B')
@ -1932,29 +1951,6 @@ enum extra_wires fpga_str2wire(const char* str)
return DW + ((wtype*4 + num)|flags); return DW + ((wtype*4 + num)|flags);
} }
} }
if (!strcmp(_str, "GFAN0")) return GFAN0;
if (!strcmp(_str, "GFAN1")) return GFAN1;
if (!strcmp(_str, "CLK0")) return CLK0;
if (!strcmp(_str, "CLK1")) return CLK1;
if (!strcmp(_str, "SR0")) return SR0;
if (!strcmp(_str, "SR1")) return SR1;
if (!strcmp(_str, "GND_WIRE")) return GND_WIRE;
if (!strcmp(_str, "VCC_WIRE")) return VCC_WIRE;
if (!strcmp(_str, "FAN_B")) return FAN_B;
if (!strncmp(_str, "LOGICIN", 7)) {
if (!strcmp(&_str[7], "20")) return LOGICIN20;
if (!strcmp(&_str[7], "21")) return LOGICIN21;
if (!strcmp(&_str[7], "44")) return LOGICIN44;
if (!strcmp(&_str[7], "52")) return LOGICIN52;
if (!strcmp(&_str[7], "_N21")) return LOGICIN_N21;
if (!strcmp(&_str[7], "_N28")) return LOGICIN_N28;
if (!strcmp(&_str[7], "_N52")) return LOGICIN_N52;
if (!strcmp(&_str[7], "_N60")) return LOGICIN_N60;
if (!strcmp(&_str[7], "_S20")) return LOGICIN_S20;
if (!strcmp(&_str[7], "_S36")) return LOGICIN_S36;
if (!strcmp(&_str[7], "_S44")) return LOGICIN_S44;
if (!strcmp(&_str[7], "_S62")) return LOGICIN_S62;
}
HERE(); HERE();
return NO_WIRE; return NO_WIRE;
} }

View File

@ -1308,7 +1308,7 @@ enum wire_type base2wire(const char* str)
if (!strncmp(str, "WW4", 3)) return W_WW4; if (!strncmp(str, "WW4", 3)) return W_WW4;
if (!strncmp(str, "NW4", 3)) return W_NW4; if (!strncmp(str, "NW4", 3)) return W_NW4;
HERE(); fprintf(stderr, "#E %s:%i base2wire() %s unknown\n", __FILE__, __LINE__, str);
return 0; return 0;
} }

View File

@ -130,9 +130,13 @@ const struct xc6_pkg_info *xc6_pkg_info(enum xc6_pkg pkg);
#define XC6_WORD_BYTES 2 #define XC6_WORD_BYTES 2
#define XC6_WORD_BITS (XC6_WORD_BYTES*8) #define XC6_WORD_BITS (XC6_WORD_BYTES*8)
#define XC6_HCLK_POS 64
#define XC6_HCLK_BYTES 2 #define XC6_HCLK_BYTES 2
#define XC6_HCLK_BITS (XC6_HCLK_BYTES*8) #define XC6_HCLK_BITS (XC6_HCLK_BYTES*8)
#define XC6_HCLK_GCLK_UP_PIN 0
#define XC6_HCLK_GCLK_DOWN_PIN 1
#define XC6_NULL_MAJOR 0 #define XC6_NULL_MAJOR 0
#define XC6_IOB_MASK_IO 0x00FF00FFFF000000 #define XC6_IOB_MASK_IO 0x00FF00FFFF000000