several bug fixes
This commit is contained in:
parent
c330b8e11f
commit
3766d7f5fc
14
autotest.c
14
autotest.c
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
16
libs/parts.c
16
libs/parts.c
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user