more work in iologic switches, minor fixes

This commit is contained in:
Wolfgang Spraul 2012-10-14 05:24:21 +02:00
parent 3766d7f5fc
commit b25f9daa4a
8 changed files with 709 additions and 220 deletions

12
README
View File

@ -1,11 +1,10 @@
Introduction Introduction
fpgatools is a toolchain to program field-programmable gate arrays fpgatools is a toolchain to program field-programmable gate arrays
(FPGAs). The only supported chip at this time is the xc6slx9, a cheap (FPGAs). The only supported chip at this time is the xc6slx9, a
(ca. 7 USD) but powerful 45nm-generation chip with 5720 6-input LUTs, 7 USD 45nm-generation fpga with 5720 6-input LUTs, block ram and
block ram and multiply-accumulate devices. multiply-accumulate devices.
The long-term goals of fpgatools are:
*) reach maximum physical chip performance *) maximize chip performance
*) fast development cycles *) fast development cycles
*) independent toolchain that only depends on other free software *) independent toolchain that only depends on other free software
*) reconfigure on-chip *) reconfigure on-chip
@ -31,6 +30,7 @@ Libraries
Design Utilities Design Utilities
- hello_world outputs an AND gate floorplan to stdout - hello_world outputs an AND gate floorplan to stdout
- blinking_led outputs blinking led design to stdout
- new_fp creates empty .fp floorplan file - new_fp creates empty .fp floorplan file
- fp2bit converts .fp floorplan into .bit bitstream - fp2bit converts .fp floorplan into .bit bitstream
- bit2fp converts .bit bitstream into .fp floorplan - bit2fp converts .bit bitstream into .fp floorplan
@ -38,7 +38,7 @@ Design Utilities
fpgatools Development Utilities fpgatools Development Utilities
- autotest executes test suite - autotest test suite
- sort_seq sorts line-based text file by sequence numbers in strings - sort_seq sorts line-based text file by sequence numbers in strings
- merge_seq merges a pre-sorted text file into wire sequences - merge_seq merges a pre-sorted text file into wire sequences
- pair2net reads the first two words per line and builds nets - pair2net reads the first two words per line and builds nets

View File

@ -95,7 +95,7 @@ struct extract_state
static int find_es_switch(struct extract_state* es, int y, int x, swidx_t sw) static int find_es_switch(struct extract_state* es, int y, int x, swidx_t sw)
{ {
int i; int i;
if (sw == NO_CONN) { HERE(); return 0; } if (sw == NO_SWITCH) { HERE(); return 0; }
for (i = 0; i < es->num_yx_pos; i++) { for (i = 0; i < es->num_yx_pos; i++) {
if (es->yx_pos[i].y == y if (es->yx_pos[i].y == y
&& es->yx_pos[i].x == x && es->yx_pos[i].x == x
@ -1311,10 +1311,28 @@ static int extract_logic(struct extract_state* es)
// todo: ff5_srinit // todo: ff5_srinit
// todo: 5Q ff also needs clock/sync check // todo: 5Q ff also needs clock/sync check
} }
// todo:
// if (lut_a->out_mux == xor || lut_a->ff_mux == xor // Check whether we should default to PRECYINIT_0
// || lut_a->acy0 != 0) && !precyinit && !cin_switch if (!cfg_ml.precyinit
// -> precyinit = precyinit_0 && (cfg_ml.a2d[LUT_A].out_mux == MUX_XOR
|| cfg_ml.a2d[LUT_A].ff_mux == MUX_XOR
|| cfg_ml.a2d[LUT_A].cy0)) {
int connpt_dests_o, num_dests, cout_y, cout_x;
str16_t cout_str;
if ((fpga_connpt_find(es->model, y, x,
dev_ml->pinw[LI_CIN], &connpt_dests_o,
&num_dests) == NO_CONN)
|| num_dests != 1) {
HERE();
} else {
fpga_conn_dest(es->model, y, x, connpt_dests_o,
&cout_y, &cout_x, &cout_str);
if (find_es_switch(es, cout_y, cout_x,fpga_switch_first(
es->model, cout_y, cout_x, cout_str, SW_TO)))
cfg_ml.precyinit = PRECYINIT_0;
}
}
// //
// Step 8: // Step 8:
@ -1559,6 +1577,216 @@ fail:
return rc; return rc;
} }
#define MAX_IOLOGIC_SWBLOCK 4
#define MAX_IOLOGIC_BITS 4
struct iologic_sw_pos
{
const char* to[MAX_IOLOGIC_SWBLOCK];
const char* from[MAX_IOLOGIC_SWBLOCK];
int minor[MAX_IOLOGIC_BITS];
int b64[MAX_IOLOGIC_BITS];
};
// todo: can we assume the maximum range for iologic
// minors to be 21..29? that would be a total of
// 9*64=675 bits for ilogic/ologic/iodelay?
struct iologic_sw_pos s_left_io_swpos[] = { {{0}} };
struct iologic_sw_pos s_right_io_swpos[] = { {{0}} };
struct iologic_sw_pos s_top_outer_io_swpos[] = { {{0}} };
struct iologic_sw_pos s_top_inner_io_swpos[] = { {{0}} };
struct iologic_sw_pos s_bot_inner_io_swpos[] =
{
// input
{{"D_ILOGIC_IDATAIN_IODELAY_S"},
{"BIOI_INNER_IBUF0"},
{23, 23, -1},
{28, 29}},
{{"D_ILOGIC_SITE"},
{"D_ILOGIC_IDATAIN_IODELAY"},
{26, -1},
{20}},
{{"D_ILOGIC_SITE_S"},
{"D_ILOGIC_IDATAIN_IODELAY_S"},
{26, -1},
{23}},
{{"DFB_ILOGIC_SITE"},
{"D_ILOGIC_SITE"},
{28, -1},
{63}},
{{"DFB_ILOGIC_SITE_S"},
{"D_ILOGIC_SITE_S"},
{28, -1},
{0}},
{{"FABRICOUT_ILOGIC_SITE"},
{"D_ILOGIC_SITE"},
{29, -1},
{49}},
{{"FABRICOUT_ILOGIC_SITE_S"},
{"D_ILOGIC_SITE_S"},
{29, -1},
{14}},
// output
{{"OQ_OLOGIC_SITE", "BIOI_INNER_O0"},
{"D1_OLOGIC_SITE", "OQ_OLOGIC_SITE"},
{26, 27, 28, -1},
{40, 21, 57}},
{{"OQ_OLOGIC_SITE_S", "BIOI_INNER_O1"},
{"D1_OLOGIC_SITE_S", "OQ_OLOGIC_SITE_S"},
{26, 27, 28, -1},
{43, 56, 6}},
{{"IOI_LOGICOUT0"}, {"IOI_INTER_LOGICOUT0"}, {-1}},
{{"IOI_LOGICOUT7"}, {"IOI_INTER_LOGICOUT7"}, {-1}},
{{"IOI_INTER_LOGICOUT0"}, {"FABRICOUT_ILOGIC_SITE"}, {-1}},
{{"IOI_INTER_LOGICOUT7"}, {"FABRICOUT_ILOGIC_SITE_S"}, {-1}},
{{"D_ILOGIC_IDATAIN_IODELAY"}, {"BIOI_INNER_IBUF0"}, {-1}},
{{"D_ILOGIC_IDATAIN_IODELAY_S"}, {"BIOI_INNER_IBUF1"}, {-1}},
{{"D1_OLOGIC_SITE"}, {"IOI_LOGICINB31"}, {-1}},
{{0}}
};
struct iologic_sw_pos s_bot_outer_io_swpos[] =
{
// input
{{"D_ILOGIC_IDATAIN_IODELAY_S"},
{"BIOI_OUTER_IBUF0"},
{23, 23, -1},
{28, 29}},
{{"D_ILOGIC_SITE"},
{"D_ILOGIC_IDATAIN_IODELAY"},
{26, -1},
{20}},
{{"D_ILOGIC_SITE_S"},
{"D_ILOGIC_IDATAIN_IODELAY_S"},
{26, -1},
{23}},
{{"DFB_ILOGIC_SITE"},
{"D_ILOGIC_SITE"},
{28, -1},
{63}},
{{"DFB_ILOGIC_SITE_S"},
{"D_ILOGIC_SITE_S"},
{28, -1},
{0}},
{{"FABRICOUT_ILOGIC_SITE"},
{"D_ILOGIC_SITE"},
{29, -1},
{49}},
{{"FABRICOUT_ILOGIC_SITE_S"},
{"D_ILOGIC_SITE_S"},
{29, -1},
{14}},
// output
{{"OQ_OLOGIC_SITE", "BIOI_OUTER_O0"},
{"D1_OLOGIC_SITE", "OQ_OLOGIC_SITE"},
{26, 27, 28, -1},
{40, 21, 57}},
{{"OQ_OLOGIC_SITE_S", "BIOI_OUTER_O1"},
{"D1_OLOGIC_SITE_S", "OQ_OLOGIC_SITE_S"},
{26, 27, 28, -1},
{43, 56, 6}},
{{"IOI_LOGICOUT0"}, {"IOI_INTER_LOGICOUT0"}, {-1}},
{{"IOI_LOGICOUT7"}, {"IOI_INTER_LOGICOUT7"}, {-1}},
{{"IOI_INTER_LOGICOUT0"}, {"FABRICOUT_ILOGIC_SITE"}, {-1}},
{{"IOI_INTER_LOGICOUT7"}, {"FABRICOUT_ILOGIC_SITE_S"}, {-1}},
{{"D_ILOGIC_IDATAIN_IODELAY"}, {"BIOI_INNER_IBUF0"}, {-1}},
{{"D_ILOGIC_IDATAIN_IODELAY_S"}, {"BIOI_INNER_IBUF1"}, {-1}},
{{"D1_OLOGIC_SITE"}, {"IOI_LOGICINB31"}, {-1}},
{{0}}
};
static int extract_iologic_switches(struct extract_state* es, int y, int x)
{
int row_num, row_pos, bit_in_frame, i, j, rc;
uint8_t* minor0_p;
struct iologic_sw_pos* sw_pos;
str16_t from_str_i, to_str_i;
swidx_t sw_idx;
// From y/x coordinate, determine major, row, bit offset
// in frame (v64_i) and pointer to first minor.
is_in_row(es->model, y, &row_num, &row_pos);
if (row_num == -1 || row_pos == -1
|| row_pos == HCLK_POS) FAIL(EINVAL);
if (row_pos > HCLK_POS)
bit_in_frame = (row_pos-1)*64 + XC6_HCLK_BITS;
else
bit_in_frame = row_pos*64;
minor0_p = get_first_minor(es->bits, row_num, es->model->x_major[x]);
if (x < LEFT_SIDE_WIDTH) {
if (x != LEFT_IO_DEVS) FAIL(EINVAL);
sw_pos = s_left_io_swpos;
} else if (x >= es->model->x_width-RIGHT_SIDE_WIDTH) {
if (x != es->model->x_width - RIGHT_IO_DEVS_O) FAIL(EINVAL);
sw_pos = s_right_io_swpos;
} else if (y == TOP_OUTER_IO)
sw_pos = s_top_outer_io_swpos;
else if (y == TOP_INNER_IO)
sw_pos = s_top_inner_io_swpos;
else if (y == es->model->y_height-BOT_INNER_IO)
sw_pos = s_bot_inner_io_swpos;
else if (y == es->model->y_height-BOT_OUTER_IO)
sw_pos = s_bot_outer_io_swpos;
else FAIL(EINVAL);
// Go through switches
for (i = 0; sw_pos[i].to[0]; i++) {
for (j = 0; sw_pos[i].minor[j] != -1; j++) {
if (!frame_get_bit(&minor0_p[sw_pos[i].minor[j]
*FRAME_SIZE], bit_in_frame+sw_pos[i].b64[j]))
break;
}
if (!j || sw_pos[i].minor[j] != -1)
continue;
for (j = 0; j < MAX_IOLOGIC_SWBLOCK && sw_pos[i].to[j]; j++) {
from_str_i = strarray_find(&es->model->str, sw_pos[i].from[j]);
to_str_i = strarray_find(&es->model->str, sw_pos[i].to[j]);
if (from_str_i == STRIDX_NO_ENTRY
|| to_str_i == STRIDX_NO_ENTRY)
FAIL(EINVAL);
sw_idx = fpga_switch_lookup(es->model, y, x,
from_str_i, to_str_i);
if (sw_idx == NO_SWITCH) FAIL(EINVAL);
if (es->num_yx_pos >= MAX_YX_SWITCHES)
{ FAIL(ENOTSUP); }
es->yx_pos[es->num_yx_pos].y = y;
es->yx_pos[es->num_yx_pos].x = x;
es->yx_pos[es->num_yx_pos].idx = sw_idx;
es->num_yx_pos++;
}
for (j = 0; sw_pos[i].minor[j] != -1; j++)
frame_clear_bit(&minor0_p[sw_pos[i].minor[j]
*FRAME_SIZE], bit_in_frame+sw_pos[i].b64[j]);
}
// todo: we could implement an all-or-nothing system where
// the device bits are first copied into an u64 array,
// and switches rewound by resetting num_yx_pos - unless
// all bits have been processed...
return 0;
fail:
return rc;
}
static int extract_switches(struct extract_state* es) static int extract_switches(struct extract_state* es)
{ {
int x, y, rc; int x, y, rc;
@ -1579,6 +1807,11 @@ static int extract_switches(struct extract_state* es)
rc = extract_logic_switches(es, y, x); rc = extract_logic_switches(es, y, x);
if (rc) FAIL(rc); if (rc) FAIL(rc);
} }
// iologic switches
if (has_device(es->model, y, x, DEV_ILOGIC)) {
rc = extract_iologic_switches(es, y, x);
if (rc) FAIL(rc);
}
} }
} }
return 0; return 0;
@ -1714,92 +1947,6 @@ fail:
return rc; return rc;
} }
#define MAX_IOLOGIC_SWBLOCK 4
#define MAX_IOLOGIC_BITS 4
struct iologic_sw_pos
{
const char* to[MAX_IOLOGIC_SWBLOCK];
const char* from[MAX_IOLOGIC_SWBLOCK];
int minor[MAX_IOLOGIC_BITS];
int b64[MAX_IOLOGIC_BITS];
};
struct iologic_sw_pos s_left_io_swpos[] = { {{0}} };
struct iologic_sw_pos s_right_io_swpos[] = { {{0}} };
struct iologic_sw_pos s_top_outer_io_swpos[] = { {{0}} };
struct iologic_sw_pos s_top_inner_io_swpos[] = { {{0}} };
struct iologic_sw_pos s_bot_inner_io_swpos[] =
{
// input
{{"D_ILOGIC_IDATAIN_IODELAY_S"}, {"BIOI_INNER_IBUF0"},
{23, 23, -1},
{28, 29}},
{{"D_ILOGIC_SITE"}, {"D_ILOGIC_IDATAIN_IODELAY"}, {26, -1}, {20}},
{{"D_ILOGIC_SITE_S"}, {"D_ILOGIC_IDATAIN_IODELAY_S"}, {26, -1}, {23}},
{{"DFB_ILOGIC_SITE"}, {"D_ILOGIC_SITE"}, {28, -1}, {63}},
{{"DFB_ILOGIC_SITE_S"}, {"D_ILOGIC_SITE_S"}, {28, -1}, {0}},
{{"FABRICOUT_ILOGIC_SITE"}, {"D_ILOGIC_SITE"}, {29, -1}, {49}},
{{"FABRICOUT_ILOGIC_SITE_S"}, {"D_ILOGIC_SITE_S"}, {29, -1}, {14}},
// output
{{"OQ_OLOGIC_SITE", "BIOI_INNER_O0"},
{"D1_OLOGIC_SITE", "OQ_OLOGIC_SITE"},
{26, 27, 28, -1},
{40, 21, 57}},
{{"OQ_OLOGIC_SITE_S", "BIOI_INNER_O1"},
{"D1_OLOGIC_SITE_S", "OQ_OLOGIC_SITE_S"},
{26, 27, 28, -1},
{43, 56, 6}},
{{"IOI_LOGICOUT0"}, {"IOI_INTER_LOGICOUT0"}, {-1}},
{{"IOI_LOGICOUT7"}, {"IOI_INTER_LOGICOUT7"}, {-1}},
{{"IOI_INTER_LOGICOUT0"}, {"FABRICOUT_ILOGIC_SITE"}, {-1}},
{{"IOI_INTER_LOGICOUT7"}, {"FABRICOUT_ILOGIC_SITE_S"}, {-1}},
{{"D_ILOGIC_IDATAIN_IODELAY"}, {"BIOI_INNER_IBUF0"}, {-1}},
{{"D_ILOGIC_IDATAIN_IODELAY_S"}, {"BIOI_INNER_IBUF1"}, {-1}},
{{"D1_OLOGIC_SITE"}, {"IOI_LOGICINB31"}, {-1}},
{{0}}
};
struct iologic_sw_pos s_bot_outer_io_swpos[] =
{
// input
{{"D_ILOGIC_IDATAIN_IODELAY_S"}, {"BIOI_OUTER_IBUF0"},
{23, 23, -1},
{28, 29}},
{{"D_ILOGIC_SITE"}, {"D_ILOGIC_IDATAIN_IODELAY"}, {26, -1}, {20}},
{{"D_ILOGIC_SITE_S"}, {"D_ILOGIC_IDATAIN_IODELAY_S"}, {26, -1}, {23}},
{{"DFB_ILOGIC_SITE"}, {"D_ILOGIC_SITE"}, {28, -1}, {63}},
{{"DFB_ILOGIC_SITE_S"}, {"D_ILOGIC_SITE_S"}, {28, -1}, {0}},
{{"FABRICOUT_ILOGIC_SITE"}, {"D_ILOGIC_SITE"}, {29, -1}, {49}},
{{"FABRICOUT_ILOGIC_SITE_S"}, {"D_ILOGIC_SITE_S"}, {29, -1}, {14}},
// output
{{"OQ_OLOGIC_SITE", "BIOI_OUTER_O0"},
{"D1_OLOGIC_SITE", "OQ_OLOGIC_SITE"},
{26, 27, 28, -1},
{40, 21, 57}},
{{"OQ_OLOGIC_SITE_S", "BIOI_OUTER_O1"},
{"D1_OLOGIC_SITE_S", "OQ_OLOGIC_SITE_S"},
{26, 27, 28, -1},
{43, 56, 6}},
{{"OQ_OLOGIC_SITE", "BIOI_OUTER_O0"},
{"D1_OLOGIC_SITE", "OQ_OLOGIC_SITE"},
{26, 27, 28, -1},
{40, 21, 57}},
{{"IOI_LOGICOUT0"}, {"IOI_INTER_LOGICOUT0"}, {-1}},
{{"IOI_LOGICOUT7"}, {"IOI_INTER_LOGICOUT7"}, {-1}},
{{"IOI_INTER_LOGICOUT0"}, {"FABRICOUT_ILOGIC_SITE"}, {-1}},
{{"IOI_INTER_LOGICOUT7"}, {"FABRICOUT_ILOGIC_SITE_S"}, {-1}},
{{"D_ILOGIC_IDATAIN_IODELAY"}, {"BIOI_INNER_IBUF0"}, {-1}},
{{"D_ILOGIC_IDATAIN_IODELAY_S"}, {"BIOI_INNER_IBUF1"}, {-1}},
{{"D1_OLOGIC_SITE"}, {"IOI_LOGICINB31"}, {-1}},
{{0}}
};
struct str_sw struct str_sw
{ {
const char* from_str; const char* from_str;

View File

@ -762,6 +762,8 @@ static void printf_v64_mi20(const uint8_t* bits, int row, int major)
if (u64 & (1ULL << i)) if (u64 & (1ULL << i))
num_bits_on++; num_bits_on++;
} }
// this is most helpful for bits 24:39 which are
// part of logic device configuration
if (num_bits_on < 5) { if (num_bits_on < 5) {
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
if (!(u64 & (1ULL << i))) if (!(u64 & (1ULL << i)))
@ -841,13 +843,12 @@ static int dump_maj_right(const uint8_t* bits, int row, int major)
return 0; return 0;
} }
static int dump_maj_center(const uint8_t* bits, int row, int major) static int dump_maj_logic(const uint8_t* bits, int row, int major)
{ {
int minor, i; const struct xc_info* xci = xc_info(XC6SLX9);
int minor, i, logdev_start, logdev_end;
if (get_major_minors(XC6SLX9, major) != 31) HERE(); for (minor = 0; minor < xci->majors[major].minors; minor++)
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor); printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
// 0:19 routing minor pairs // 0:19 routing minor pairs
@ -857,102 +858,89 @@ static int dump_maj_center(const uint8_t* bits, int row, int major)
// mi20 as 64-char 0/1 string // mi20 as 64-char 0/1 string
printf_v64_mi20(&bits[20*FRAME_SIZE], row, major); printf_v64_mi20(&bits[20*FRAME_SIZE], row, major);
// L devices logdev_start = 0;
for (i = 0; i < 16; i++) { logdev_end = 15;
printf_lut(bits, row, major, 21, i*2); if (xci->majors[major].flags & XC_MAJ_TOP_BOT_IO) {
printf_lut(bits, row, major, 23, i*2); if (row == xc_info(XC6SLX9)->num_rows-1)
printf_lut(bits, row, major, 21, i*2+1); logdev_start += TOPBOT_IO_ROWS;
printf_lut(bits, row, major, 23, i*2+1); else if (!row)
logdev_end -= TOPBOT_IO_ROWS;
} }
printf_frames(&bits[25*FRAME_SIZE], /*max_frames*/ 1,
row, major, 25, /*print_empty*/ 0, /*no_clock*/ 1);
// X devices
for (i = 0; i < 16; i++) {
printf_lut(bits, row, major, 26, i*2);
printf_lut(bits, row, major, 28, i*2);
printf_lut(bits, row, major, 26, i*2+1);
printf_lut(bits, row, major, 28, i*2+1);
}
printf_frames(&bits[30*FRAME_SIZE], /*max_frames*/ 1,
row, major, 30, /*print_empty*/ 0, /*no_clock*/ 1);
return 0;
}
static int dump_maj_logic_xm(const uint8_t* bits, int row, int major) if (xci->majors[major].flags & XC_MAJ_XM) {
{ if (xci->majors[major].minors != 31) HERE();
int minor, i;
if (get_major_minors(XC6SLX9, major) != 31) HERE();
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
// 0:19 routing minor pairs
for (i = 0; i < 10; i++)
printf_routing_2minors(&bits[i*2*FRAME_SIZE], row, major, i*2);
// mi20 as 64-char 0/1 string
printf_v64_mi20(&bits[20*FRAME_SIZE], row, major);
// todo: some logic device configuration bits are also in mi20
// todo: the top and bottom two luts should be skipped in !no_io cols
// M devices // M devices
for (i = 0; i < 16; i++) { if (logdev_start)
printf_extrabits(bits, 21, 2, 0, logdev_start*64, row, major);
for (i = logdev_start; i <= logdev_end; i++) {
printf_lut(bits, row, major, 21, i*2); printf_lut(bits, row, major, 21, i*2);
printf_lut(bits, row, major, 21, i*2+1); printf_lut(bits, row, major, 21, i*2+1);
} }
if (logdev_end < 15)
printf_extrabits(bits, 21, 2, i*64 + XC6_HCLK_BITS, (15-logdev_end)*64, row, major);
printf_frames(&bits[23*FRAME_SIZE], /*max_frames*/ 1, printf_frames(&bits[23*FRAME_SIZE], /*max_frames*/ 1,
row, major, 23, /*print_empty*/ 0, /*no_clock*/ 1); row, major, 23, /*print_empty*/ 0, /*no_clock*/ 1);
for (i = 0; i < 16; i++) { if (logdev_start)
printf_extrabits(bits, 24, 2, 0, logdev_start*64, row, major);
for (i = logdev_start; i <= logdev_end; i++) {
printf_lut(bits, row, major, 24, i*2); printf_lut(bits, row, major, 24, i*2);
printf_lut(bits, row, major, 24, i*2+1); printf_lut(bits, row, major, 24, i*2+1);
} }
if (logdev_end < 15)
printf_extrabits(bits, 24, 2, i*64 + XC6_HCLK_BITS, (15-logdev_end)*64, row, major);
// X devices // X devices
printf_frames(&bits[26*FRAME_SIZE], /*max_frames*/ 1, printf_frames(&bits[26*FRAME_SIZE], /*max_frames*/ 1,
row, major, 26, /*print_empty*/ 0, /*no_clock*/ 1); row, major, 26, /*print_empty*/ 0, /*no_clock*/ 1);
for (i = 0; i < 16; i++) { if (logdev_start)
printf_extrabits(bits, 27, 4, 0, logdev_start*64, row, major);
for (i = logdev_start; i <= logdev_end; i++) {
printf_lut(bits, row, major, 27, i*2); printf_lut(bits, row, major, 27, i*2);
printf_lut(bits, row, major, 29, i*2); printf_lut(bits, row, major, 29, i*2);
printf_lut(bits, row, major, 27, i*2+1); printf_lut(bits, row, major, 27, i*2+1);
printf_lut(bits, row, major, 29, i*2+1); printf_lut(bits, row, major, 29, i*2+1);
} }
return 0; if (logdev_end < 15)
} printf_extrabits(bits, 27, 4, i*64 + XC6_HCLK_BITS, (15-logdev_end)*64, row, major);
} else if (xci->majors[major].flags & (XC_MAJ_XL|XC_MAJ_CENTER)) {
static int dump_maj_logic_xl(const uint8_t* bits, int row, int major)
{
int minor, i;
if (get_major_minors(XC6SLX9, major) != 30) HERE();
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
// 0:19 routing minor pairs
for (i = 0; i < 10; i++)
printf_routing_2minors(&bits[i*2*FRAME_SIZE], row, major, i*2);
// mi20 as 64-char 0/1 string
printf_v64_mi20(&bits[20*FRAME_SIZE], row, major);
// L devices // L devices
for (i = 0; i < 16; i++) { if (logdev_start)
printf_extrabits(bits, 21, 4, 0, logdev_start*64, row, major);
for (i = logdev_start; i <= logdev_end; i++) {
printf_lut(bits, row, major, 21, i*2); printf_lut(bits, row, major, 21, i*2);
printf_lut(bits, row, major, 23, i*2); printf_lut(bits, row, major, 23, i*2);
printf_lut(bits, row, major, 21, i*2+1); printf_lut(bits, row, major, 21, i*2+1);
printf_lut(bits, row, major, 23, i*2+1); printf_lut(bits, row, major, 23, i*2+1);
} }
if (logdev_end < 15)
printf_extrabits(bits, 21, 4, i*64 + XC6_HCLK_BITS, (15-logdev_end)*64, row, major);
printf_frames(&bits[25*FRAME_SIZE], /*max_frames*/ 1, printf_frames(&bits[25*FRAME_SIZE], /*max_frames*/ 1,
row, major, 25, /*print_empty*/ 0, /*no_clock*/ 1); row, major, 25, /*print_empty*/ 0, /*no_clock*/ 1);
// X devices // X devices
for (i = 0; i < 16; i++) { if (logdev_start)
printf_extrabits(bits, 26, 4, 0, logdev_start*64, row, major);
for (i = logdev_start; i <= logdev_end; i++) {
printf_lut(bits, row, major, 26, i*2); printf_lut(bits, row, major, 26, i*2);
printf_lut(bits, row, major, 28, i*2); printf_lut(bits, row, major, 28, i*2);
printf_lut(bits, row, major, 26, i*2+1); printf_lut(bits, row, major, 26, i*2+1);
printf_lut(bits, row, major, 28, i*2+1); printf_lut(bits, row, major, 28, i*2+1);
} }
if (logdev_end < 15)
printf_extrabits(bits, 26, 4, i*64 + XC6_HCLK_BITS, (15-logdev_end)*64, row, major);
// one extra minor in the center major
if (xci->majors[major].flags & XC_MAJ_CENTER) {
if (xci->majors[major].minors != 31) HERE();
printf_frames(&bits[30*FRAME_SIZE], /*max_frames*/ 1,
row, major, 30, /*print_empty*/ 0, /*no_clock*/ 1);
} else { // XL
if (xci->majors[major].minors != 30) HERE();
}
} else
HERE();
return 0; return 0;
} }
@ -1022,13 +1010,18 @@ static int dump_maj_macc(const uint8_t* bits, int row, int major)
static int dump_bits(struct fpga_config* cfg) static int dump_bits(struct fpga_config* cfg)
{ {
int row, major, off, rc; int idcode, num_rows, row, major, off, rc;
if (cfg->idcode_reg == -1) FAIL(EINVAL);
idcode = cfg->reg[cfg->idcode_reg].int_v;
num_rows = xc_num_rows(idcode);
if (num_rows < 1) FAIL(EINVAL);
// type0 // type0
for (major = 0; major <= get_rightside_major(XC6SLX9); major++) { for (major = 0; major <= get_rightside_major(idcode); major++) {
for (row = 3; row >= 0; row--) { for (row = num_rows-1; row >= 0; row--) {
off = (row*get_frames_per_row(XC6SLX9) + get_major_framestart(XC6SLX9, major)) * FRAME_SIZE; off = (row*get_frames_per_row(idcode) + get_major_framestart(idcode, major)) * FRAME_SIZE;
switch (get_major_type(cfg->reg[cfg->idcode_reg].int_v, major)) { switch (get_major_type(idcode, major)) {
case MAJ_ZERO: case MAJ_ZERO:
rc = dump_maj_zero(&cfg->bits.d[off], row, major); rc = dump_maj_zero(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc); if (rc) FAIL(rc);
@ -1041,16 +1034,10 @@ static int dump_bits(struct fpga_config* cfg)
rc = dump_maj_right(&cfg->bits.d[off], row, major); rc = dump_maj_right(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc); if (rc) FAIL(rc);
break; break;
case MAJ_CENTER:
rc = dump_maj_center(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc);
break;
case MAJ_LOGIC_XM: case MAJ_LOGIC_XM:
rc = dump_maj_logic_xm(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc);
break;
case MAJ_LOGIC_XL: case MAJ_LOGIC_XL:
rc = dump_maj_logic_xl(&cfg->bits.d[off], row, major); case MAJ_CENTER:
rc = dump_maj_logic(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc); if (rc) FAIL(rc);
break; break;
case MAJ_BRAM: case MAJ_BRAM:
@ -1113,7 +1100,7 @@ int dump_config(struct fpga_config* cfg, int flags)
if (rc) FAIL(rc); if (rc) FAIL(rc);
rc = dump_bram(cfg); rc = dump_bram(cfg);
if (rc) FAIL(rc); if (rc) FAIL(rc);
printf_iob(cfg->bits.d, cfg->bits.len, printf_type2(cfg->bits.d, cfg->bits.len,
BRAM_DATA_START + BRAM_DATA_LEN, 896*2/8); BRAM_DATA_START + BRAM_DATA_LEN, 896*2/8);
if (flags & DUMP_CRC) if (flags & DUMP_CRC)
printf("auto-crc 0x%X\n", cfg->auto_crc); printf("auto-crc 0x%X\n", cfg->auto_crc);

View File

@ -7,7 +7,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <errno.h> #include <errno.h>
#include "helper.h" #include "model.h"
#include "parts.h" #include "parts.h"
const char* bitstr(uint32_t value, int digits) const char* bitstr(uint32_t value, int digits)
@ -230,16 +230,22 @@ const char* bool_bits2str(uint64_t u64, int num_bits)
int str_end, first_op, bit_width; int str_end, first_op, bit_width;
static char str[2048]; static char str[2048];
if (num_bits == 64) if (!u64) return "0";
if (num_bits == 64) {
if (u64 == 0xFFFFFFFFFFFFFFFFULL) return "1";
bit_width = 6; bit_width = 6;
else if (num_bits == 32) } else if (num_bits == 32) {
bit_width = 5; if (u64 & 0xFFFFFFFF00000000ULL) {
else { // upper 32 bits should be 0
HERE();
return "0";
}
if (u64 == 0x00000000FFFFFFFFULL) return "1";
bit_width = 5;
} else {
HERE(); HERE();
return "0"; return "0";
} }
if (!u64) return "0";
if (u64 == 0xFFFFFFFFFFFFFFFFULL) return "1";
memset(mt, 0, sizeof(mt)); memset(mt, 0, sizeof(mt));
memset(mt_size, 0, sizeof(mt_size)); memset(mt_size, 0, sizeof(mt_size));
@ -350,7 +356,7 @@ int parse_boolexpr(const char* expr, uint64_t* lut)
return 0; return 0;
} }
int printf_iob(uint8_t* d, int len, int inpos, int num_entries) int printf_type2(uint8_t* d, int len, int inpos, int num_entries)
{ {
int i, num_printed; int i, num_printed;
uint64_t u64; uint64_t u64;
@ -359,7 +365,7 @@ int printf_iob(uint8_t* d, int len, int inpos, int num_entries)
for (i = 0; i < num_entries; i++) { for (i = 0; i < num_entries; i++) {
u64 = frame_get_u64(&d[inpos+i*8]); u64 = frame_get_u64(&d[inpos+i*8]);
if (u64) { if (u64) {
printf("iob i%i 0x%016lX\n", i, u64); printf("type2 i%i 0x%016lX\n", i, u64);
num_printed++; num_printed++;
} }
} }
@ -681,13 +687,19 @@ int clb_empty(uint8_t* maj_bits, int idx)
void printf_extrabits(const uint8_t* maj_bits, int start_minor, int num_minors, void printf_extrabits(const uint8_t* maj_bits, int start_minor, int num_minors,
int start_bit, int num_bits, int row, int major) int start_bit, int num_bits, int row, int major)
{ {
int minor, bit; int minor, bit, bit_no_clk;
for (minor = start_minor; minor < start_minor + num_minors; minor++) { for (minor = start_minor; minor < start_minor + num_minors; minor++) {
for (bit = start_bit; bit < start_bit + num_bits; bit++) { for (bit = start_bit; bit < start_bit + num_bits; bit++) {
if (frame_get_bit(&maj_bits[minor*130], bit)) if (frame_get_bit(&maj_bits[minor*FRAME_SIZE], bit)) {
printf("r%i ma%i extra mi%i bit %i\n", bit_no_clk = bit;
row, major, minor, bit); if (bit_no_clk >= 528)
bit_no_clk -= XC6_HCLK_BITS;
printf("r%i ma%i mi%i bit %i 64*%i+%i 256*%i+%i\n",
row, major, minor, bit,
bit_no_clk/64, bit_no_clk%64,
bit_no_clk/256, bit_no_clk%256);
}
} }
} }
} }
@ -1049,3 +1061,20 @@ void strarray_free(struct hashed_strarray* array)
free(array->index_to_bin); free(array->index_to_bin);
array->index_to_bin = 0; array->index_to_bin = 0;
} }
int row_pos_to_y(int num_rows, int row, int pos)
{
int y;
if (row >= num_rows) {
HERE();
return -1;
}
y = TOP_IO_TILES;
if (row < num_rows/2)
y++; // below center
y += num_rows - row - 1; // hclk in full rows from top
if (pos >= HALF_ROW)
y++; // hclk in row
return y;
}

View File

@ -64,7 +64,7 @@ const char* bool_bits2str(uint64_t u64, int num_bits);
int parse_boolexpr(const char* expr, uint64_t* lut); int parse_boolexpr(const char* expr, uint64_t* lut);
int printf_iob(uint8_t* d, int len, int inpos, int num_entries); int printf_type2(uint8_t* d, int len, int inpos, int num_entries);
void printf_ramb16_data(uint8_t* bits, int inpos); void printf_ramb16_data(uint8_t* bits, int inpos);
int is_empty(const uint8_t* d, int l); int is_empty(const uint8_t* d, int l);
@ -151,3 +151,5 @@ int strarray_add(struct hashed_strarray* array, const char* str, int* idx);
// anymore, only strarray_lookup(). // anymore, only strarray_lookup().
int strarray_stash(struct hashed_strarray* array, const char* str, int idx); int strarray_stash(struct hashed_strarray* array, const char* str, int idx);
int strarray_used_slots(struct hashed_strarray* array); int strarray_used_slots(struct hashed_strarray* array);
int row_pos_to_y(int num_rows, int row, int pos);

View File

@ -602,9 +602,9 @@ void is_in_row(const struct fpga_model* model, int y,
if (row_num) *row_num = -1; if (row_num) *row_num = -1;
if (row_pos) *row_pos = -1; if (row_pos) *row_pos = -1;
if (y < 2) return; if (y < TOP_IO_TILES) return;
// normalize y to beginning of rows // normalize y to beginning of rows
y -= 2; y -= TOP_IO_TILES;
// calculate distance to center and check // calculate distance to center and check
// that y is not pointing to the center // that y is not pointing to the center

View File

@ -91,6 +91,284 @@ int find_iob_sitename(int idcode, const char* name)
return -1; return -1;
} }
int xc_num_rows(int idcode)
{
if ((idcode & IDCODE_MASK) != XC6SLX9) {
HERE();
return -1;
}
return NUM_ROWS;
}
const struct xc_info* xc_info(int idcode)
{
static const struct xc_info xc6slx9_info = {
.num_rows = 4,
.left_wiring =
/* row 3 */ "UWUWUWUW" "WWWWUUUU" \
/* row 2 */ "UUUUUUUU" "WWWWWWUU" \
/* row 1 */ "WWWUUWUU" "WUUWUUWU" \
/* row 0 */ "UWUUWUUW" "UUWWWWUU",
.right_wiring =
/* row 3 */ "UUWWUWUW" "WWWWUUUU" \
/* row 2 */ "UUUUUUUU" "WWWWWWUU" \
/* row 1 */ "WWWUUWUU" "WUUWUUWU" \
/* row 0 */ "UWUUWUUW" "UUWWWWUU",
.major_str = "M L Bg M L D M R M Ln M L Bg M L",
.num_majors = 18,
.majors = {
// maj_zero: 505 bytes = extra 8-bit for each minor?
[0] = { XC_MAJ_ZERO, 4 },
[1] = { XC_MAJ_LEFT, 30 },
[2] = { XC_MAJ_XM | XC_MAJ_TOP_BOT_IO, 31 },
[3] = { XC_MAJ_XL | XC_MAJ_TOP_BOT_IO, 30 },
[4] = { XC_MAJ_BRAM | XC_MAJ_GCLK_SEP, 25 },
[5] = { XC_MAJ_XM | XC_MAJ_TOP_BOT_IO, 31 },
[6] = { XC_MAJ_XL | XC_MAJ_TOP_BOT_IO, 30 },
[7] = { XC_MAJ_MACC, 24 },
[8] = { XC_MAJ_XM | XC_MAJ_TOP_BOT_IO, 31 },
[9] = { XC_MAJ_CENTER | XC_MAJ_TOP_BOT_IO, 31 },
[10] = { XC_MAJ_XM | XC_MAJ_TOP_BOT_IO, 31 },
[11] = { XC_MAJ_XL, 30 },
[12] = { XC_MAJ_XM | XC_MAJ_TOP_BOT_IO, 31 },
[13] = { XC_MAJ_XL | XC_MAJ_TOP_BOT_IO, 30 },
[14] = { XC_MAJ_BRAM | XC_MAJ_GCLK_SEP, 25 },
[15] = { XC_MAJ_XM | XC_MAJ_TOP_BOT_IO, 31 },
[16] = { XC_MAJ_XL | XC_MAJ_TOP_BOT_IO, 30 },
[17] = { XC_MAJ_RIGHT, 30 }},
.num_type2 = 224,
.type2 = {
[0] = { XC_T2_IOB_PAD, 70 },
[1] = { XC_T2_IOB_PAD, 69 },
[2] = { XC_T2_IOB_PAD, 67 },
[3] = { XC_T2_IOB_PAD, 66 },
[4] = { XC_T2_IOB_PAD, 65 },
[5] = { XC_T2_IOB_PAD, 64 },
[6] = { XC_T2_IOB_PAD, 62 },
[7] = { XC_T2_IOB_PAD, 61 },
[8] = { XC_T2_IOB_PAD, 60 },
[9] = { XC_T2_IOB_PAD, 59 },
[10] = { XC_T2_IOB_PAD, 58 },
[11] = { XC_T2_IOB_PAD, 57 },
[12] = { XC_T2_IOB_UNBONDED, 113 },
[13] = { XC_T2_IOB_UNBONDED, 114 },
[14] = { XC_T2_IOB_UNBONDED, 115 },
[15] = { XC_T2_IOB_UNBONDED, 116 },
[16] = { XC_T2_IOB_UNBONDED, 117 },
[17] = { XC_T2_IOB_UNBONDED, 118 },
[18] = { XC_T2_IOB_PAD, 56 },
[19] = { XC_T2_IOB_PAD, 55 },
[20] = { XC_T2_CENTER },
[21] = { XC_T2_CENTER },
[22] = { XC_T2_CENTER },
[23] = { XC_T2_CENTER },
[24] = { XC_T2_CENTER },
[25] = { XC_T2_CENTER },
[26] = { XC_T2_IOB_PAD, 51 },
[27] = { XC_T2_IOB_PAD, 50 },
[28] = { XC_T2_IOB_UNBONDED, 123 },
[29] = { XC_T2_IOB_UNBONDED, 124 },
[30] = { XC_T2_IOB_UNBONDED, 125 },
[31] = { XC_T2_IOB_UNBONDED, 126 },
[32] = { XC_T2_IOB_UNBONDED, 127 },
[33] = { XC_T2_IOB_UNBONDED, 128 },
[34] = { XC_T2_IOB_UNBONDED, 129 },
[35] = { XC_T2_IOB_UNBONDED, 130 },
[36] = { XC_T2_IOB_UNBONDED, 131 },
[37] = { XC_T2_IOB_UNBONDED, 132 },
[38] = { XC_T2_IOB_PAD, 48 },
[39] = { XC_T2_IOB_PAD, 47 },
[40] = { XC_T2_IOB_PAD, 46 },
[41] = { XC_T2_IOB_PAD, 45 },
[42] = { XC_T2_IOB_PAD, 44 },
[43] = { XC_T2_IOB_PAD, 43 },
[44] = { XC_T2_IOB_UNBONDED, 139 },
[45] = { XC_T2_IOB_UNBONDED, 140 },
[46] = { XC_T2_IOB_PAD, 41 },
[47] = { XC_T2_IOB_PAD, 40 },
[48] = { XC_T2_IOB_PAD, 39 },
[49] = { XC_T2_IOB_PAD, 38 },
[50] = { XC_T2_IOB_PAD, 35 },
[51] = { XC_T2_IOB_PAD, 34 },
[52] = { XC_T2_IOB_PAD, 33 },
[53] = { XC_T2_IOB_PAD, 32 },
[54] = { XC_T2_IOB_UNBONDED, 149 },
[55] = { XC_T2_IOB_UNBONDED, 150 },
[56] = { XC_T2_IOB_UNBONDED, 151 },
[57] = { XC_T2_IOB_UNBONDED, 152 },
[58] = { XC_T2_IOB_UNBONDED, 153 },
[59] = { XC_T2_IOB_UNBONDED, 154 },
[60] = { XC_T2_IOB_UNBONDED, 155 },
[61] = { XC_T2_IOB_UNBONDED, 156 },
[62] = { XC_T2_IOB_UNBONDED, 157 },
[63] = { XC_T2_IOB_UNBONDED, 158 },
[64] = { XC_T2_IOB_PAD, 30 },
[65] = { XC_T2_IOB_PAD, 29 },
[66] = { XC_T2_IOB_PAD, 27 },
[67] = { XC_T2_IOB_PAD, 26 },
[68] = { XC_T2_IOB_UNBONDED, 163 },
[69] = { XC_T2_IOB_UNBONDED, 164 },
[70] = { XC_T2_IOB_UNBONDED, 165 },
[71] = { XC_T2_IOB_UNBONDED, 166 },
[72] = { XC_T2_IOB_UNBONDED, 167 },
[73] = { XC_T2_IOB_UNBONDED, 168 },
[74] = { XC_T2_IOB_PAD, 24 },
[75] = { XC_T2_IOB_PAD, 23 },
[76] = { XC_T2_IOB_PAD, 22 },
[77] = { XC_T2_IOB_PAD, 21 },
[78] = { XC_T2_CENTER },
[79] = { XC_T2_CENTER },
[80] = { XC_T2_CENTER },
[81] = { XC_T2_CENTER },
[82] = { XC_T2_CENTER },
[83] = { XC_T2_CENTER },
[84] = { XC_T2_IOB_PAD, 17 },
[85] = { XC_T2_IOB_PAD, 16 },
[86] = { XC_T2_IOB_PAD, 15 },
[87] = { XC_T2_IOB_PAD, 14 },
[88] = { XC_T2_IOB_UNBONDED, 177 },
[89] = { XC_T2_IOB_UNBONDED, 178 },
[90] = { XC_T2_IOB_UNBONDED, 179 },
[91] = { XC_T2_IOB_UNBONDED, 180 },
[92] = { XC_T2_IOB_UNBONDED, 181 },
[93] = { XC_T2_IOB_UNBONDED, 182 },
[94] = { XC_T2_IOB_UNBONDED, 183 },
[95] = { XC_T2_IOB_UNBONDED, 184 },
[96] = { XC_T2_IOB_PAD, 12 },
[97] = { XC_T2_IOB_PAD, 11 },
[98] = { XC_T2_IOB_PAD, 10 },
[99] = { XC_T2_IOB_PAD, 9 },
[100] = { XC_T2_IOB_PAD, 8 },
[101] = { XC_T2_IOB_PAD, 7 },
[102] = { XC_T2_IOB_PAD, 6 },
[103] = { XC_T2_IOB_PAD, 5 },
[104] = { XC_T2_IOB_UNBONDED, 193 },
[105] = { XC_T2_IOB_UNBONDED, 194 },
[106] = { XC_T2_IOB_UNBONDED, 195 },
[107] = { XC_T2_IOB_UNBONDED, 196 },
[108] = { XC_T2_IOB_UNBONDED, 197 },
[109] = { XC_T2_IOB_UNBONDED, 198 },
[110] = { XC_T2_IOB_PAD, 2 },
[111] = { XC_T2_IOB_PAD, 1 },
[112] = { XC_T2_IOB_PAD, 144 },
[113] = { XC_T2_IOB_PAD, 143 },
[114] = { XC_T2_IOB_PAD, 142 },
[115] = { XC_T2_IOB_PAD, 141 },
[116] = { XC_T2_IOB_PAD, 140 },
[117] = { XC_T2_IOB_PAD, 139 },
[118] = { XC_T2_IOB_PAD, 138 },
[119] = { XC_T2_IOB_PAD, 137 },
[120] = { XC_T2_IOB_UNBONDED, 9 },
[121] = { XC_T2_IOB_UNBONDED, 10 },
[122] = { XC_T2_IOB_UNBONDED, 11 },
[123] = { XC_T2_IOB_UNBONDED, 12 },
[124] = { XC_T2_IOB_UNBONDED, 13 },
[125] = { XC_T2_IOB_UNBONDED, 14 },
[126] = { XC_T2_IOB_UNBONDED, 15 },
[127] = { XC_T2_IOB_UNBONDED, 16 },
[128] = { XC_T2_IOB_UNBONDED, 17 },
[129] = { XC_T2_IOB_UNBONDED, 18 },
[130] = { XC_T2_IOB_UNBONDED, 19 },
[131] = { XC_T2_IOB_UNBONDED, 20 },
[132] = { XC_T2_IOB_PAD, 134 },
[133] = { XC_T2_IOB_PAD, 133 },
[134] = { XC_T2_IOB_PAD, 132 },
[135] = { XC_T2_IOB_PAD, 131 },
[136] = { XC_T2_CENTER },
[137] = { XC_T2_CENTER },
[138] = { XC_T2_CENTER },
[139] = { XC_T2_CENTER },
[140] = { XC_T2_CENTER },
[141] = { XC_T2_CENTER },
[142] = { XC_T2_IOB_PAD, 127 },
[143] = { XC_T2_IOB_PAD, 126 },
[144] = { XC_T2_IOB_PAD, 124 },
[145] = { XC_T2_IOB_PAD, 123 },
[146] = { XC_T2_IOB_UNBONDED, 29 },
[147] = { XC_T2_IOB_UNBONDED, 30 },
[148] = { XC_T2_IOB_UNBONDED, 31 },
[149] = { XC_T2_IOB_UNBONDED, 32 },
[150] = { XC_T2_IOB_UNBONDED, 33 },
[151] = { XC_T2_IOB_UNBONDED, 34 },
[152] = { XC_T2_IOB_PAD, 121 },
[153] = { XC_T2_IOB_PAD, 120 },
[154] = { XC_T2_IOB_PAD, 119 },
[155] = { XC_T2_IOB_PAD, 118 },
[156] = { XC_T2_IOB_PAD, 117 },
[157] = { XC_T2_IOB_PAD, 116 },
[158] = { XC_T2_IOB_PAD, 115 },
[159] = { XC_T2_IOB_PAD, 114 },
[160] = { XC_T2_IOB_PAD, 112 },
[161] = { XC_T2_IOB_PAD, 111 },
[162] = { XC_T2_IOB_PAD, 105 },
[163] = { XC_T2_IOB_PAD, 104 },
[164] = { XC_T2_IOB_UNBONDED, 47 },
[165] = { XC_T2_IOB_UNBONDED, 48 },
[166] = { XC_T2_IOB_UNBONDED, 49 },
[167] = { XC_T2_IOB_UNBONDED, 50 },
[168] = { XC_T2_IOB_UNBONDED, 51 },
[169] = { XC_T2_IOB_UNBONDED, 52 },
[170] = { XC_T2_IOB_PAD, 102 },
[171] = { XC_T2_IOB_PAD, 101 },
[172] = { XC_T2_IOB_PAD, 100 },
[173] = { XC_T2_IOB_PAD, 99 },
[174] = { XC_T2_IOB_PAD, 98 },
[175] = { XC_T2_IOB_PAD, 97 },
[176] = { XC_T2_IOB_UNBONDED, 59 },
[177] = { XC_T2_IOB_UNBONDED, 60 },
[178] = { XC_T2_IOB_UNBONDED, 61 },
[179] = { XC_T2_IOB_UNBONDED, 62 },
[180] = { XC_T2_IOB_UNBONDED, 63 },
[181] = { XC_T2_IOB_UNBONDED, 64 },
[182] = { XC_T2_IOB_UNBONDED, 65 },
[183] = { XC_T2_IOB_UNBONDED, 66 },
[184] = { XC_T2_IOB_UNBONDED, 67 },
[185] = { XC_T2_IOB_UNBONDED, 68 },
[186] = { XC_T2_IOB_PAD, 95 },
[187] = { XC_T2_IOB_PAD, 94 },
[188] = { XC_T2_IOB_PAD, 93 },
[189] = { XC_T2_IOB_PAD, 92 },
[190] = { XC_T2_CENTER },
[191] = { XC_T2_CENTER },
[192] = { XC_T2_CENTER },
[193] = { XC_T2_CENTER },
[194] = { XC_T2_CENTER },
[195] = { XC_T2_CENTER },
[196] = { XC_T2_IOB_PAD, 88 },
[197] = { XC_T2_IOB_PAD, 87 },
[198] = { XC_T2_IOB_PAD, 85 },
[199] = { XC_T2_IOB_PAD, 84 },
[200] = { XC_T2_IOB_UNBONDED, 77 },
[201] = { XC_T2_IOB_UNBONDED, 78 },
[202] = { XC_T2_IOB_PAD, 83 },
[203] = { XC_T2_IOB_PAD, 82 },
[204] = { XC_T2_IOB_PAD, 81 },
[205] = { XC_T2_IOB_PAD, 80 },
[206] = { XC_T2_IOB_PAD, 79 },
[207] = { XC_T2_IOB_PAD, 78 },
[208] = { XC_T2_IOB_UNBONDED, 85 },
[209] = { XC_T2_IOB_UNBONDED, 86 },
[210] = { XC_T2_IOB_UNBONDED, 87 },
[211] = { XC_T2_IOB_UNBONDED, 88 },
[212] = { XC_T2_IOB_UNBONDED, 89 },
[213] = { XC_T2_IOB_UNBONDED, 90 },
[214] = { XC_T2_IOB_UNBONDED, 91 },
[215] = { XC_T2_IOB_UNBONDED, 92 },
[216] = { XC_T2_IOB_UNBONDED, 93 },
[217] = { XC_T2_IOB_UNBONDED, 94 },
[218] = { XC_T2_IOB_UNBONDED, 95 },
[219] = { XC_T2_IOB_UNBONDED, 96 },
[220] = { XC_T2_IOB_UNBONDED, 97 },
[221] = { XC_T2_IOB_UNBONDED, 98 },
[222] = { XC_T2_IOB_PAD, 75 },
[223] = { XC_T2_IOB_PAD, 74 }}};
switch (idcode & IDCODE_MASK) {
case XC6SLX9: return &xc6slx9_info;
}
HERE();
return 0;
}
int get_major_minors(int idcode, int major) int get_major_minors(int idcode, int major)
{ {
static const int minors_per_major[] = // for slx9 static const int minors_per_major[] = // for slx9

View File

@ -23,6 +23,50 @@
#define XC6SLX100T 0x04031093 #define XC6SLX100T 0x04031093
#define XC6SLX150 0x0401D093 #define XC6SLX150 0x0401D093
#define XC_MAX_MAJORS 400
#define XC_MAX_TYPE2_ENTRIES 2000
#define XC_MAJ_ZERO 0x00000001
#define XC_MAJ_LEFT 0x00000002
#define XC_MAJ_CENTER 0x00000004
#define XC_MAJ_RIGHT 0x00000008
#define XC_MAJ_XM 0x00000010
#define XC_MAJ_XL 0x00000020
#define XC_MAJ_BRAM 0x00000040
#define XC_MAJ_MACC 0x00000080
#define XC_MAJ_TOP_BOT_IO 0x00000100
#define XC_MAJ_GCLK_SEP 0x00000200
struct xc_major_info
{
int flags;
int minors;
};
#define XC_T2_IOB_PAD 0x00000001
#define XC_T2_IOB_UNBONDED 0x00000002
#define XC_T2_CENTER 0x00000004
struct xc_type2_info
{
int flags;
int val;
};
struct xc_info
{
int num_rows;
const char* left_wiring;
const char* right_wiring;
const char* major_str;
int num_majors;
struct xc_major_info majors[XC_MAX_MAJORS];
int num_type2;
struct xc_type2_info type2[XC_MAX_TYPE2_ENTRIES];
};
const struct xc_info* xc_info(int idcode);
#define FRAME_SIZE 130 #define FRAME_SIZE 130
#define FRAMES_PER_ROW 505 // for slx4 and slx9 #define FRAMES_PER_ROW 505 // for slx4 and slx9
#define PADDING_FRAMES_PER_ROW 2 #define PADDING_FRAMES_PER_ROW 2
@ -130,6 +174,8 @@ const char* get_iob_sitename(int idcode, int idx);
// returns -1 if sitename not found // returns -1 if sitename not found
int find_iob_sitename(int idcode, const char* name); int find_iob_sitename(int idcode, const char* name);
int xc_num_rows(int idcode);
// The routing bitpos is relative to a tile, i.e. major (x) // The routing bitpos is relative to a tile, i.e. major (x)
// and row/v64_i (y) are defined outside. // and row/v64_i (y) are defined outside.
struct xc6_routing_bitpos struct xc6_routing_bitpos