several bug fixes

This commit is contained in:
Wolfgang Spraul 2012-10-13 02:40:30 +02:00
parent c330b8e11f
commit 3766d7f5fc
8 changed files with 135 additions and 65 deletions

View File

@ -1228,7 +1228,7 @@ static int test_lut_encoding(struct test_state* tstate)
if (rc) FAIL(rc); if (rc) FAIL(rc);
for (i = '1'; i <= '5'; i++) { for (i = '1'; i <= '5'; i++) {
sprintf(lut5_str, "A%c", i); sprintf(lut5_str, "A%c", i);
sprintf(lut6_str, "(A6+~A6)*%s", lut5_str); sprintf(lut6_str, "(A6+~A6)*A%c", (i == '5') ? '1' : i+1);
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i], rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
&logic_cfg); &logic_cfg);
if (rc) FAIL(rc); if (rc) FAIL(rc);
@ -1540,22 +1540,22 @@ static int test_logic_config(struct test_state* tstate)
if (idx_enum[type_i] == DEV_LOG_X) { if (idx_enum[type_i] == DEV_LOG_X) {
// minimum-config X device // minimum-config X device
memset(&logic_cfg, 0, sizeof(logic_cfg)); memset(&logic_cfg, 0, sizeof(logic_cfg));
logic_cfg.a2d[LUT_A].lut6 = "(A6+~A6)*A3"; logic_cfg.a2d[LUT_A].lut6 = "(A6+~A6)*A1";
logic_cfg.a2d[LUT_A].lut5 = "A3+A5"; logic_cfg.a2d[LUT_A].lut5 = "A2";
logic_cfg.a2d[LUT_A].out_mux = MUX_5Q; logic_cfg.a2d[LUT_A].out_mux = MUX_5Q;
logic_cfg.a2d[LUT_A].ff5_srinit = FF_SRINIT0; logic_cfg.a2d[LUT_A].ff5_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_A].ff = FF_FF; logic_cfg.a2d[LUT_A].ff = FF_FF;
logic_cfg.a2d[LUT_A].ff_mux = MUX_O6; logic_cfg.a2d[LUT_A].ff_mux = MUX_O6;
logic_cfg.a2d[LUT_A].ff_srinit = FF_SRINIT0; logic_cfg.a2d[LUT_A].ff_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_B].lut6 = "(A6+~A6)*A3"; logic_cfg.a2d[LUT_B].lut6 = "(A6+~A6)*A4";
logic_cfg.a2d[LUT_B].lut5 = "A3+A5"; logic_cfg.a2d[LUT_B].lut5 = "A3";
logic_cfg.a2d[LUT_B].out_mux = MUX_5Q; logic_cfg.a2d[LUT_B].out_mux = MUX_5Q;
logic_cfg.a2d[LUT_B].ff5_srinit = FF_SRINIT0; logic_cfg.a2d[LUT_B].ff5_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_B].ff = FF_FF; logic_cfg.a2d[LUT_B].ff = FF_FF;
logic_cfg.a2d[LUT_B].ff_mux = MUX_O6; logic_cfg.a2d[LUT_B].ff_mux = MUX_O6;
logic_cfg.a2d[LUT_B].ff_srinit = FF_SRINIT0; logic_cfg.a2d[LUT_B].ff_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_C].lut6 = "(A6+~A6)*A3"; logic_cfg.a2d[LUT_C].lut6 = "(A6+~A6)*(A2+A5)";
logic_cfg.a2d[LUT_C].lut5 = "A3+A5"; logic_cfg.a2d[LUT_C].lut5 = "A3+A4";
logic_cfg.a2d[LUT_C].out_mux = MUX_5Q; logic_cfg.a2d[LUT_C].out_mux = MUX_5Q;
logic_cfg.a2d[LUT_C].ff5_srinit = FF_SRINIT0; logic_cfg.a2d[LUT_C].ff5_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_C].ff = FF_FF; logic_cfg.a2d[LUT_C].ff = FF_FF;

View File

@ -49,7 +49,7 @@ int main(int argc, char** argv)
8); 8);
#if 0 #if 0
logic_y = 68; logic_y = 55-58
logic_x = 13; logic_x = 13;
logic_type_idx = DEV_LOG_X; logic_type_idx = DEV_LOG_X;
if ((rc = fdev_logic_a2d_lut(&model, logic_y, logic_x, logic_type_idx, if ((rc = fdev_logic_a2d_lut(&model, logic_y, logic_x, logic_type_idx,

View File

@ -92,6 +92,19 @@ struct extract_state
struct sw_yxpos yx_pos[MAX_YX_SWITCHES]; // needs to be dynamically alloced... struct sw_yxpos yx_pos[MAX_YX_SWITCHES]; // needs to be dynamically alloced...
}; };
static int find_es_switch(struct extract_state* es, int y, int x, swidx_t sw)
{
int i;
if (sw == NO_CONN) { HERE(); return 0; }
for (i = 0; i < es->num_yx_pos; i++) {
if (es->yx_pos[i].y == y
&& es->yx_pos[i].x == x
&& es->yx_pos[i].idx == sw)
return 1;
}
return 0;
}
static int write_iobs(struct fpga_bits* bits, struct fpga_model* model) static int write_iobs(struct fpga_bits* bits, struct fpga_model* model)
{ {
int i, y, x, type_idx, part_idx, dev_idx, first_iob, rc; int i, y, x, type_idx, part_idx, dev_idx, first_iob, rc;
@ -603,6 +616,7 @@ static int extract_logic(struct extract_state* es)
char lut5_ml[NUM_LUTS][MAX_LUT_LEN]; char lut5_ml[NUM_LUTS][MAX_LUT_LEN];
char lut6_x[NUM_LUTS][MAX_LUT_LEN]; char lut6_x[NUM_LUTS][MAX_LUT_LEN];
char lut5_x[NUM_LUTS][MAX_LUT_LEN]; char lut5_x[NUM_LUTS][MAX_LUT_LEN];
struct fpga_device* dev_ml;
for (x = LEFT_SIDE_WIDTH; x < es->model->x_width-RIGHT_SIDE_WIDTH; x++) { for (x = LEFT_SIDE_WIDTH; x < es->model->x_width-RIGHT_SIDE_WIDTH; x++) {
if (!is_atx(X_FABRIC_LOGIC_COL|X_CENTER_LOGIC_COL, es->model, x)) if (!is_atx(X_FABRIC_LOGIC_COL|X_CENTER_LOGIC_COL, es->model, x))
@ -1065,7 +1079,13 @@ static int extract_logic(struct extract_state* es)
// Do device-global sanity checking pre-LUT // Do device-global sanity checking pre-LUT
// //
// todo: cfg_ml.cout_used must be determined from switches // cfg_ml.cout_used
dev_ml = fdev_p(es->model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
if (!dev_ml) FAIL(EINVAL);
if (find_es_switch(es, y, x, fpga_switch_first(
es->model, y, x, dev_ml->pinw[LO_COUT], SW_FROM)))
cfg_ml.cout_used = 1;
// todo: if srinit=1, the matching ff/latch must be on // todo: if srinit=1, the matching ff/latch must be on
// todo: handle all_latch // todo: handle all_latch
// todo: precyinit=0 has no bits // todo: precyinit=0 has no bits
@ -1270,18 +1290,31 @@ static int extract_logic(struct extract_state* es)
// todo: latch and2l and or2l need to be determined // todo: latch and2l and or2l need to be determined
// from vcc connectivity, srinit etc. // from vcc connectivity, srinit etc.
for (lut = LUT_A; lut <= LUT_D; lut++) { for (lut = LUT_A; lut <= LUT_D; lut++) {
if (cfg_ml.a2d[lut].ff_mux) if (cfg_ml.a2d[lut].ff_mux) {
cfg_ml.a2d[lut].ff = latch_ml ? FF_LATCH : FF_FF; cfg_ml.a2d[lut].ff = latch_ml ? FF_LATCH : FF_FF;
if (cfg_x.a2d[lut].ff_mux) if (!cfg_ml.a2d[lut].ff_srinit)
cfg_ml.a2d[lut].ff_srinit = FF_SRINIT0;
if (!cfg_ml.clk_inv)
cfg_ml.clk_inv = CLKINV_CLK;
if (!cfg_ml.sync_attr)
cfg_ml.sync_attr = SYNCATTR_ASYNC;
}
if (cfg_x.a2d[lut].ff_mux) {
cfg_x.a2d[lut].ff = latch_x ? FF_LATCH : FF_FF; cfg_x.a2d[lut].ff = latch_x ? FF_LATCH : FF_FF;
if (!cfg_x.a2d[lut].ff_srinit)
cfg_x.a2d[lut].ff_srinit = FF_SRINIT0;
if (!cfg_x.clk_inv)
cfg_x.clk_inv = CLKINV_CLK;
if (!cfg_x.sync_attr)
cfg_x.sync_attr = SYNCATTR_ASYNC;
}
// todo: ff5_srinit
// todo: 5Q ff also needs clock/sync check
} }
// todo:
// If any ff_mux (5 or 6) is set, check that we have // if (lut_a->out_mux == xor || lut_a->ff_mux == xor
// a clock and sync attribute. Do this after the LUT // || lut_a->acy0 != 0) && !precyinit && !cin_switch
// checks because presence of a 'hard' clock/sync bit // -> precyinit = precyinit_0
// may signal ff presence there.
// todo: if a ff_mux is != 0, clk and sync must be set
// todo: if a ff/latch is on, either srinit1 or srinit0 must be set
// //
// Step 8: // Step 8:
@ -1471,7 +1504,6 @@ fail:
static int extract_logic_switches(struct extract_state* es, int y, int x) static int extract_logic_switches(struct extract_state* es, int y, int x)
{ {
int row, row_pos, byte_off, minor, rc; int row, row_pos, byte_off, minor, rc;
swidx_t sw_idx;
uint8_t* u8_p; uint8_t* u8_p;
row = which_row(y, es->model); row = which_row(y, es->model);
@ -1489,20 +1521,38 @@ static int extract_logic_switches(struct extract_state* es, int y, int x)
else else
FAIL(EINVAL); FAIL(EINVAL);
if (frame_get_bit(u8_p + minor*FRAME_SIZE, byte_off*8 + XC6_ML_COUT_CIN_SW)) { if (frame_get_bit(u8_p + minor*FRAME_SIZE, byte_off*8 + XC6_ML_CIN_USED)) {
sw_idx = fpga_switch_lookup(es->model, y, x, struct fpga_device* dev;
strarray_find(&es->model->str, "M_COUT"), int connpt_dests_o, num_dests, cout_y, cout_x;
strarray_find(&es->model->str, "M_COUT_N")); str16_t cout_str;
if (sw_idx == NO_SWITCH) { HERE(); return 0; } swidx_t cout_sw;
if (es->num_yx_pos >= MAX_YX_SWITCHES) dev = fdev_p(es->model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
{ FAIL(ENOTSUP); } if (!dev) FAIL(EINVAL);
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); if ((fpga_connpt_find(es->model, y, x,
dev->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);
cout_sw = fpga_switch_first(es->model, cout_y,
cout_x, cout_str, SW_TO);
if (cout_sw == NO_SWITCH) HERE();
else {
if (es->num_yx_pos >= MAX_YX_SWITCHES)
{ FAIL(ENOTSUP); }
es->yx_pos[es->num_yx_pos].y = cout_y;
es->yx_pos[es->num_yx_pos].x = cout_x;
es->yx_pos[es->num_yx_pos].idx = cout_sw;
es->num_yx_pos++;
frame_clear_bit(u8_p + minor*FRAME_SIZE,
byte_off*8 + XC6_ML_CIN_USED);
}
}
} }
return 0; return 0;
fail: fail:

View File

@ -1054,6 +1054,7 @@ swidx_t fpga_switch_first(struct fpga_model* model, int y, int x,
int i, connpt_o; int i, connpt_o;
// Finds the first switch either from or to the name given. // Finds the first switch either from or to the name given.
if (name_i == STRIDX_NO_ENTRY) { HERE(); return NO_SWITCH; }
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++) {
connpt_o = SW_I(tile->switches[i], from_to); connpt_o = SW_I(tile->switches[i], from_to);

View File

@ -323,16 +323,30 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model,
} }
} }
cfg = &tile->devs[i].u.logic; cfg = &tile->devs[i].u.logic;
for (j = LUT_A; j <= LUT_D; j++) { for (j = LUT_D; j >= LUT_A; j--) {
if (cfg->a2d[j].out_used)
fprintf(f, "%s %c_used\n", pref, 'A'+j);
if (cfg->a2d[j].lut6 && cfg->a2d[j].lut6[0]) if (cfg->a2d[j].lut6 && cfg->a2d[j].lut6[0])
fprintf(f, "%s %c6_lut %s\n", pref, 'A'+j, fprintf(f, "%s %c6_lut %s\n", pref, 'A'+j,
cfg->a2d[j].lut6); cfg->a2d[j].lut6);
if (cfg->a2d[j].lut5 && cfg->a2d[j].lut5[0]) if (cfg->a2d[j].lut5 && cfg->a2d[j].lut5[0])
fprintf(f, "%s %c5_lut %s\n", pref, 'A'+j, fprintf(f, "%s %c5_lut %s\n", pref, 'A'+j,
cfg->a2d[j].lut5); cfg->a2d[j].lut5);
if (cfg->a2d[j].out_used)
fprintf(f, "%s %c_used\n", pref, 'A'+j);
switch (cfg->a2d[j].ff) {
case FF_OR2L:
fprintf(f, "%s %c_ff OR2L\n", pref, 'A'+j);
break;
case FF_AND2L:
fprintf(f, "%s %c_ff AND2L\n", pref, 'A'+j);
break;
case FF_LATCH:
fprintf(f, "%s %c_ff LATCH\n", pref, 'A'+j);
break;
case FF_FF:
fprintf(f, "%s %c_ff FF\n", pref, 'A'+j);
break;
case 0: break; default: FAIL(EINVAL);
}
switch (cfg->a2d[j].ff_mux) { switch (cfg->a2d[j].ff_mux) {
case MUX_O6: case MUX_O6:
fprintf(f, "%s %c_ffmux O6\n", pref, 'A'+j); fprintf(f, "%s %c_ffmux O6\n", pref, 'A'+j);
@ -369,15 +383,6 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model,
break; break;
case 0: break; default: FAIL(EINVAL); case 0: break; default: FAIL(EINVAL);
} }
switch (cfg->a2d[j].ff5_srinit) {
case FF_SRINIT0:
fprintf(f, "%s %c5_ffsrinit 0\n", pref, 'A'+j);
break;
case FF_SRINIT1:
fprintf(f, "%s %c5_ffsrinit 1\n", pref, 'A'+j);
break;
case 0: break; default: FAIL(EINVAL);
}
switch (cfg->a2d[j].out_mux) { switch (cfg->a2d[j].out_mux) {
case MUX_O6: case MUX_O6:
fprintf(f, "%s %c_outmux O6\n", pref, 'A'+j); fprintf(f, "%s %c_outmux O6\n", pref, 'A'+j);
@ -405,18 +410,12 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model,
break; break;
case 0: break; default: FAIL(EINVAL); case 0: break; default: FAIL(EINVAL);
} }
switch (cfg->a2d[j].ff) { switch (cfg->a2d[j].ff5_srinit) {
case FF_OR2L: case FF_SRINIT0:
fprintf(f, "%s %c_ff OR2L\n", pref, 'A'+j); fprintf(f, "%s %c5_ffsrinit 0\n", pref, 'A'+j);
break; break;
case FF_AND2L: case FF_SRINIT1:
fprintf(f, "%s %c_ff AND2L\n", pref, 'A'+j); fprintf(f, "%s %c5_ffsrinit 1\n", pref, 'A'+j);
break;
case FF_LATCH:
fprintf(f, "%s %c_ff LATCH\n", pref, 'A'+j);
break;
case FF_FF:
fprintf(f, "%s %c_ff FF\n", pref, 'A'+j);
break; break;
case 0: break; default: FAIL(EINVAL); case 0: break; default: FAIL(EINVAL);
} }
@ -663,19 +662,25 @@ int printf_devices(FILE* f, struct fpga_model* model, int config_only)
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++) {
rc = printf_IOB(f, model, y, x, config_only); rc = printf_IOB(f, model, y, x, config_only);
if (rc) goto fail; if (rc) goto fail;
}
}
for (x = 0; x < model->x_width; x++) {
for (y = 0; y < model->y_height; y++) {
rc = printf_LOGIC(f, model, y, x, config_only); rc = printf_LOGIC(f, model, y, x, config_only);
if (rc) goto fail; if (rc) goto fail;
}
}
for (x = 0; x < model->x_width; x++) {
for (y = 0; y < model->y_height; y++) {
tile = YX_TILE(model, y, x); tile = YX_TILE(model, y, x);
for (i = 0; i < tile->num_devs; i++) { for (i = 0; i < tile->num_devs; i++) {
if (config_only && !(tile->devs[i].instantiated)) if (config_only && !(tile->devs[i].instantiated))
continue; continue;
if (tile->devs[i].type == DEV_LOGIC if (tile->devs[i].type == DEV_LOGIC
|| tile->devs[i].type == DEV_IOB) || tile->devs[i].type == DEV_IOB)
continue; // handled above continue; // handled earlier
fprintf(f, "dev y%02i x%02i %s\n", y, x, fprintf(f, "dev y%02i x%02i %s\n", y, x,
fdev_type2str(tile->devs[i].type)); fdev_type2str(tile->devs[i].type));
} }

View File

@ -23,9 +23,9 @@
#define HERE() fprintf(stderr, "#E Internal error in %s:%i\n", \ #define HERE() fprintf(stderr, "#E Internal error in %s:%i\n", \
__FILE__, __LINE__) __FILE__, __LINE__)
#define FAIL(code) do { HERE(); rc = (code); goto fail; } while (0) #define FAIL(code) do { HERE(); rc = (code); goto fail; } while (0)
#define XOUT() do { HERE(); goto xout; } while (0) #define XOUT() do { HERE(); goto xout; } while (0)
#define CHECK_MODEL(m) do { if ((m)->rc) return (m)->rc; } while (0) #define CHECK_RC(m) do { if ((m)->rc) return (m)->rc; } while (0)
#define OUT_OF_U16(val) ((val) < 0 || (val) > 0xFFFF) #define OUT_OF_U16(val) ((val) < 0 || (val) > 0xFFFF)
@ -85,7 +85,7 @@ void frame_set_u32(uint8_t* frame_d, uint32_t v);
void frame_set_u64(uint8_t* frame_d, uint64_t v); void frame_set_u64(uint8_t* frame_d, uint64_t v);
uint64_t frame_get_lut64(const uint8_t* two_minors, int v32); uint64_t frame_get_lut64(const uint8_t* two_minors, int v32);
// In a lut pair, LOW32 is lut5, HIGH32 is lut6. // In a lut pair, lut5 is always mapped to LOW32, lut6 to HIGH32.
#define ULL_LOW32(v) ((uint32_t) (((uint64_t)v) & 0xFFFFFFFFULL)) #define ULL_LOW32(v) ((uint32_t) (((uint64_t)v) & 0xFFFFFFFFULL))
#define ULL_HIGH32(v) ((uint32_t) (((uint64_t)v) >> 32)) #define ULL_HIGH32(v) ((uint32_t) (((uint64_t)v) >> 32))
void frame_set_lut64(uint8_t* two_minors, int v32, uint64_t v); void frame_set_lut64(uint8_t* two_minors, int v32, uint64_t v);

View File

@ -842,8 +842,20 @@ void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits)
// expand from 32 to 64 for either lut6 only or lut5/lut6 pair. // expand from 32 to 64 for either lut6 only or lut5/lut6 pair.
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
if (num_bits == 32) { if (num_bits == 32) {
(*map)[i] = map32[i]%32; if (lut_pos == XC6_LMAP_XM_M_A
(*map)[32+i] = 32+(*map)[i]; || lut_pos == XC6_LMAP_XM_M_C
|| lut_pos == XC6_LMAP_XM_X_A
|| lut_pos == XC6_LMAP_XM_X_B
|| lut_pos == XC6_LMAP_XL_L_B
|| lut_pos == XC6_LMAP_XL_L_D
|| lut_pos == XC6_LMAP_XL_X_A
|| lut_pos == XC6_LMAP_XL_X_B) {
(*map)[i] = map32[i]%32;
(*map)[32+i] = 32+(map32[i]%32);
} else {
(*map)[i] = 32+(map32[i]%32);
(*map)[32+i] = map32[i]%32;
}
} else { } else {
if (num_bits != 64) HERE(); if (num_bits != 64) HERE();
(*map)[i] = map32[i]; (*map)[i] = map32[i];

View File

@ -323,7 +323,9 @@ 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_B_CY0_O5 56 // implies lut5 on ML-B
#define XC6_ML_PRECYINIT_AX 57 #define XC6_ML_PRECYINIT_AX 57
#define XC6_X_A_FFSRINIT_1 58 #define XC6_X_A_FFSRINIT_1 58
#define XC6_ML_COUT_CIN_SW 59 // CIN_USED best corresponds to the cout->cout_n switch in the
// next lower logic device (y+1).
#define XC6_ML_CIN_USED 59
// ML_PRECYINIT=0 - // ML_PRECYINIT=0 -
#define XC6_ML_PRECYINIT_1 60 #define XC6_ML_PRECYINIT_1 60
#define XC6_ML_B_FFSRINIT_1 61 #define XC6_ML_B_FFSRINIT_1 61