more work on distributed memory, fixes

This commit is contained in:
Wolfgang Spraul 2013-02-15 21:32:12 -05:00
parent 0a320d67f6
commit 8a4402bbc8
5 changed files with 140 additions and 11 deletions

View File

@ -2175,6 +2175,9 @@ static int test_dist_mem(struct test_state *tstate)
rc = test_logic(tstate, y, x, type_i, &logic_cfg);
if (rc) FAIL(rc);
}
// todo: we could test a configuration with a memory lut in the
// first and last position of a row (doesn't work easily
// with test_logic() subfunction right now).
return 0;
fail:
return rc;

View File

@ -762,8 +762,8 @@ static int extract_logic(struct extract_state* es)
//
// Step 3:
//
// Parse all bits from minors 20 and 25/26 into more
// easily usable cfg_ml and cfg_x structures.
// Parse all bits from minors 20, 23 and 25/26 into
// more easily usable cfg_ml and cfg_x structures.
//
memset(&cfg_ml, 0, sizeof(cfg_ml));
@ -817,6 +817,80 @@ static int extract_logic(struct extract_state* es)
mi20 &= ~(1ULL<<XC6_ML_A5_FFSRINIT_1);
}
// minor 23
if (mi23_M & (1ULL<<XC6_M_A_RAM)) {
// todo: determine SPRAM from connectivity?
cfg_ml.a2d[LUT_A].ram_mode =
(mi23_M & (1ULL<<XC6_M_A_X2))
? DPRAM32 : DPRAM64;
mi23_M &= ~((1ULL<<XC6_M_A_RAM)|(1ULL<<XC6_M_A_X2));
} else if (mi23_M & (1ULL<<XC6_M_A_SHIFT_REG)) {
cfg_ml.a2d[LUT_A].ram_mode =
(mi23_M & (1ULL<<XC6_M_A_X2))
? SRL16 : SRL32;
mi23_M &= ~((1ULL<<XC6_M_A_SHIFT_REG)|(1ULL<<XC6_M_A_X2));
}
if (mi23_M & (1ULL<<XC6_M_B_RAM)) {
// todo: determine SPRAM from connectivity?
cfg_ml.a2d[LUT_B].ram_mode =
(mi23_M & (1ULL<<XC6_M_B_X2))
? DPRAM32 : DPRAM64;
mi23_M &= ~((1ULL<<XC6_M_B_RAM)|(1ULL<<XC6_M_B_X2));
} else if (mi23_M & (1ULL<<XC6_M_B_SHIFT_REG)) {
cfg_ml.a2d[LUT_B].ram_mode =
(mi23_M & (1ULL<<XC6_M_B_X2))
? SRL16 : SRL32;
mi23_M &= ~((1ULL<<XC6_M_B_SHIFT_REG)|(1ULL<<XC6_M_B_X2));
}
if (mi23_M & (1ULL<<XC6_M_C_RAM)) {
// todo: determine SPRAM from connectivity?
cfg_ml.a2d[LUT_C].ram_mode =
(mi23_M & (1ULL<<XC6_M_C_X2))
? DPRAM32 : DPRAM64;
mi23_M &= ~((1ULL<<XC6_M_C_RAM)|(1ULL<<XC6_M_C_X2));
} else if (mi23_M & (1ULL<<XC6_M_C_SHIFT_REG)) {
cfg_ml.a2d[LUT_C].ram_mode =
(mi23_M & (1ULL<<XC6_M_C_X2))
? SRL16 : SRL32;
mi23_M &= ~((1ULL<<XC6_M_C_SHIFT_REG)|(1ULL<<XC6_M_C_X2));
}
if (mi23_M & (1ULL<<XC6_M_D_RAM)) {
// todo: determine SPRAM from connectivity?
cfg_ml.a2d[LUT_D].ram_mode =
(mi23_M & (1ULL<<XC6_M_D_X2))
? DPRAM32 : DPRAM64;
mi23_M &= ~((1ULL<<XC6_M_D_RAM)|(1ULL<<XC6_M_D_X2));
} else if (mi23_M & (1ULL<<XC6_M_D_SHIFT_REG)) {
cfg_ml.a2d[LUT_D].ram_mode =
(mi23_M & (1ULL<<XC6_M_D_X2))
? SRL16 : SRL32;
mi23_M &= ~((1ULL<<XC6_M_D_SHIFT_REG)|(1ULL<<XC6_M_D_X2));
}
if (mi23_M & (1ULL<<XC6_M_ADI1MUX_AX)) {
cfg_ml.a2d[LUT_A].di_mux = DIMUX_X;
mi23_M &= ~(1ULL<<XC6_M_ADI1MUX_AX);
}
if (mi23_M & (1ULL<<XC6_M_BDI1MUX_BX)) {
cfg_ml.a2d[LUT_B].di_mux = DIMUX_X;
mi23_M &= ~(1ULL<<XC6_M_BDI1MUX_BX);
}
if (mi23_M & (1ULL<<XC6_M_CDI1MUX_CX)) {
cfg_ml.a2d[LUT_C].di_mux = DIMUX_X;
mi23_M &= ~(1ULL<<XC6_M_CDI1MUX_CX);
}
if (mi23_M & (1ULL<<XC6_M_WEMUX_CE)) {
cfg_ml.we_mux = WEMUX_CE;
mi23_M &= ~(1ULL<<XC6_M_WEMUX_CE);
}
if (mi23_M & (1ULL<<XC6_M_WA8_USED)) {
cfg_ml.wa8_used = 1;
mi23_M &= ~(1ULL<<XC6_M_WA8_USED);
}
if (mi23_M & (1ULL<<XC6_M_WA7_USED)) {
cfg_ml.wa7_used = 1;
mi23_M &= ~(1ULL<<XC6_M_WA7_USED);
}
// minor 25/26
if (mi2526 & (1ULL<<XC6_ML_D_CY0_O5)) {
cfg_ml.a2d[LUT_D].cy0 = CY0_O5;
@ -1432,12 +1506,34 @@ static int extract_logic(struct extract_state* es)
//
// Remove all bits.
//
frame_set_u64(u8_p + 20*FRAME_SIZE + byte_off,
frame_get_u64(u8_p + 20*FRAME_SIZE + byte_off)
& ~XC6_MI20_LOGIC_MASK);
last_minor = l_col ? 29 : 30;
for (i = 21; i <= last_minor; i++)
frame_set_u64(u8_p + i*FRAME_SIZE + byte_off, 0);
if (cfg_ml.a2d[LUT_A].ram_mode
|| cfg_ml.a2d[LUT_B].ram_mode
|| cfg_ml.a2d[LUT_C].ram_mode
|| cfg_ml.a2d[LUT_D].ram_mode) {
int clock_word[4];
// check whether all 4 clock bits in minors 16-19 are on
for (i = XC6_ROW_RAM_MI16; i <= XC6_ROW_RAM_MI19; i++) {
clock_word[i-XC6_ROW_RAM_MI16] =
frame_get_pinword(u8_p + i*FRAME_SIZE + XC6_HCLK_POS);
if (!(clock_word[i-XC6_ROW_RAM_MI16] & (1<<XC6_ROW_RAM_ENABLE_CLOCK_PIN)))
break;
}
// if they are all on, clear them
if (i > XC6_ROW_RAM_MI19) {
for (i = XC6_ROW_RAM_MI16; i <= XC6_ROW_RAM_MI19; i++) {
frame_set_pinword(u8_p + i*FRAME_SIZE + XC6_HCLK_POS,
clock_word[i-XC6_ROW_RAM_MI16] & ~(1<<XC6_ROW_RAM_ENABLE_CLOCK_PIN));
}
}
}
//
// Step 9:

View File

@ -473,6 +473,8 @@ struct fpgadev_logic_a2d
// 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.
// - In x2 mode (RAM32/SRL16), both A6 and WA6 must be driven
// high to keep O5 and O6 independent.
int ram_mode; // if set, the lut is in RAM mode
// DPRAM64, DPRAM32, SPRAM64, SPRAM32, SRL32, SRL16
int di_mux; // only for A-C

View File

@ -1582,25 +1582,25 @@ uint64_t xc6_lut_value(int lut_pos, int lutw_tl, int lutw_tr, int lutw_bl, int l
// assemble bits
v = 0;
for (i = 0; i < 16; i++) {
for (i = 0; i < 16; i+=2) {
// top side
if (lutw_tr & 1<<full_word_positions[i])
if (lutw_tr & (1<<full_word_positions[i]))
v |= 1ULL << (i*2);
if (lutw_tr & 1<<full_word_positions[i+1])
if (lutw_tr & (1<<full_word_positions[i+1]))
v |= 1ULL << (i*2+1);
if (lutw_tl & 1<<full_word_positions[i])
if (lutw_tl & (1<<full_word_positions[i]))
v |= 1ULL << (i*2+2);
if (lutw_tl & 1<<full_word_positions[i+1])
if (lutw_tl & (1<<full_word_positions[i+1]))
v |= 1ULL << (i*2+3);
// bottom side
if (lutw_br & 1<<full_word_positions[i])
if (lutw_br & (1<<full_word_positions[i]))
v |= 1ULL << (32+i*2);
if (lutw_br & 1<<full_word_positions[i+1])
if (lutw_br & (1<<full_word_positions[i+1]))
v |= 1ULL << (32+i*2+1);
if (lutw_bl & 1<<full_word_positions[i])
if (lutw_bl & (1<<full_word_positions[i]))
v |= 1ULL << (32+i*2+2);
if (lutw_bl & 1<<full_word_positions[i+1])
if (lutw_bl & (1<<full_word_positions[i+1]))
v |= 1ULL << (32+i*2+3);
}
return v;

View File

@ -316,6 +316,34 @@ uint64_t xc6_lut_value(int lut_pos, int lutw_tl, int lutw_tr, int lutw_bl, int l
#define XC6_X_A5_FFSRINIT_1 38
#define XC6_ML_A5_FFSRINIT_1 39
// minor 23 (M only)
// When any ram or shift-reg lut is configured in a row, the entire
// row is enabled by setting clock-pin-0 in minors 16, 17, 18 and 19.
// This is not for ROM luts, who are treated just like regular luts.
#define XC6_ROW_RAM_ENABLE_CLOCK_PIN 0
#define XC6_ROW_RAM_MI16 16
#define XC6_ROW_RAM_MI19 19
#define XC6_M_C_RAM 3
#define XC6_M_C_SHIFT_REG 4
#define XC6_M_D_X2 9
#define XC6_M_CDI1MUX_CX 14
#define XC6_M_C_X2 15
#define XC6_M_D_SHIFT_REG 25
#define XC6_M_D_RAM 26
#define XC6_M_WEMUX_CE 32
#define XC6_M_B_RAM 36
#define XC6_M_B_SHIFT_REG 37
#define XC6_M_WA8_USED 45
#define XC6_M_WA7_USED 46
#define XC6_M_BDI1MUX_BX 48
#define XC6_M_ADI1MUX_AX 53
#define XC6_M_A_X2 54
#define XC6_M_A_SHIFT_REG 58
#define XC6_M_A_RAM 59
#define XC6_M_B_X2 63
// minor 26 in XM, 25 in XL columns:
// ML_D_CY0=DX -