doing simple work in the lord's vineyard

This commit is contained in:
Wolfgang Spraul 2013-02-12 20:34:18 -05:00
parent 0ff7ed690a
commit cc1cd89564
10 changed files with 438 additions and 264 deletions

View File

@ -1057,6 +1057,8 @@ static int test_logic(struct test_state* tstate, int y, int x, int type_idx,
rc = printf_LOGIC(stdout, tstate->model, y, x, type_idx,
/*config_only*/ 1);
if (rc) FAIL(rc);
fdev_print_required_pins(tstate->model, y, x,
DEV_LOGIC, type_idx);
}
latch_logic = 0;
for (lut = LUT_A; lut <= LUT_D; lut++) {
@ -1228,8 +1230,9 @@ static int test_lut_encoding(struct test_state* tstate)
char lut6_str[128], lut5_str[128];
tstate->diff_to_null = 1;
y = 68;
// aggregate expressions
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++) {
@ -1252,21 +1255,6 @@ static int test_lut_encoding(struct test_state* tstate)
&logic_cfg);
if (rc) FAIL(rc);
}
for (i = 0; i < 64; i++) {
lut_str_len = 0;
for (j = 0; j < 6; j++) {
if (lut_str_len)
lut6_str[lut_str_len++] = '*';
if (!(i & (1<<j)))
lut6_str[lut_str_len++] = '~';
lut6_str[lut_str_len++] = 'A';
lut6_str[lut_str_len++] = '1' + j;
}
lut6_str[lut_str_len] = 0;
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
&logic_cfg);
if (rc) FAIL(rc);
}
// lut6 and lut5 pairs
logic_cfg.a2d[lut].lut5_str = lut5_str;
@ -1289,18 +1277,29 @@ static int test_lut_encoding(struct test_state* tstate)
&logic_cfg);
if (rc) FAIL(rc);
}
for (i = 0; i < 32; i++) {
}
}
}
// --skip=240 - separate bits for lut6 0:63
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++) {
CLEAR(logic_cfg);
logic_cfg.a2d[lut].lut6_str = lut6_str;
logic_cfg.a2d[lut].flags |= OUT_USED;
for (i = 0; i < 64; i++) {
lut_str_len = 0;
for (j = 0; j < 5; j++) {
for (j = 0; j < 6; j++) {
if (lut_str_len)
lut5_str[lut_str_len++] = '*';
lut6_str[lut_str_len++] = '*';
if (!(i & (1<<j)))
lut5_str[lut_str_len++] = '~';
lut5_str[lut_str_len++] = 'A';
lut5_str[lut_str_len++] = '1' + j;
lut6_str[lut_str_len++] = '~';
lut6_str[lut_str_len++] = 'A';
lut6_str[lut_str_len++] = '1' + j;
}
lut5_str[lut_str_len] = 0;
sprintf(lut6_str, "(A6+~A6)*%s", lut5_str);
lut6_str[lut_str_len] = 0;
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
&logic_cfg);
if (rc) FAIL(rc);
@ -1308,6 +1307,69 @@ static int test_lut_encoding(struct test_state* tstate)
}
}
}
// --skip=1264 --count=64 - separate bits for lut5 (32) and lut6 (32) (xm-m-a only)
CLEAR(logic_cfg);
logic_cfg.a2d[LUT_A].lut6_str = lut6_str;
logic_cfg.a2d[LUT_A].lut5_str = lut5_str;
logic_cfg.a2d[LUT_A].flags |= OUT_USED;
logic_cfg.a2d[LUT_A].out_mux = MUX_O5;
// 32 bits in lut5 with lut6=0
for (i = 0; i < 32; i++) {
lut_str_len = 0;
for (j = 0; j < 5; j++) {
if (lut_str_len)
lut5_str[lut_str_len++] = '*';
if (!(i & (1<<j)))
lut5_str[lut_str_len++] = '~';
lut5_str[lut_str_len++] = 'A';
lut5_str[lut_str_len++] = '1' + j;
}
lut5_str[lut_str_len] = 0;
strcpy(lut6_str, "(A6+~A6)*0");
rc = test_logic(tstate, y, /*XM*/ 13, DEV_LOG_M_OR_L, &logic_cfg);
if (rc) FAIL(rc);
}
// 32 bits in lut6 with lut5=0
for (i = 0; i < 32; i++) {
strcpy(lut6_str, "(A6+~A6)");
lut_str_len = strlen(lut6_str);
for (j = 0; j < 5; j++) {
lut6_str[lut_str_len++] = '*';
if (!(i & (1<<j)))
lut6_str[lut_str_len++] = '~';
lut6_str[lut_str_len++] = 'A';
lut6_str[lut_str_len++] = '1' + j;
}
lut6_str[lut_str_len] = 0;
strcpy(lut5_str, "0");
rc = test_logic(tstate, y, /*XM*/ 13, DEV_LOG_M_OR_L, &logic_cfg);
if (rc) FAIL(rc);
}
// --skip=1328 --count=128 - test ROM and RAM bits
for (i = 0; i < 64; i++) {
// ROM test in LUT_A
CLEAR(logic_cfg);
logic_cfg.clk_inv = CLKINV_CLK;
logic_cfg.a2d[LUT_A].lut6_val = 1ULL << i;
logic_cfg.a2d[LUT_A].flags |= LUT6VAL_SET | LUTMODE_ROM2;
rc = test_logic(tstate, y, /*XM*/ 13, DEV_LOG_M_OR_L,
&logic_cfg);
if (rc) FAIL(rc);
}
for (i = 0; i < 64; i++) {
// RAM test in LUT_D
CLEAR(logic_cfg);
logic_cfg.we_mux = WEMUX_WE;
logic_cfg.clk_inv = CLKINV_CLK;
logic_cfg.a2d[LUT_D].lut6_val = 1ULL << i;
logic_cfg.a2d[LUT_D].flags |= LUT6VAL_SET;
logic_cfg.a2d[LUT_D].ram_mode = DPRAM64;
rc = test_logic(tstate, y, /*XM*/ 13, DEV_LOG_M_OR_L,
&logic_cfg);
if (rc) FAIL(rc);
}
return 0;
fail:
return rc;
@ -1934,22 +1996,36 @@ static int test_dist_mem(struct test_state *tstate)
x = 13 /* XM */;
type_i = DEV_LOG_M_OR_L;
CLEAR(logic_cfg);
logic_cfg.we_mux = WEMUX_WE;
logic_cfg.clk_inv = CLKINV_CLK;
logic_cfg.a2d[LUT_D].lut6_val = 0x00000000000000FF;
logic_cfg.a2d[LUT_D].flags |= LUT6VAL_SET;
logic_cfg.a2d[LUT_D].ram_mode = DPRAM64;
rc = test_logic(tstate, y, x, type_i, &logic_cfg);
if (rc) FAIL(rc);
logic_cfg.we_mux = WEMUX_CE;
rc = test_logic(tstate, y, x, type_i, &logic_cfg);
if (rc) FAIL(rc);
logic_cfg.we_mux = WEMUX_WE;
logic_cfg.wa7_used = 1;
rc = test_logic(tstate, y, x, type_i, &logic_cfg);
if (rc) FAIL(rc);
logic_cfg.wa8_used = 1;
rc = test_logic(tstate, y, x, type_i, &logic_cfg);
if (rc) FAIL(rc);
for (lut = LUT_A; lut <= LUT_D; lut++) {
// Requirements for functioning ram:
// - input on CLK and WE pins
// - SRL32 and SRL16 should have O6 or MC31 output
// - SRL32 and SRL16 require A1 tied to VCC
// - DRPAM64, SPRAM64 and SRL32 require DI1
// - DRPAM32, SPRAM32 and SRL16 require DI2
// - dual or single port RAM requires WA1-WA6 (or WA1-WA5)
// - when dual or single port RAM should be used in any
// of the 4 luts, the lut-D must be one of them
for (ram_mode_i = 0; ram_mode_i < sizeof(ram_modes)/sizeof(*ram_modes);
ram_mode_i++) {
CLEAR(logic_cfg);
logic_cfg.we_mux = WEMUX_WE;
logic_cfg.clk_inv = CLKINV_CLK;
logic_cfg.a2d[lut].lut6_val = 0x00000000000000FF;
logic_cfg.a2d[lut].flags |= LUT6VAL_SET;
logic_cfg.a2d[lut].ram_mode = ram_modes[ram_mode_i];
@ -1971,6 +2047,9 @@ static int test_dist_mem(struct test_state *tstate)
if (lut != LUT_D) { // LUT_D has no DIMUX
CLEAR(logic_cfg);
logic_cfg.we_mux = WEMUX_WE;
logic_cfg.clk_inv = CLKINV_CLK;
logic_cfg.a2d[lut].lut6_val = 0x00000000000000FF;
logic_cfg.a2d[lut].flags |= LUT6VAL_SET;
logic_cfg.a2d[lut].ram_mode = SRL32;
@ -1991,8 +2070,9 @@ static int test_dist_mem(struct test_state *tstate)
}
CLEAR(logic_cfg);
logic_cfg.clk_inv = CLKINV_CLK;
logic_cfg.a2d[lut].lut6_val = 0x00000000000000FF;
logic_cfg.a2d[lut].flags |= LUT6VAL_SET | LUTMODE_ROM;
logic_cfg.a2d[lut].flags |= LUT6VAL_SET | LUTMODE_ROM2;
rc = test_logic(tstate, y, x, type_i, &logic_cfg);
if (rc) FAIL(rc);

View File

@ -644,32 +644,26 @@ static int extract_type2(struct extract_state* es)
RC_RETURN(es->model);
}
static int lut2str(uint64_t lut, int lut_pos, int lut5_used,
static int lut2str(uint64_t lut_val, int lut5_used,
char *lut6_buf, char** lut6_p, char *lut5_buf, char** lut5_p)
{
int lut_map[64], rc;
uint64_t lut_mapped;
const char* str;
int rc;
if (lut5_used) {
xc6_lut_bitmap(lut_pos, &lut_map, 32);
lut_mapped = map_bits(lut, 64, lut_map);
// lut6
str = bool_bits2str(ULL_HIGH32(lut_mapped), 32);
str = bool_bits2str(ULL_HIGH32(lut_val), 32);
if (!str) FAIL(EINVAL);
snprintf(lut6_buf, MAX_LUT_LEN, "(A6+~A6)*(%s)", str);
*lut6_p = lut6_buf;
// lut5
str = bool_bits2str(ULL_LOW32(lut_mapped), 32);
str = bool_bits2str(ULL_LOW32(lut_val), 32);
if (!str) FAIL(EINVAL);
strcpy(lut5_buf, str);
*lut5_p = lut5_buf;
} else {
xc6_lut_bitmap(lut_pos, &lut_map, 64);
lut_mapped = map_bits(lut, 64, lut_map);
str = bool_bits2str(lut_mapped, 64);
str = bool_bits2str(lut_val, 64);
if (!str) FAIL(EINVAL);
strcpy(lut6_buf, str);
*lut6_p = lut6_buf;
@ -742,26 +736,43 @@ static int extract_logic(struct extract_state* es)
if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_M)) {
mi23_M = frame_get_u64(u8_p + 23*FRAME_SIZE + byte_off);
mi2526 = frame_get_u64(u8_p + 26*FRAME_SIZE + byte_off);
lut_ML[LUT_A] = frame_get_lut64(u8_p + 24*FRAME_SIZE, row_pos*2+1);
lut_ML[LUT_B] = frame_get_lut64(u8_p + 21*FRAME_SIZE, row_pos*2+1);
lut_ML[LUT_C] = frame_get_lut64(u8_p + 24*FRAME_SIZE, row_pos*2);
lut_ML[LUT_D] = frame_get_lut64(u8_p + 21*FRAME_SIZE, row_pos*2);
lut_X[LUT_A] = frame_get_lut64(u8_p + 27*FRAME_SIZE, row_pos*2+1);
lut_X[LUT_B] = frame_get_lut64(u8_p + 29*FRAME_SIZE, row_pos*2+1);
lut_X[LUT_C] = frame_get_lut64(u8_p + 27*FRAME_SIZE, row_pos*2);
lut_X[LUT_D] = frame_get_lut64(u8_p + 29*FRAME_SIZE, row_pos*2);
lut_ML[LUT_A] = frame_get_lut64(XC6_LMAP_XM_M_A,
u8_p + 24*FRAME_SIZE, row_pos*4+2);
lut_ML[LUT_B] = frame_get_lut64(XC6_LMAP_XM_M_B,
u8_p + 21*FRAME_SIZE, row_pos*4+2);
lut_ML[LUT_C] = frame_get_lut64(XC6_LMAP_XM_M_C,
u8_p + 24*FRAME_SIZE, row_pos*4);
lut_ML[LUT_D] = frame_get_lut64(XC6_LMAP_XM_M_D,
u8_p + 21*FRAME_SIZE, row_pos*4);
lut_X[LUT_A] = frame_get_lut64(XC6_LMAP_XM_X_A,
u8_p + 27*FRAME_SIZE, row_pos*4+2);
lut_X[LUT_B] = frame_get_lut64(XC6_LMAP_XM_X_B,
u8_p + 29*FRAME_SIZE, row_pos*4+2);
lut_X[LUT_C] = frame_get_lut64(XC6_LMAP_XM_X_C,
u8_p + 27*FRAME_SIZE, row_pos*4);
lut_X[LUT_D] = frame_get_lut64(XC6_LMAP_XM_X_D,
u8_p + 29*FRAME_SIZE, row_pos*4);
l_col = 0;
} else if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_L)) {
mi23_M = 0;
mi2526 = frame_get_u64(u8_p + 25*FRAME_SIZE + byte_off);
lut_ML[LUT_A] = frame_get_lut64(u8_p + 23*FRAME_SIZE, row_pos*2+1);
lut_ML[LUT_B] = frame_get_lut64(u8_p + 21*FRAME_SIZE, row_pos*2+1);
lut_ML[LUT_C] = frame_get_lut64(u8_p + 23*FRAME_SIZE, row_pos*2);
lut_ML[LUT_D] = frame_get_lut64(u8_p + 21*FRAME_SIZE, row_pos*2);
lut_X[LUT_A] = frame_get_lut64(u8_p + 26*FRAME_SIZE, row_pos*2+1);
lut_X[LUT_B] = frame_get_lut64(u8_p + 28*FRAME_SIZE, row_pos*2+1);
lut_X[LUT_C] = frame_get_lut64(u8_p + 26*FRAME_SIZE, row_pos*2);
lut_X[LUT_D] = frame_get_lut64(u8_p + 28*FRAME_SIZE, row_pos*2);
lut_ML[LUT_A] = frame_get_lut64(XC6_LMAP_XL_L_A,
u8_p + 23*FRAME_SIZE, row_pos*4+2);
lut_ML[LUT_B] = frame_get_lut64(XC6_LMAP_XL_L_B,
u8_p + 21*FRAME_SIZE, row_pos*4+2);
lut_ML[LUT_C] = frame_get_lut64(XC6_LMAP_XL_L_C,
u8_p + 23*FRAME_SIZE, row_pos*4);
lut_ML[LUT_D] = frame_get_lut64(XC6_LMAP_XL_L_D,
u8_p + 21*FRAME_SIZE, row_pos*4);
lut_X[LUT_A] = frame_get_lut64(XC6_LMAP_XL_X_A,
u8_p + 26*FRAME_SIZE, row_pos*4+2);
lut_X[LUT_B] = frame_get_lut64(XC6_LMAP_XL_X_B,
u8_p + 28*FRAME_SIZE, row_pos*4+2);
lut_X[LUT_C] = frame_get_lut64(XC6_LMAP_XL_X_C,
u8_p + 26*FRAME_SIZE, row_pos*4);
lut_X[LUT_D] = frame_get_lut64(XC6_LMAP_XL_X_D,
u8_p + 28*FRAME_SIZE, row_pos*4);
l_col = 1;
} else {
HERE();
@ -777,8 +788,8 @@ static int extract_logic(struct extract_state* es)
//
if (!mi20 && !mi23_M && !mi2526
&& !lut_X[0] && !lut_X[1] && !lut_X[2] && !lut_X[3]
&& !lut_ML[0] && !lut_ML[1] && !lut_ML[2] && !lut_ML[3])
&& !lut_X[LUT_A] && !lut_X[LUT_B] && !lut_X[LUT_C] && !lut_X[LUT_D]
&& !lut_ML[LUT_A] && !lut_ML[LUT_B] && !lut_ML[LUT_C] && !lut_ML[LUT_D])
continue;
//
@ -1217,8 +1228,7 @@ static int extract_logic(struct extract_state* es)
|| cfg_ml.a2d[LUT_A].out_mux == MUX_5Q
|| cfg_ml.a2d[LUT_A].out_mux == MUX_O5
|| cfg_ml.a2d[LUT_A].cy0 == CY0_O5);
rc = lut2str(lut_ML[LUT_A], l_col
? XC6_LMAP_XL_L_A : XC6_LMAP_XM_M_A,
rc = lut2str(lut_ML[LUT_A],
lut5_used,
lut6_ml[LUT_A], &cfg_ml.a2d[LUT_A].lut6_str,
lut5_ml[LUT_A], &cfg_ml.a2d[LUT_A].lut5_str);
@ -1242,8 +1252,7 @@ static int extract_logic(struct extract_state* es)
|| cfg_ml.a2d[LUT_B].out_mux == MUX_5Q
|| cfg_ml.a2d[LUT_B].out_mux == MUX_O5
|| cfg_ml.a2d[LUT_B].cy0 == CY0_O5);
rc = lut2str(lut_ML[LUT_B], l_col
? XC6_LMAP_XL_L_B : XC6_LMAP_XM_M_B,
rc = lut2str(lut_ML[LUT_B],
lut5_used,
lut6_ml[LUT_B], &cfg_ml.a2d[LUT_B].lut6_str,
lut5_ml[LUT_B], &cfg_ml.a2d[LUT_B].lut5_str);
@ -1267,8 +1276,7 @@ static int extract_logic(struct extract_state* es)
|| cfg_ml.a2d[LUT_C].out_mux == MUX_5Q
|| cfg_ml.a2d[LUT_C].out_mux == MUX_O5
|| cfg_ml.a2d[LUT_C].cy0 == CY0_O5);
rc = lut2str(lut_ML[LUT_C], l_col
? XC6_LMAP_XL_L_C : XC6_LMAP_XM_M_C,
rc = lut2str(lut_ML[LUT_C],
lut5_used,
lut6_ml[LUT_C], &cfg_ml.a2d[LUT_C].lut6_str,
lut5_ml[LUT_C], &cfg_ml.a2d[LUT_C].lut5_str);
@ -1292,8 +1300,7 @@ static int extract_logic(struct extract_state* es)
|| cfg_ml.a2d[LUT_D].out_mux == MUX_5Q
|| cfg_ml.a2d[LUT_D].out_mux == MUX_O5
|| cfg_ml.a2d[LUT_D].cy0 == CY0_O5);
rc = lut2str(lut_ML[LUT_D], l_col
? XC6_LMAP_XL_L_D : XC6_LMAP_XM_M_D,
rc = lut2str(lut_ML[LUT_D],
lut5_used,
lut6_ml[LUT_D], &cfg_ml.a2d[LUT_D].lut6_str,
lut5_ml[LUT_D], &cfg_ml.a2d[LUT_D].lut5_str);
@ -1306,8 +1313,7 @@ static int extract_logic(struct extract_state* es)
&& cfg_x.a2d[LUT_A].ff_mux != MUX_O6)
cfg_x.a2d[LUT_A].flags |= OUT_USED;
lut5_used = cfg_x.a2d[LUT_A].out_mux != 0;
rc = lut2str(lut_X[LUT_A], l_col
? XC6_LMAP_XL_X_A : XC6_LMAP_XM_X_A,
rc = lut2str(lut_X[LUT_A],
lut5_used,
lut6_x[LUT_A], &cfg_x.a2d[LUT_A].lut6_str,
lut5_x[LUT_A], &cfg_x.a2d[LUT_A].lut5_str);
@ -1321,8 +1327,7 @@ static int extract_logic(struct extract_state* es)
&& cfg_x.a2d[LUT_B].ff_mux != MUX_O6)
cfg_x.a2d[LUT_B].flags |= OUT_USED;
lut5_used = cfg_x.a2d[LUT_B].out_mux != 0;
rc = lut2str(lut_X[LUT_B], l_col
? XC6_LMAP_XL_X_B : XC6_LMAP_XM_X_B,
rc = lut2str(lut_X[LUT_B],
lut5_used,
lut6_x[LUT_B], &cfg_x.a2d[LUT_B].lut6_str,
lut5_x[LUT_B], &cfg_x.a2d[LUT_B].lut5_str);
@ -1336,8 +1341,7 @@ static int extract_logic(struct extract_state* es)
&& cfg_x.a2d[LUT_C].ff_mux != MUX_O6)
cfg_x.a2d[LUT_C].flags |= OUT_USED;
lut5_used = cfg_x.a2d[LUT_C].out_mux != 0;
rc = lut2str(lut_X[LUT_C], l_col
? XC6_LMAP_XL_X_C : XC6_LMAP_XM_X_C,
rc = lut2str(lut_X[LUT_C],
lut5_used,
lut6_x[LUT_C], &cfg_x.a2d[LUT_C].lut6_str,
lut5_x[LUT_C], &cfg_x.a2d[LUT_C].lut5_str);
@ -1351,8 +1355,7 @@ static int extract_logic(struct extract_state* es)
&& cfg_x.a2d[LUT_D].ff_mux != MUX_O6)
cfg_x.a2d[LUT_D].flags |= OUT_USED;
lut5_used = cfg_x.a2d[LUT_D].out_mux != 0;
rc = lut2str(lut_X[LUT_D], l_col
? XC6_LMAP_XL_X_D : XC6_LMAP_XM_X_D,
rc = lut2str(lut_X[LUT_D],
lut5_used,
lut6_x[LUT_D], &cfg_x.a2d[LUT_D].lut6_str,
lut5_x[LUT_D], &cfg_x.a2d[LUT_D].lut5_str);
@ -2762,8 +2765,7 @@ static int is_latch(struct fpga_device *dev)
static int str2lut(uint64_t *lut, int lut_pos, const struct fpgadev_logic_a2d *a2d)
{
int lut6_used, lut5_used, lut_map[64], rc;
uint64_t u64;
int lut6_used, lut5_used, rc;
lut6_used = a2d->lut6_str && a2d->lut6_str[0];
lut5_used = a2d->lut5_str && a2d->lut5_str[0];
@ -2771,22 +2773,19 @@ static int str2lut(uint64_t *lut, int lut_pos, const struct fpgadev_logic_a2d *a
return 0;
if (lut5_used) {
if (!lut6_used) u64 = 0;
if (!lut6_used) *lut = 0;
else {
rc = bool_str2bits(a2d->lut6_str, &u64, 32);
rc = bool_str2bits(a2d->lut6_str, lut, 32);
if (rc) FAIL(rc);
u64 <<= 32;
(*lut) <<= 32;
}
rc = bool_str2bits(a2d->lut5_str, &u64, 32);
rc = bool_str2bits(a2d->lut5_str, lut, 32);
if (rc) FAIL(rc);
xc6_lut_bitmap(lut_pos, &lut_map, 32);
} else {
// lut6_used only
rc = bool_str2bits(a2d->lut6_str, &u64, 64);
rc = bool_str2bits(a2d->lut6_str, lut, 64);
if (rc) FAIL(rc);
xc6_lut_bitmap(lut_pos, &lut_map, 64);
}
*lut = map_bits(u64, 64, lut_map);
return 0;
fail:
return rc;
@ -2826,25 +2825,41 @@ static int write_logic(struct fpga_bits* bits, struct fpga_model* model)
if (xm_col) {
mi23_M = frame_get_u64(u8_p + 23*FRAME_SIZE + byte_off);
mi2526 = frame_get_u64(u8_p + 26*FRAME_SIZE + byte_off);
lut_ML[LUT_A] = frame_get_lut64(u8_p + 24*FRAME_SIZE, row_pos*2+1);
lut_ML[LUT_B] = frame_get_lut64(u8_p + 21*FRAME_SIZE, row_pos*2+1);
lut_ML[LUT_C] = frame_get_lut64(u8_p + 24*FRAME_SIZE, row_pos*2);
lut_ML[LUT_D] = frame_get_lut64(u8_p + 21*FRAME_SIZE, row_pos*2);
lut_X[LUT_A] = frame_get_lut64(u8_p + 27*FRAME_SIZE, row_pos*2+1);
lut_X[LUT_B] = frame_get_lut64(u8_p + 29*FRAME_SIZE, row_pos*2+1);
lut_X[LUT_C] = frame_get_lut64(u8_p + 27*FRAME_SIZE, row_pos*2);
lut_X[LUT_D] = frame_get_lut64(u8_p + 29*FRAME_SIZE, row_pos*2);
lut_ML[LUT_A] = frame_get_lut64(XC6_LMAP_XM_M_A,
u8_p + 24*FRAME_SIZE, row_pos*4+2);
lut_ML[LUT_B] = frame_get_lut64(XC6_LMAP_XM_M_B,
u8_p + 21*FRAME_SIZE, row_pos*4+2);
lut_ML[LUT_C] = frame_get_lut64(XC6_LMAP_XM_M_C,
u8_p + 24*FRAME_SIZE, row_pos*4);
lut_ML[LUT_D] = frame_get_lut64(XC6_LMAP_XM_M_D,
u8_p + 21*FRAME_SIZE, row_pos*4);
lut_X[LUT_A] = frame_get_lut64(XC6_LMAP_XM_X_A,
u8_p + 27*FRAME_SIZE, row_pos*4+2);
lut_X[LUT_B] = frame_get_lut64(XC6_LMAP_XM_X_B,
u8_p + 29*FRAME_SIZE, row_pos*4+2);
lut_X[LUT_C] = frame_get_lut64(XC6_LMAP_XM_X_C,
u8_p + 27*FRAME_SIZE, row_pos*4);
lut_X[LUT_D] = frame_get_lut64(XC6_LMAP_XM_X_D,
u8_p + 29*FRAME_SIZE, row_pos*4);
} else { // xl
mi23_M = 0;
mi2526 = frame_get_u64(u8_p + 25*FRAME_SIZE + byte_off);
lut_ML[LUT_A] = frame_get_lut64(u8_p + 23*FRAME_SIZE, row_pos*2+1);
lut_ML[LUT_B] = frame_get_lut64(u8_p + 21*FRAME_SIZE, row_pos*2+1);
lut_ML[LUT_C] = frame_get_lut64(u8_p + 23*FRAME_SIZE, row_pos*2);
lut_ML[LUT_D] = frame_get_lut64(u8_p + 21*FRAME_SIZE, row_pos*2);
lut_X[LUT_A] = frame_get_lut64(u8_p + 26*FRAME_SIZE, row_pos*2+1);
lut_X[LUT_B] = frame_get_lut64(u8_p + 28*FRAME_SIZE, row_pos*2+1);
lut_X[LUT_C] = frame_get_lut64(u8_p + 26*FRAME_SIZE, row_pos*2);
lut_X[LUT_D] = frame_get_lut64(u8_p + 28*FRAME_SIZE, row_pos*2);
lut_ML[LUT_A] = frame_get_lut64(XC6_LMAP_XL_L_A,
u8_p + 23*FRAME_SIZE, row_pos*4+2);
lut_ML[LUT_B] = frame_get_lut64(XC6_LMAP_XL_L_B,
u8_p + 21*FRAME_SIZE, row_pos*4+2);
lut_ML[LUT_C] = frame_get_lut64(XC6_LMAP_XL_L_C,
u8_p + 23*FRAME_SIZE, row_pos*4);
lut_ML[LUT_D] = frame_get_lut64(XC6_LMAP_XL_L_D,
u8_p + 21*FRAME_SIZE, row_pos*4);
lut_X[LUT_A] = frame_get_lut64(XC6_LMAP_XL_X_A,
u8_p + 26*FRAME_SIZE, row_pos*4+2);
lut_X[LUT_B] = frame_get_lut64(XC6_LMAP_XL_X_B,
u8_p + 28*FRAME_SIZE, row_pos*4+2);
lut_X[LUT_C] = frame_get_lut64(XC6_LMAP_XL_X_C,
u8_p + 26*FRAME_SIZE, row_pos*4);
lut_X[LUT_D] = frame_get_lut64(XC6_LMAP_XL_X_D,
u8_p + 28*FRAME_SIZE, row_pos*4);
}
// Except for XC6_ML_CIN_USED (which is set by a switch elsewhere),
// everything else should be 0.

View File

@ -736,7 +736,7 @@ static void printf_routing_2minors(const uint8_t* bits, int row, int major,
bit_str[i*2+1] = '1';
}
// todo: might be nice to add the tile y and x here
printf("r%i ma%i v64_%02i mip%02i %s\n",
printf("r%i ma%i v64_%i mip%i %s\n",
row, major, y, even_minor, bit_str);
}
}
@ -755,7 +755,7 @@ static void printf_v64_mi20(const uint8_t* bits, int row, int major)
if (u64) {
for (i = 0; i < 64; i++)
bit_str[i] = (u64 & (1ULL << i)) ? '1' : '0';
printf("r%i ma%i v64_%02i mi20 %s\n",
printf("r%i ma%i v64_%i mi20 %s\n",
row, major, y, bit_str);
num_bits_on = 0;
for (i = 0; i < 64; i++) {
@ -768,7 +768,7 @@ static void printf_v64_mi20(const uint8_t* bits, int row, int major)
for (i = 0; i < 64; i++) {
if (!(u64 & (1ULL << i)))
continue;
printf("r%i ma%i v64_%02i mi20 b%i\n",
printf("r%i ma%i v64_%i mi20 b%i\n",
row, major, y, i);
}
}
@ -776,37 +776,53 @@ static void printf_v64_mi20(const uint8_t* bits, int row, int major)
}
}
static void printf_lut(const uint8_t* bits, int row, int major,
int minor, int v32_i)
static void printf_word(int word, int row, int major, int minor, int v16_i)
{
char bit_str[64];
uint64_t u64;
char bit_str[XC6_WORD_BITS];
int i, num_bits_on;
u64 = frame_get_lut64(&bits[minor*FRAME_SIZE], v32_i);
if (u64) {
num_bits_on = 0;
for (i = 0; i < 64; i++) {
if (u64 & (1ULL << i))
num_bits_on++;
}
if (num_bits_on < 5) {
printf("r%i ma%02i v32_%02i mip%02i_lut", row,
major, v32_i, minor);
for (i = 0; i < 64; i++) {
if (u64 & (1ULL << i))
printf(" b%i", i);
}
printf("\n");
} else {
for (i = 0; i < 64; i++)
bit_str[i] = (u64 & (1ULL << i)) ? '1' : '0';
printf("r%i ma%02i v32_%02i mip%02i_lut %.64s\n", row,
major, v32_i, minor, bit_str);
num_bits_on = 0;
for (i = 0; i < XC6_WORD_BITS; i++) {
if (word & (1ULL << i))
num_bits_on++;
}
if (num_bits_on >= 1 && num_bits_on <= 4) {
printf("r%i ma%i v%i_%i mi%i", row,
major, XC6_WORD_BITS, v16_i, minor);
for (i = 0; i < XC6_WORD_BITS; i++) {
if (word & (1ULL << i))
printf(" b%i", i);
}
printf("\n");
} else {
for (i = 0; i < XC6_WORD_BITS; i++)
bit_str[i] = (word & (1ULL << i)) ? '1' : '0';
printf("r%i ma%i v%i_%i mi%i %.*s\n", row,
major, XC6_WORD_BITS, v16_i, minor, XC6_WORD_BITS, bit_str);
}
}
static void printf_lut_words(const uint8_t *major_bits, int row, int major, int minor, int v16_i)
{
int off_in_frame, w;
off_in_frame = v16_i*XC6_WORD_BYTES;
if (off_in_frame >= XC6_HCLK_POS)
off_in_frame += XC6_HCLK_BYTES;
w = frame_get_pinword(&major_bits[minor*FRAME_SIZE + off_in_frame]);
if (w) printf_word(w, row, major, minor, v16_i);
w = frame_get_pinword(&major_bits[minor*FRAME_SIZE + off_in_frame + XC6_WORD_BYTES]);
if (w) printf_word(w, row, major, minor, v16_i+1);
w = frame_get_pinword(&major_bits[(minor+1)*FRAME_SIZE + off_in_frame]);
if (w) printf_word(w, row, major, minor+1, v16_i);
w = frame_get_pinword(&major_bits[(minor+1)*FRAME_SIZE + off_in_frame + XC6_WORD_BYTES]);
if (w) printf_word(w, row, major, minor+1, v16_i+1);
}
static int dump_maj_zero(const uint8_t* bits, int row, int major)
{
int minor;
@ -874,8 +890,8 @@ static int dump_maj_logic(const uint8_t* bits, int row, int major)
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+1);
printf_lut_words(bits, row, major, 21, i*4);
printf_lut_words(bits, row, major, 21, i*4+2);
}
if (logdev_end < 15)
printf_extrabits(bits, 21, 2, i*64 + XC6_HCLK_BITS, (15-logdev_end)*64, row, major);
@ -884,8 +900,8 @@ static int dump_maj_logic(const uint8_t* bits, int row, int major)
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+1);
printf_lut_words(bits, row, major, 24, i*4);
printf_lut_words(bits, row, major, 24, i*4+2);
}
if (logdev_end < 15)
printf_extrabits(bits, 24, 2, i*64 + XC6_HCLK_BITS, (15-logdev_end)*64, row, major);
@ -896,10 +912,10 @@ static int dump_maj_logic(const uint8_t* bits, int row, int major)
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, 29, i*2);
printf_lut(bits, row, major, 27, i*2+1);
printf_lut(bits, row, major, 29, i*2+1);
printf_lut_words(bits, row, major, 27, i*4);
printf_lut_words(bits, row, major, 29, i*4);
printf_lut_words(bits, row, major, 27, i*4+2);
printf_lut_words(bits, row, major, 29, i*4+2);
}
if (logdev_end < 15)
printf_extrabits(bits, 27, 4, i*64 + XC6_HCLK_BITS, (15-logdev_end)*64, row, major);
@ -909,10 +925,10 @@ static int dump_maj_logic(const uint8_t* bits, int row, int major)
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, 23, i*2);
printf_lut(bits, row, major, 21, i*2+1);
printf_lut(bits, row, major, 23, i*2+1);
printf_lut_words(bits, row, major, 21, i*4);
printf_lut_words(bits, row, major, 23, i*4);
printf_lut_words(bits, row, major, 21, i*4+2);
printf_lut_words(bits, row, major, 23, i*4+2);
}
if (logdev_end < 15)
printf_extrabits(bits, 21, 4, i*64 + XC6_HCLK_BITS, (15-logdev_end)*64, row, major);
@ -922,10 +938,10 @@ static int dump_maj_logic(const uint8_t* bits, int row, int major)
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, 28, i*2);
printf_lut(bits, row, major, 26, i*2+1);
printf_lut(bits, row, major, 28, i*2+1);
printf_lut_words(bits, row, major, 26, i*4);
printf_lut_words(bits, row, major, 28, i*4);
printf_lut_words(bits, row, major, 26, i*4+2);
printf_lut_words(bits, row, major, 28, i*4+2);
}
if (logdev_end < 15)
printf_extrabits(bits, 26, 4, i*64 + XC6_HCLK_BITS, (15-logdev_end)*64, row, major);

View File

@ -408,32 +408,32 @@ int fdev_logic_setconf(struct fpga_model* model, int y, int x,
int type_idx, const struct fpgadev_logic* logic_cfg)
{
struct fpga_device* dev;
int lut, rc;
int lut;
RC_CHECK(model);
// todo: if we delete the entire old config, why do we do the
// config OR'ing below?
fdev_delete(model, y, x, DEV_LOGIC, type_idx);
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
if (!dev) FAIL(EINVAL);
rc = reset_required_pins(dev);
if (rc) FAIL(rc);
// todo: should we delete the current device configuration?
RC_ASSERT(model, dev);
reset_required_pins(dev);
for (lut = LUT_A; lut <= LUT_D; lut++) {
if (logic_cfg->a2d[lut].lut_mode)
dev->u.logic.a2d[lut].lut_mode = logic_cfg->a2d[lut].lut_mode;
if (logic_cfg->a2d[lut].flags & OUT_USED)
dev->u.logic.a2d[lut].flags |= OUT_USED;
if (logic_cfg->a2d[lut].lut6_str) {
rc = fdev_logic_a2d_lut(model, y, x, type_idx,
fdev_logic_a2d_lut(model, y, x, type_idx,
lut, 6, logic_cfg->a2d[lut].lut6_str, ZTERM);
if (rc) FAIL(rc);
}
if (logic_cfg->a2d[lut].lut5_str) {
rc = fdev_logic_a2d_lut(model, y, x, type_idx,
fdev_logic_a2d_lut(model, y, x, type_idx,
lut, 5, logic_cfg->a2d[lut].lut5_str, ZTERM);
if (rc) FAIL(rc);
}
if (logic_cfg->a2d[lut].ff) {
if (!logic_cfg->a2d[lut].ff_mux
|| !logic_cfg->a2d[lut].ff_srinit)
FAIL(EINVAL);
RC_ASSERT(model, logic_cfg->a2d[lut].ff_mux
&& logic_cfg->a2d[lut].ff_srinit);
dev->u.logic.a2d[lut].ff = logic_cfg->a2d[lut].ff;
dev->u.logic.a2d[lut].ff_mux = logic_cfg->a2d[lut].ff_mux;
dev->u.logic.a2d[lut].ff_srinit = logic_cfg->a2d[lut].ff_srinit;
@ -454,8 +454,8 @@ int fdev_logic_setconf(struct fpga_model* model, int y, int x,
dev->u.logic.a2d[lut].flags |= LUT5VAL_SET;
dev->u.logic.a2d[lut].lut5_val = logic_cfg->a2d[lut].lut5_val;
}
if (logic_cfg->a2d[lut].flags & LUTMODE_ROM)
dev->u.logic.a2d[lut].flags |= LUTMODE_ROM;
if (logic_cfg->a2d[lut].flags & LUTMODE_ROM2)
dev->u.logic.a2d[lut].flags |= LUTMODE_ROM2;
if (logic_cfg->a2d[lut].ram_mode)
dev->u.logic.a2d[lut].ram_mode = logic_cfg->a2d[lut].ram_mode;
if (logic_cfg->a2d[lut].di_mux)
@ -475,13 +475,14 @@ int fdev_logic_setconf(struct fpga_model* model, int y, int x,
dev->u.logic.cout_used = logic_cfg->cout_used;
if (logic_cfg->precyinit)
dev->u.logic.precyinit = logic_cfg->precyinit;
if (logic_cfg->wa7_used)
dev->u.logic.wa7_used = logic_cfg->wa7_used;
if (logic_cfg->wa8_used)
dev->u.logic.wa8_used = logic_cfg->wa8_used;
dev->instantiated = 1;
rc = fdev_set_required_pins(model, y, x, DEV_LOGIC, type_idx);
if (rc) FAIL(rc);
return 0;
fail:
return rc;
fdev_set_required_pins(model, y, x, DEV_LOGIC, type_idx);
RC_RETURN(model);
}
int fdev_logic_a2d_out_used(struct fpga_model* model, int y, int x,
@ -947,6 +948,14 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
add_req_inpin(dev, LI_BX);
add_req_inpin(dev, LI_CX);
}
if (dev->u.logic.we_mux == WEMUX_WE)
add_req_inpin(dev, LI_WE);
else if (dev->u.logic.we_mux == WEMUX_CE)
add_req_inpin(dev, LI_CE);
if (dev->u.logic.wa7_used)
add_req_inpin(dev, LI_CX);
if (dev->u.logic.wa8_used)
add_req_inpin(dev, LI_BX);
for (i = LUT_A; i <= LUT_D; i++) {
if (dev->u.logic.a2d[i].flags & OUT_USED) {
// LO_A..LO_D are in sequence
@ -961,7 +970,8 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
add_req_outpin(dev, LO_AQ+i);
}
if (dev->u.logic.a2d[i].ff_mux == MUX_X
|| dev->u.logic.a2d[i].cy0 == CY0_X) {
|| dev->u.logic.a2d[i].cy0 == CY0_X
|| dev->u.logic.a2d[i].di_mux == DIMUX_X) {
// LI_AX..LI_DX are in sequence
add_req_inpin(dev, LI_AX+i);
}
@ -985,6 +995,8 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
|| dev->u.logic.a2d[i].out_mux == MUX_XOR)
&& !dev->u.logic.precyinit)
add_req_inpin(dev, LI_CIN);
if (dev->u.logic.a2d[i].flags & (LUT6VAL_SET|LUT5VAL_SET))
add_req_inpin(dev, LI_CLK);
}
return 0;
}

View File

@ -312,12 +312,35 @@ int printf_LOGIC(FILE* f, struct fpga_model* model,
cfg = &tile->devs[dev_i].u.logic;
for (j = LUT_D; j >= LUT_A; j--) {
switch (cfg->a2d[j].lut_mode) {
case LUTMODE_LUT:
fprintf(f, "%s %c_mode LUT\n", pref, 'A'+j);
// todo: A6_str, A5_str
break;
case LUTMODE_ROM:
fprintf(f, "%s %c_mode ROM\n", pref, 'A'+j);
fprintf(f, "%s %c_val 0x%016lX\n", pref, 'A'+j, cfg->a2d[j].lut_val);
break;
case LUTMODE_RAM:
fprintf(f, "%s %c_mode RAM\n", pref, 'A'+j);
fprintf(f, "%s %c_val 0x%016lX\n", pref, 'A'+j, cfg->a2d[j].lut_val);
break;
// default: RC_FAIL(model, EINVAL);
}
if (cfg->a2d[j].lut6_str && cfg->a2d[j].lut6_str[0])
fprintf(f, "%s %c6_lut_str %s\n", pref, 'A'+j,
cfg->a2d[j].lut6_str);
if (cfg->a2d[j].lut5_str && cfg->a2d[j].lut5_str[0])
fprintf(f, "%s %c5_lut_str %s\n", pref, 'A'+j,
cfg->a2d[j].lut5_str);
if (cfg->a2d[j].flags & LUT6VAL_SET)
fprintf(f, "%s %c6_lut_val 0x%016lX\n", pref, 'A'+j, cfg->a2d[j].lut6_val);
if (cfg->a2d[j].flags & LUT5VAL_SET)
fprintf(f, "%s %c5_lut_val 0x%08X\n", pref, 'A'+j, cfg->a2d[j].lut5_val);
if (cfg->a2d[j].flags & LUTMODE_ROM2)
fprintf(f, "%s %c_rom\n", pref, 'A'+j);
if (cfg->a2d[j].flags & OUT_USED)
fprintf(f, "%s %c_used\n", pref, 'A'+j);
@ -439,12 +462,6 @@ int printf_LOGIC(FILE* f, struct fpga_model* model,
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
if (cfg->a2d[j].flags & LUT6VAL_SET)
fprintf(f, "%s %c6_lut_val 0x%016lX\n", pref, 'A'+j, cfg->a2d[j].lut6_val);
if (cfg->a2d[j].flags & LUT5VAL_SET)
fprintf(f, "%s %c5_lut_val 0x%08X\n", pref, 'A'+j, cfg->a2d[j].lut5_val);
if (cfg->a2d[j].flags & LUTMODE_ROM)
fprintf(f, "%s %c_rom\n", pref, 'A'+j);
switch (cfg->a2d[j].di_mux) {
case DIMUX_MC31:
fprintf(f, "%s %c_di_mux MC31\n", pref, 'A'+j);
@ -506,6 +523,10 @@ int printf_LOGIC(FILE* f, struct fpga_model* model,
break;
case 0: break; default: RC_FAIL(model, EINVAL);
}
if (cfg->wa7_used)
fprintf(f, "%s wa7_used\n", pref);
if (cfg->wa8_used)
fprintf(f, "%s wa8_used\n", pref);
RC_RETURN(model);
}
@ -515,7 +536,7 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
struct fpga_device* dev;
char cmp_str[128], buf[32];
char *endptr;
long int val;
uint64_t val;
int i, j, rc;
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
@ -530,7 +551,7 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
}
snprintf(cmp_str, sizeof(cmp_str), "%c_rom", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
dev->u.logic.a2d[i].flags |= LUTMODE_ROM;
dev->u.logic.a2d[i].flags |= LUTMODE_ROM2;
goto inst_1;
}
}
@ -546,6 +567,14 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
dev->u.logic.cout_used = 1;
goto inst_1;
}
if (!str_cmp(w1, w1_len, "wa7_used", ZTERM)) {
dev->u.logic.wa7_used = 1;
goto inst_1;
}
if (!str_cmp(w1, w1_len, "wa8_used", ZTERM)) {
dev->u.logic.wa8_used = 1;
goto inst_1;
}
// The remaining attributes all require 2 words.
if (w2_len < 1) return 0;
@ -669,14 +698,17 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
if (w2_len < 3
|| w2[0] != '0'
|| (w2[1] != 'x' && w2[1] != 'X')
|| w2_len > 2+16) return 0;
|| w2_len > 2+16) { HERE(); return 0; }
errno = 0;
for (j = 2; j < w2_len; j++)
buf[j-2] = w2[j];
buf[j-2] = 0;
val = strtol(buf, &endptr, /*base*/ 16);
if (errno || *endptr) return 0;
val = strtoull(buf, &endptr, /*base*/ 16);
if (errno || *endptr) {
fprintf(stderr, "#E %s:%i errno %i endptr '%s'\n",
__FILE__, __LINE__, errno, endptr);
return 0;
}
dev->u.logic.a2d[i].lut6_val = val;
dev->u.logic.a2d[i].flags |= LUT6VAL_SET;
goto inst_2;
@ -691,7 +723,7 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
for (j = 2; j < w2_len; j++)
buf[j-2] = w2[j];
buf[j-2] = 0;
val = strtol(buf, &endptr, /*base*/ 16);
val = strtoul(buf, &endptr, /*base*/ 16);
if (errno || *endptr) return 0;
dev->u.logic.a2d[i].lut5_val = val;

View File

@ -570,24 +570,18 @@ void frame_set_u64(uint8_t* frame_d, uint64_t v)
frame_set_u32(frame_d+4, high_w);
}
uint64_t frame_get_lut64(const uint8_t* two_minors, int v32)
uint64_t frame_get_lut64(int lut_pos, const uint8_t *two_minors, int v16)
{
int off_in_frame, i;
uint32_t m0, m1;
uint64_t lut64;
int off_in_frame, lutw_tl, lutw_tr, lutw_bl, lutw_br;
off_in_frame = v32*4;
if (off_in_frame >= 64)
off_in_frame = v16*XC6_WORD_BYTES;
if (off_in_frame >= XC6_HCLK_POS)
off_in_frame += XC6_HCLK_BYTES;
m0 = frame_get_u32(&two_minors[off_in_frame]);
m1 = frame_get_u32(&two_minors[FRAME_SIZE + off_in_frame]);
lut64 = 0;
for (i = 0; i < 32; i++) {
if (m0 & (1<<i)) lut64 |= 1ULL << (2*i);
if (m1 & (1<<i)) lut64 |= 1ULL << (2*i+1);
}
return lut64;
lutw_tl = frame_get_pinword(two_minors + off_in_frame);
lutw_tr = frame_get_pinword(two_minors + FRAME_SIZE + off_in_frame);
lutw_bl = frame_get_pinword(two_minors + off_in_frame + XC6_WORD_BYTES);
lutw_br = frame_get_pinword(two_minors + FRAME_SIZE + off_in_frame + XC6_WORD_BYTES);
return xc6_lut_value(lut_pos, lutw_tl, lutw_tr, lutw_bl, lutw_br);
}
void frame_set_lut64(uint8_t* two_minors, int v32, uint64_t v)

View File

@ -92,7 +92,7 @@ void frame_set_u16(uint8_t* frame_d, uint16_t v);
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);
uint64_t frame_get_lut64(int lut_pos, const uint8_t *two_minors, int v16);
// 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))

View File

@ -416,10 +416,11 @@ enum {
"COUT" }
enum { LUT_A = 0, LUT_B, LUT_C, LUT_D }; // offset into a2d[]
#define OUT_USED 0x0001
#define LUT6VAL_SET 0x0002
#define LUT5VAL_SET 0x0004
#define LUTMODE_ROM 0x0008
#define OUT_USED 0x0001
#define LUT6VAL_SET 0x0002
#define LUT5VAL_SET 0x0004
#define LUTMODE_ROM2 0x0008
enum { LUTMODE_LUT = 1, LUTMODE_ROM, LUTMODE_RAM };
enum { FF_SRINIT0 = 1, FF_SRINIT1 };
enum { MUX_O6 = 1, MUX_O5, MUX_5Q, MUX_X, MUX_CY, MUX_XOR, MUX_F7, MUX_F8, MUX_MC31 };
enum { FF_OR2L = 1, FF_AND2L, FF_LATCH, FF_FF };
@ -436,17 +437,20 @@ enum { DIMUX_MC31 = 1, DIMUX_X, DIMUX_DX, DIMUX_BDI1 };
struct fpgadev_logic_a2d
{
// LUT/RAM/ROM mode:
// - Both the lut6 and lut5 must have the same mode of either
// LUT, RAM or ROM.
// - If neither LUT6VAL_SET nor LUT5VAL_SET are on, the mode is LUT.
// - If either LUT6VAL_SET or LUT5VAL_SET are on, lut6_str and
// lut5_str are ignored, and the mode is RAM, or ROM if
// LUTMODE_ROM is on.
int flags; // OUT_USED, LUT6VAL_SET, LUT5VAL_SET, LUTMODE_ROM2
char* lut6_str;
char* lut5_str;
int flags; // OUT_USED, LUT6VAL_SET, LUT5VAL_SET, LUTMODE_ROM
char* lut6_str;
char* lut5_str;
// ROM and LUT are almost identical, RAM is a completely
// different mode for the entire slice (M only).
// In LUT or ROM mode, DI1/DI2, MC31 and WA1..WA8
// should not be connected.
// lut_mode should always be set for a used lut.
int lut_mode; // LUTMODE_LUT, LUTMODE_ROM, LUTMODE_RAM
uint64_t lut_val;
int out_used;
int ff_mux; // O6, O5, X, F7(a/c), F8(b), MC31(d), CY, XOR
int ff_srinit; // SRINIT0, SRINIT1
int ff5_srinit; // SRINIT0, SRINIT1
@ -454,12 +458,24 @@ struct fpgadev_logic_a2d
int ff; // OR2L, AND2L, LATCH, FF
int cy0; // X, O5
// distributed memory related - if either LUT6VAL_SET or LUT5VAL_SET are on:
uint64_t lut6_val;
uint32_t lut5_val;
// ram_mode is only valid if LUTMODE_ROM is not set. If both
// lut6_val and lut5_val are used, they must use the same ram_mode.
int ram_mode; // DPRAM64, DPRAM32, SPRAM64, SPRAM32, SRL32, SRL16
// distributed memory related - if either LUT6VAL_SET or LUT5VAL_SET are on:
uint64_t lut6_val;
uint32_t lut5_val;
// Requirements for LUTMODE_RAM:
// - input on CLK and WE pins
// - SRL32 and SRL16 should have O6 or MC31 output
// - MC31 is only driven in SRL32 or SRL16 mode.
// - SRL32 and SRL16 require A1 tied to VCC
// - DRPAM64, SPRAM64 and SRL32 require DI1 (DI1MUX)
// - DPRAM32, SPRAM32 and SRL16 require DI2 (AI..DI)
// - dual or single port RAM requires WA1..WA5/6 (D1..D5/6)
// - When dual or single port RAM should be used in any
// of the 4 luts, the lut-D must be one of them.
// - With WA7 or WA8 used, all other luts should be either
// unused or in DPRAM64 or SPRAM64 mode.
int ram_mode; // only with LUTMODE_RAM
// DPRAM64, DPRAM32, SPRAM64, SPRAM32, SRL32, SRL16
int di_mux; // only for A-C
// DIMUX_MC31, DIMUX_X, DIMUX_DX (b/c), DIMUX_BDI1 (a)
};
@ -474,6 +490,8 @@ struct fpgadev_logic
int we_mux; // WEMUX_WE, WEMUX_CE
int cout_used;
int precyinit; // PRECYINIT_0, PRECYINIT_1, PRECYINIT_AX
int wa7_used;
int wa8_used;
};
//

View File

@ -1544,53 +1544,64 @@ void free_xc6_routing_bitpos(struct xc6_routing_bitpos* bitpos)
free(bitpos);
}
void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits)
uint64_t xc6_lut_value(int lut_pos, int lutw_tl, int lutw_tr, int lutw_bl, int lutw_br)
{
static const int xc6_lut_wiring[4][16] = {
// XC6_LMAP_ macros are offsets into this array:
static const int xc6_lut_wiring[4][8] = {
// xm-m a; xm-m c;
{ 17, 19, 16, 18, 23, 21, 22, 20, 31, 29, 30, 28, 25, 27, 24, 26 },
{ 15, 14, 12, 13, 8, 9, 11, 10 },
// xm-m b; xm-m d;
{ 47, 45, 46, 44, 41, 43, 40, 42, 33, 35, 32, 34, 39, 37, 38, 36 },
{ 0, 1, 3, 2, 7, 6, 4, 5 },
// xm-x a; xm-x b; xl-l b; xl-l d; xl-x a; xl-x b;
{ 31, 29, 30, 28, 27, 25, 26, 24, 19, 17, 18, 16, 23, 21, 22, 20 },
{ 8, 9, 10, 11, 14, 15, 12, 13 },
// xm-x c; xm-x d; xl-l a; xl-l c; xl-x c; xl-x d;
{ 33, 35, 32, 34, 37, 39, 36, 38, 45, 47, 44, 46, 41, 43, 40, 42 }};
{ 7, 6, 5, 4, 1, 0, 3, 2 }};
int map32[32];
int i;
uint64_t v;
int full_word_positions[16], i;
// expand from 16 to 32 bit positions
// expand 8 bits to 16 bits
for (i = 0; i < 8; i++) {
full_word_positions[i] = xc6_lut_wiring[lut_pos][i];
full_word_positions[i+8] = (xc6_lut_wiring[lut_pos][i]+8)%16;
}
// swap top and bottom words if needed
if (lut_pos == XC6_LMAP_XM_M_B
|| lut_pos == XC6_LMAP_XM_M_D
|| lut_pos == XC6_LMAP_XM_X_C
|| lut_pos == XC6_LMAP_XM_X_D
|| lut_pos == XC6_LMAP_XL_L_A
|| lut_pos == XC6_LMAP_XL_L_C
|| lut_pos == XC6_LMAP_XL_X_C
|| lut_pos == XC6_LMAP_XL_X_D) {
int temp_w;
temp_w = lutw_tl; lutw_tl = lutw_bl; lutw_bl = temp_w;
temp_w = lutw_tr; lutw_tr = lutw_br; lutw_br = temp_w;
}
// assemble bits
v = 0;
for (i = 0; i < 16; i++) {
map32[i] = xc6_lut_wiring[lut_pos][i];
if (map32[i] < 32) {
if (map32[i] < 16) HERE();
map32[16+i] = map32[i]-16;
} else {
if (map32[i] > 47) HERE();
map32[16+i] = map32[i]+16;
}
}
// expand from 32 to 64 for either lut6 only or lut5/lut6 pair.
for (i = 0; i < 32; i++) {
if (num_bits == 32) {
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];
(*map)[32+i] = ((*map)[i]+32)%64;
}
// top side
if (lutw_tr & 1<<full_word_positions[i])
v |= 1ULL << (i*2);
if (lutw_tr & 1<<full_word_positions[i+1])
v |= 1ULL << (i*2+1);
if (lutw_tl & 1<<full_word_positions[i])
v |= 1ULL << (i*2+2);
if (lutw_tl & 1<<full_word_positions[i+1])
v |= 1ULL << (i*2+3);
// bottom side
if (lutw_br & 1<<full_word_positions[i])
v |= 1ULL << (32+i*2);
if (lutw_br & 1<<full_word_positions[i+1])
v |= 1ULL << (32+i*2+1);
if (lutw_bl & 1<<full_word_positions[i])
v |= 1ULL << (32+i*2+2);
if (lutw_bl & 1<<full_word_positions[i+1])
v |= 1ULL << (32+i*2+3);
}
return v;
}

View File

@ -286,11 +286,7 @@ void free_xc6_routing_bitpos(struct xc6_routing_bitpos* bitpos);
#define XC6_LMAP_XL_X_C 3
#define XC6_LMAP_XL_X_D 3
// num_bits must be 32 or 64. If it is 32, the lower
// 32 entries of map contain the bit positions for lut5,
// the upper 32 entries of map the ones for lut6.
// In either case 64 entries are written to map.
void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits);
uint64_t xc6_lut_value(int lut_pos, int lutw_tl, int lutw_tr, int lutw_bl, int lutw_br);
//
// logic configuration