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);
for (i = '1'; i <= '5'; 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],
&logic_cfg);
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) {
// minimum-config X device
memset(&logic_cfg, 0, sizeof(logic_cfg));
logic_cfg.a2d[LUT_A].lut6 = "(A6+~A6)*A3";
logic_cfg.a2d[LUT_A].lut5 = "A3+A5";
logic_cfg.a2d[LUT_A].lut6 = "(A6+~A6)*A1";
logic_cfg.a2d[LUT_A].lut5 = "A2";
logic_cfg.a2d[LUT_A].out_mux = MUX_5Q;
logic_cfg.a2d[LUT_A].ff5_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_A].ff = FF_FF;
logic_cfg.a2d[LUT_A].ff_mux = MUX_O6;
logic_cfg.a2d[LUT_A].ff_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_B].lut6 = "(A6+~A6)*A3";
logic_cfg.a2d[LUT_B].lut5 = "A3+A5";
logic_cfg.a2d[LUT_B].lut6 = "(A6+~A6)*A4";
logic_cfg.a2d[LUT_B].lut5 = "A3";
logic_cfg.a2d[LUT_B].out_mux = MUX_5Q;
logic_cfg.a2d[LUT_B].ff5_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_B].ff = FF_FF;
logic_cfg.a2d[LUT_B].ff_mux = MUX_O6;
logic_cfg.a2d[LUT_B].ff_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_C].lut6 = "(A6+~A6)*A3";
logic_cfg.a2d[LUT_C].lut5 = "A3+A5";
logic_cfg.a2d[LUT_C].lut6 = "(A6+~A6)*(A2+A5)";
logic_cfg.a2d[LUT_C].lut5 = "A3+A4";
logic_cfg.a2d[LUT_C].out_mux = MUX_5Q;
logic_cfg.a2d[LUT_C].ff5_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_C].ff = FF_FF;

View File

@ -49,7 +49,7 @@ int main(int argc, char** argv)
8);
#if 0
logic_y = 68;
logic_y = 55-58
logic_x = 13;
logic_type_idx = DEV_LOG_X;
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...
};
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)
{
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 lut6_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++) {
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
//
// 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: handle all_latch
// 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
// from vcc connectivity, srinit etc.
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;
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;
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
}
// If any ff_mux (5 or 6) is set, check that we have
// a clock and sync attribute. Do this after the LUT
// checks because presence of a 'hard' clock/sync bit
// 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
// todo:
// if (lut_a->out_mux == xor || lut_a->ff_mux == xor
// || lut_a->acy0 != 0) && !precyinit && !cin_switch
// -> precyinit = precyinit_0
//
// Step 8:
@ -1471,7 +1504,6 @@ fail:
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);
@ -1489,20 +1521,38 @@ static int extract_logic_switches(struct extract_state* es, int y, int x)
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 (frame_get_bit(u8_p + minor*FRAME_SIZE, byte_off*8 + XC6_ML_CIN_USED)) {
struct fpga_device* dev;
int connpt_dests_o, num_dests, cout_y, cout_x;
str16_t cout_str;
swidx_t cout_sw;
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++;
dev = fdev_p(es->model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
if (!dev) FAIL(EINVAL);
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;
fail:

View File

@ -1054,6 +1054,7 @@ swidx_t fpga_switch_first(struct fpga_model* model, int y, int x,
int i, connpt_o;
// 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);
for (i = 0; i < tile->num_switches; i++) {
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;
for (j = LUT_A; j <= LUT_D; j++) {
if (cfg->a2d[j].out_used)
fprintf(f, "%s %c_used\n", pref, 'A'+j);
for (j = LUT_D; j >= LUT_A; j--) {
if (cfg->a2d[j].lut6 && cfg->a2d[j].lut6[0])
fprintf(f, "%s %c6_lut %s\n", pref, 'A'+j,
cfg->a2d[j].lut6);
if (cfg->a2d[j].lut5 && cfg->a2d[j].lut5[0])
fprintf(f, "%s %c5_lut %s\n", pref, 'A'+j,
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) {
case MUX_O6:
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;
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) {
case MUX_O6:
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;
case 0: break; default: FAIL(EINVAL);
}
switch (cfg->a2d[j].ff) {
case FF_OR2L:
fprintf(f, "%s %c_ff OR2L\n", pref, 'A'+j);
switch (cfg->a2d[j].ff5_srinit) {
case FF_SRINIT0:
fprintf(f, "%s %c5_ffsrinit 0\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);
case FF_SRINIT1:
fprintf(f, "%s %c5_ffsrinit 1\n", pref, 'A'+j);
break;
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 (y = 0; y < model->y_height; y++) {
rc = printf_IOB(f, model, y, x, config_only);
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);
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);
for (i = 0; i < tile->num_devs; i++) {
if (config_only && !(tile->devs[i].instantiated))
continue;
if (tile->devs[i].type == DEV_LOGIC
|| tile->devs[i].type == DEV_IOB)
continue; // handled above
continue; // handled earlier
fprintf(f, "dev y%02i x%02i %s\n", y, x,
fdev_type2str(tile->devs[i].type));
}

View File

@ -23,9 +23,9 @@
#define HERE() fprintf(stderr, "#E Internal error in %s:%i\n", \
__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 FAIL(code) do { HERE(); rc = (code); goto fail; } while (0)
#define XOUT() do { HERE(); goto xout; } while (0)
#define CHECK_RC(m) do { if ((m)->rc) return (m)->rc; } while (0)
#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);
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_HIGH32(v) ((uint32_t) (((uint64_t)v) >> 32))
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.
for (i = 0; i < 32; i++) {
if (num_bits == 32) {
(*map)[i] = map32[i]%32;
(*map)[32+i] = 32+(*map)[i];
if (lut_pos == XC6_LMAP_XM_M_A
|| 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 {
if (num_bits != 64) HERE();
(*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_PRECYINIT_AX 57
#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 -
#define XC6_ML_PRECYINIT_1 60
#define XC6_ML_B_FFSRINIT_1 61