carry chain fixes

This commit is contained in:
Wolfgang Spraul 2012-10-12 10:18:47 +02:00
parent 9c964f848e
commit c330b8e11f
9 changed files with 108 additions and 51 deletions

View File

@ -1012,7 +1012,7 @@ static int test_logic(struct test_state* tstate, int y, int x, int type_idx,
}
}
// add stub nets for each required pin
// add one stub net per required pin
dev = fdev_p(tstate->model, y, x, DEV_LOGIC, type_idx);
if (!dev) FAIL(EINVAL);
for (i = 0; i < dev->pinw_req_total; i++) {
@ -1022,6 +1022,30 @@ static int test_logic(struct test_state* tstate, int y, int x, int type_idx,
rc = fnet_add_port(tstate->model, pinw_nets[i], y, x,
DEV_LOGIC, type_idx, dev->pinw_req_for_cfg[i]);
if (rc) FAIL(rc);
if (dev->pinw_req_for_cfg[i] == LI_CIN) {
int connpt_dests_o, num_dests, cout_y, cout_x;
str16_t cout_str;
swidx_t cout_sw;
if ((fpga_connpt_find(tstate->model, y, x,
dev->pinw[LI_CIN], &connpt_dests_o,
&num_dests) == NO_CONN)
|| num_dests != 1) {
HERE();
} else {
fpga_conn_dest(tstate->model, y, x,
connpt_dests_o, &cout_y, &cout_x, &cout_str);
cout_sw = fpga_switch_first(tstate->model,
cout_y, cout_x, cout_str, SW_TO);
if (cout_sw == NO_SWITCH) HERE();
else {
rc = fnet_add_sw(tstate->model,
pinw_nets[i], cout_y, cout_x,
&cout_sw, /*num_sw*/ 1);
if (rc) FAIL(rc);
}
}
}
if ((dev->pinw_req_for_cfg[i] == LI_A6
&& dev->u.logic.a2d[LUT_A].lut5
&& *dev->u.logic.a2d[LUT_A].lut5)
@ -1247,7 +1271,8 @@ static int test_logic_config(struct test_state* tstate)
tstate->diff_to_null = 1;
y = 68;
// For cin/cout testing, pick a y that is not at the bottom.
y = 67;
for (x_i = 0; x_i < sizeof(x_enum)/sizeof(*x_enum); x_i++) {
for (type_i = 0; type_i < sizeof(idx_enum)/sizeof(*idx_enum); type_i++) {
for (lut = LUT_A; lut <= LUT_D; lut++) {
@ -1693,39 +1718,6 @@ int main(int argc, char** argv)
// for example: ./autotest 2>&1 | tee autotest.log
setvbuf(stdout, /*buf*/ 0, _IOLBF, /*size*/ 0);
#if 0
int lut_map1[64] = {63,62,61,60,59,58,57,56,55,54,53,52,51,50,
49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,
30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,
9,8,7,6,5,4,3,2,1,0};
//int bool_str2bits(const char* str, uint64_t* u64, int num_bits);
//const char* bool_bits2str(uint64_t u64, int num_bits);
{
uint64_t u64, u64_2;
rc = bool_str2bits("~A6*~A5*~A4*~A3*~A2*~A1", &u64, 64);
printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64));
rc = bool_str2bits("~A6*~A5*~A4*~A3*~A2*A1", &u64, 64);
printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64));
rc = bool_str2bits("A6*A5*A4*A3*A2*A1", &u64, 64);
printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64));
rc = bool_str2bits("A5*A4*A3*A2*A1", &u64, 32);
printf("rc %i u32 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 32));
rc = bool_str2bits("A4*A3", &u64, 32);
printf("rc %i u32 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 32));
rc = bool_str2bits("A1", &u64, 64);
printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64));
rc = bool_str2bits("A1", &u64, 32);
printf("rc %i u32 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 32));
u64 = 1;
u64_2 = map_bits(u64, 64, lut_map1);
printf("u %llX mapped %llX\n", u64, u64_2);
return 0;
}
#endif
if (argc < 2) {
printf_help(argv[0], available_tests);
return 0;

View File

@ -270,7 +270,9 @@ static int extract_iobs(struct extract_state* es)
iob_sitename = get_iob_sitename(XC6SLX9, i);
if (!iob_sitename) {
HERE();
// The space for 6 IOBs on all four sides
// (6*8 = 48 bytes, *4=192 bytes) is used
// for clocks etc, so we ignore them here.
continue;
}
rc = fpga_find_iob(es->model, iob_sitename, &iob_y, &iob_x, &iob_idx);
@ -1038,8 +1040,22 @@ static int extract_logic(struct extract_state* es)
// instantiate the logic devices.
//
if (mi20 || mi23_M || mi2526) {
HERE();
if (mi20) {
fprintf(stderr, "#E %s:%i y%02i x%02i l%i "
"mi20 0x%016lX\n",
__FILE__, __LINE__, y, x, l_col, mi20);
continue;
}
if (mi23_M) {
fprintf(stderr, "#E %s:%i y%02i x%02i l%i "
"mi23_M 0x%016lX\n",
__FILE__, __LINE__, y, x, l_col, mi23_M);
continue;
}
if (mi2526) {
fprintf(stderr, "#E %s:%i y%02i x%02i l%i "
"mi2526 0x%016lX\n",
__FILE__, __LINE__, y, x, l_col, mi2526);
continue;
}
@ -1452,12 +1468,54 @@ fail:
return rc;
}
static int extract_logic_switches(struct extract_state* es, int y, int x)
{
int row, row_pos, byte_off, minor, rc;
swidx_t sw_idx;
uint8_t* u8_p;
row = which_row(y, es->model);
row_pos = pos_in_row(y, es->model);
if (row == -1 || row_pos == -1 || row_pos == 8) FAIL(EINVAL);
if (row_pos > 8) row_pos--;
u8_p = get_first_minor(es->bits, row, es->model->x_major[x]);
byte_off = row_pos * 8;
if (row_pos >= 8) byte_off += HCLK_BYTES;
if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_M))
minor = 26;
else if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_L))
minor = 25;
else
FAIL(EINVAL);
if (frame_get_bit(u8_p + minor*FRAME_SIZE, byte_off*8 + XC6_ML_COUT_CIN_SW)) {
sw_idx = fpga_switch_lookup(es->model, y, x,
strarray_find(&es->model->str, "M_COUT"),
strarray_find(&es->model->str, "M_COUT_N"));
if (sw_idx == NO_SWITCH) { HERE(); return 0; }
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++;
frame_clear_bit(u8_p + minor*FRAME_SIZE, byte_off*8 + XC6_ML_COUT_CIN_SW);
}
return 0;
fail:
return rc;
}
static int extract_switches(struct extract_state* es)
{
int x, y, rc;
for (x = 0; x < es->model->x_width; x++) {
for (y = 0; y < es->model->y_height; y++) {
// routing switches
if (is_atx(X_ROUTING_COL, es->model, x)
&& y >= TOP_IO_TILES
&& y < es->model->y_height-BOT_IO_TILES
@ -1466,6 +1524,11 @@ static int extract_switches(struct extract_state* es)
rc = extract_routing_switches(es, y, x);
if (rc) FAIL(rc);
}
// logic switches
if (has_device(es->model, y, x, DEV_LOGIC)) {
rc = extract_logic_switches(es, y, x);
if (rc) FAIL(rc);
}
}
}
return 0;

View File

@ -887,11 +887,8 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
add_req_inpin(dev, LI_CE);
if (dev->u.logic.sr_used)
add_req_inpin(dev, LI_SR);
if (dev->u.logic.cout_used) {
if (dev->u.logic.cout_used)
add_req_outpin(dev, LO_COUT);
if (!dev->u.logic.precyinit)
add_req_inpin(dev, LI_CIN);
}
if (dev->u.logic.precyinit == PRECYINIT_AX)
add_req_inpin(dev, LI_AX);
if (dev->u.logic.a2d[LUT_A].out_mux == MUX_F7
@ -1537,7 +1534,8 @@ int fpga_switch_chain(struct sw_chain* ch)
idx = fpga_switch_backtofirst(ch->model, ch->y, ch->x,
ch->set.sw[ch->set.len-1], ch->from_to);
if (idx == NO_SWITCH) {
HERE(); goto internal_error;
ch->set.len = 0;
return NO_SWITCH;
}
#ifdef DBG_ENUM_SWITCH
printf("back_to_first from %s to %s\n",

View File

@ -359,8 +359,7 @@ int printf_iob(uint8_t* d, int len, int inpos, int num_entries)
for (i = 0; i < num_entries; i++) {
u64 = frame_get_u64(&d[inpos+i*8]);
if (u64) {
printf("iob i%i 0x%016llX\n", i,
(long long unsigned) u64);
printf("iob i%i 0x%016lX\n", i, u64);
num_printed++;
}
}

View File

@ -25,6 +25,7 @@
__FILE__, __LINE__)
#define FAIL(code) do { HERE(); rc = (code); goto fail; } while (0)
#define XOUT() do { HERE(); goto xout; } while (0)
#define CHECK_MODEL(m) do { if ((m)->rc) return (m)->rc; } while (0)
#define OUT_OF_U16(val) ((val) < 0 || (val) > 0xFFFF)

View File

@ -376,7 +376,7 @@ enum {
LI_AX, LI_BX, LI_CX, LI_DX,
LI_CLK, LI_CE, LI_SR,
// only for L and M:
LI_CIN, // only some L and M devs have this
LI_CIN,
// only for M:
LI_WE, LI_AI, LI_BI, LI_CI, LI_DI,

View File

@ -510,11 +510,11 @@ static int init_logic(struct fpga_model* model, int y, int x, int idx)
if (rc) FAIL(rc);
} else
tile->devs[idx].pinw[LI_WE] = STRIDX_NO_ENTRY;
if (tile->devs[idx].subtype != LOGIC_X
&& ((is_atx(X_ROUTING_NO_IO, model, x-1)
&& is_aty(Y_INNER_BOTTOM, model, y+1))
|| (!is_atx(X_ROUTING_NO_IO, model, x-1)
&& is_aty(Y_BOT_INNER_IO, model, y+1)))) {
if (tile->devs[idx].subtype != LOGIC_X) {
// Wire connections will go to some CIN later
// (and must not warn about duplicates), but we
// have to add the connection point here so
// that pinw[LI_CIN] is initialized.
rc = add_connpt_name(model, y, x, pf("%sCIN", pre),
/*dup_warn*/ 1,
&tile->devs[idx].pinw[LI_CIN], 0);

View File

@ -11,6 +11,9 @@
const char* iob_xc6slx9_sitenames[IOB_WORDS*2/8] =
{
// Note that the configuration space for 4*6 IOBs
// that are marked with 0 is used for clocks etc,
// just not IOBs.
[0]
"P70", "P69", "P67", "P66", "P65", "P64", "P62", "P61",
"P60", "P59", "P58", "P57", "UNB113", "UNB114", "UNB115", "UNB116",

View File

@ -323,6 +323,7 @@ void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits);
#define XC6_ML_B_CY0_O5 56 // implies lut5 on ML-B
#define XC6_ML_PRECYINIT_AX 57
#define XC6_X_A_FFSRINIT_1 58
#define XC6_ML_COUT_CIN_SW 59
// ML_PRECYINIT=0 -
#define XC6_ML_PRECYINIT_1 60
#define XC6_ML_B_FFSRINIT_1 61