cleanup and improvement of logic configuration
This commit is contained in:
parent
468b8e3f5b
commit
6a0f623028
|
@ -553,155 +553,54 @@ fail:
|
|||
return rc;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// M device
|
||||
dev_idx = fpga_dev_idx(es->model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
|
||||
if (dev_idx == NO_DEV) FAIL(EINVAL);
|
||||
static int lut2str(uint64_t lut, int lut_pos, 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;
|
||||
|
||||
// A6_LUT
|
||||
if (frame_get_u32(u8_p + 24*FRAME_SIZE + byte_off + 4)
|
||||
|| frame_get_u32(u8_p + 25*FRAME_SIZE + byte_off + 4)) {
|
||||
u64 = read_lut64(u8_p + 24*FRAME_SIZE, (byte_off+4)*8);
|
||||
{ int logic_base[6] = {0,1,0,0,1,0};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 1); }
|
||||
if (*lut_str) {
|
||||
rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_M_OR_L,
|
||||
LUT_A, 6, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
*(uint32_t*)(u8_p+24*FRAME_SIZE+byte_off+4) = 0;
|
||||
*(uint32_t*)(u8_p+25*FRAME_SIZE+byte_off+4) = 0;
|
||||
}
|
||||
}
|
||||
// B6_LUT
|
||||
if (frame_get_u32(u8_p + 21*FRAME_SIZE + byte_off + 4)
|
||||
|| frame_get_u32(u8_p + 22*FRAME_SIZE + byte_off + 4)) {
|
||||
u64 = read_lut64(u8_p + 21*FRAME_SIZE, (byte_off+4)*8);
|
||||
{ int logic_base[6] = {1,1,0,1,0,1};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 1); }
|
||||
if (*lut_str) {
|
||||
rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_M_OR_L,
|
||||
LUT_B, 6, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
*(uint32_t*)(u8_p+21*FRAME_SIZE+byte_off+4) = 0;
|
||||
*(uint32_t*)(u8_p+22*FRAME_SIZE+byte_off+4) = 0;
|
||||
}
|
||||
}
|
||||
// C6_LUT
|
||||
if (frame_get_u32(u8_p + 24*FRAME_SIZE + byte_off)
|
||||
|| frame_get_u32(u8_p + 25*FRAME_SIZE + byte_off)) {
|
||||
u64 = read_lut64(u8_p + 24*FRAME_SIZE, byte_off*8);
|
||||
{ int logic_base[6] = {0,1,0,0,1,0};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 1); }
|
||||
if (*lut_str) {
|
||||
rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_M_OR_L,
|
||||
LUT_C, 6, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
*(uint32_t*)(u8_p+24*FRAME_SIZE+byte_off) = 0;
|
||||
*(uint32_t*)(u8_p+25*FRAME_SIZE+byte_off) = 0;
|
||||
}
|
||||
}
|
||||
// D6_LUT
|
||||
if (frame_get_u32(u8_p + 21*FRAME_SIZE + byte_off)
|
||||
|| frame_get_u32(u8_p + 22*FRAME_SIZE + byte_off)) {
|
||||
u64 = read_lut64(u8_p + 21*FRAME_SIZE, byte_off*8);
|
||||
{ int logic_base[6] = {1,1,0,1,0,1};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 1); }
|
||||
if (*lut_str) {
|
||||
rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_M_OR_L,
|
||||
LUT_D, 6, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
*(uint32_t*)(u8_p+21*FRAME_SIZE+byte_off) = 0;
|
||||
*(uint32_t*)(u8_p+22*FRAME_SIZE+byte_off) = 0;
|
||||
}
|
||||
}
|
||||
if (lut5_used) {
|
||||
xc6_lut_bitmap(lut_pos, &lut_map, 32);
|
||||
lut_mapped = map_bits(lut, 64, lut_map);
|
||||
|
||||
// X device
|
||||
u64 = frame_get_u64(u8_p + 26*FRAME_SIZE + byte_off);
|
||||
if ( u64 ) {
|
||||
// 21, 22, 36 and 37 are actually not default
|
||||
// and can go off with the FFMUXes or routing
|
||||
// say D over the FF to DQ etc. (AFFMUX=b37,
|
||||
// BFFMUX=b36, CFFMUX=b22, DFFMUX=b21).
|
||||
if (!(u64 & (1ULL<<1) && u64 & (1ULL<<2)
|
||||
&& u64 & (1ULL<<7) && u64 & (1ULL<<21)
|
||||
&& u64 & (1ULL<<22) && u64 & (1ULL<<36)
|
||||
&& u64 & (1ULL<<37) && u64 & (1ULL<<39))) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
if (u64 & ~(0x000000B000600086ULL)) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
// lut6
|
||||
str = bool_bits2str(ULL_HIGH32(lut_mapped), 32);
|
||||
if (!str) FAIL(EINVAL);
|
||||
snprintf(lut6_buf, MAX_LUT_LEN, "(A6+~A6)*(%s)", str);
|
||||
*lut6_p = lut6_buf;
|
||||
|
||||
dev_idx = fpga_dev_idx(es->model, y, x, DEV_LOGIC, DEV_LOG_X);
|
||||
if (dev_idx == NO_DEV) FAIL(EINVAL);
|
||||
*(uint64_t*)(u8_p+26*FRAME_SIZE+byte_off) = 0;
|
||||
// lut5
|
||||
str = bool_bits2str(ULL_LOW32(lut_mapped), 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);
|
||||
if (!str) FAIL(EINVAL);
|
||||
strcpy(lut6_buf, str);
|
||||
*lut6_p = lut6_buf;
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
// A6_LUT
|
||||
u64 = read_lut64(u8_p + 27*FRAME_SIZE, (byte_off+4)*8);
|
||||
if (!u64) lut_str = 0;
|
||||
else {
|
||||
int logic_base[6] = {1,1,0,1,1,0};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0);
|
||||
}
|
||||
if (lut_str && *lut_str) {
|
||||
rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_X,
|
||||
LUT_A, 6, lut_str, ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
*(uint32_t*)(u8_p+27*FRAME_SIZE+byte_off+4) = 0;
|
||||
*(uint32_t*)(u8_p+28*FRAME_SIZE+byte_off+4) = 0;
|
||||
}
|
||||
// B6_LUT
|
||||
u64 = read_lut64(u8_p + 29*FRAME_SIZE, (byte_off+4)*8);
|
||||
if (!u64) lut_str = 0;
|
||||
else {
|
||||
int logic_base[6] = {1,1,0,1,1,0};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0);
|
||||
}
|
||||
if (lut_str && *lut_str) {
|
||||
rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_X,
|
||||
LUT_B, 6, lut_str, ZTERM);
|
||||
*(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off+4) = 0;
|
||||
*(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off+4) = 0;
|
||||
}
|
||||
// C6_LUT
|
||||
u64 = read_lut64(u8_p + 27*FRAME_SIZE, byte_off*8);
|
||||
if (!u64) lut_str = 0;
|
||||
else {
|
||||
int logic_base[6] = {0,1,0,0,0,1};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0);
|
||||
}
|
||||
if (lut_str && *lut_str) {
|
||||
rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_X,
|
||||
LUT_C, 6, lut_str, ZTERM);
|
||||
*(uint32_t*)(u8_p+27*FRAME_SIZE+byte_off) = 0;
|
||||
*(uint32_t*)(u8_p+28*FRAME_SIZE+byte_off) = 0;
|
||||
}
|
||||
// D6_LUT
|
||||
u64 = read_lut64(u8_p + 29*FRAME_SIZE, byte_off*8);
|
||||
if (!u64) lut_str = 0;
|
||||
else {
|
||||
int logic_base[6] = {0,1,0,0,0,1};
|
||||
lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0);
|
||||
}
|
||||
if (lut_str && *lut_str) {
|
||||
rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_X,
|
||||
LUT_D, 6, lut_str, ZTERM);
|
||||
*(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off) = 0;
|
||||
*(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off) = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int extract_logic(struct extract_state* es)
|
||||
{
|
||||
int row, row_pos, x, y, i, byte_off, last_minor, lut5_used, rc;
|
||||
int ml_latch, x_latch;
|
||||
int latch_ml, latch_x, l_col, lut;
|
||||
struct fpgadev_logic cfg_ml, cfg_x;
|
||||
uint64_t lut_X[4], lut_ML[4]; // LUT_A-LUT_D
|
||||
uint64_t mi20, mi23_M, mi2526;
|
||||
uint8_t* u8_p;
|
||||
char lut6_ml[NUM_LUTS][MAX_LUT_LEN];
|
||||
char lut5_ml[NUM_LUTS][MAX_LUT_LEN];
|
||||
char lut6_x[NUM_LUTS][MAX_LUT_LEN];
|
||||
char lut5_x[NUM_LUTS][MAX_LUT_LEN];
|
||||
|
||||
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))
|
||||
|
@ -720,6 +619,13 @@ static int extract_logic(struct extract_state* es)
|
|||
byte_off = row_pos * 8;
|
||||
if (row_pos >= 8) byte_off += HCLK_BYTES;
|
||||
|
||||
//
|
||||
// Step 1:
|
||||
//
|
||||
// read all configuration bits for the 2 logic devices
|
||||
// into local variables
|
||||
//
|
||||
|
||||
mi20 = frame_get_u64(u8_p + 20*FRAME_SIZE + byte_off) & XC6_MI20_LOGIC_MASK;
|
||||
if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_M)) {
|
||||
mi23_M = frame_get_u64(u8_p + 23*FRAME_SIZE + byte_off);
|
||||
|
@ -732,6 +638,7 @@ static int extract_logic(struct extract_state* es)
|
|||
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);
|
||||
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);
|
||||
|
@ -743,19 +650,36 @@ static int extract_logic(struct extract_state* es)
|
|||
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);
|
||||
l_col = 1;
|
||||
} else {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Step 2:
|
||||
//
|
||||
// If all is zero, assume the devices are not instantiated.
|
||||
// todo: we could check pin connectivity and infer 0-bit
|
||||
// configured devices
|
||||
//
|
||||
|
||||
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])
|
||||
continue;
|
||||
|
||||
//
|
||||
// Step 3:
|
||||
//
|
||||
// Parse all bits from minors 20 and 25/26 into more
|
||||
// easily usable cfg_ml and cfg_x structures.
|
||||
//
|
||||
|
||||
memset(&cfg_ml, 0, sizeof(cfg_ml));
|
||||
memset(&cfg_x, 0, sizeof(cfg_x));
|
||||
ml_latch = 0;
|
||||
x_latch = 0;
|
||||
latch_ml = 0;
|
||||
latch_x = 0;
|
||||
|
||||
// minor20
|
||||
if (mi20 & (1ULL<<XC6_ML_D5_FFSRINIT_1)) {
|
||||
|
@ -787,7 +711,7 @@ static int extract_logic(struct extract_state* es)
|
|||
mi20 &= ~(1ULL<<XC6_X_B5_FFSRINIT_1);
|
||||
}
|
||||
if (mi20 & (1ULL<<XC6_M_A_FFSRINIT_1)) {
|
||||
if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_L)) {
|
||||
if (l_col) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
|
@ -880,7 +804,7 @@ static int extract_logic(struct extract_state* es)
|
|||
mi2526 &= ~(1ULL<<XC6_X_CLK_B);
|
||||
}
|
||||
if (mi2526 & (1ULL<<XC6_ML_ALL_LATCH)) {
|
||||
ml_latch = 1;
|
||||
latch_ml = 1;
|
||||
mi2526 &= ~(1ULL<<XC6_ML_ALL_LATCH);
|
||||
}
|
||||
if (mi2526 & (1ULL<<XC6_ML_SR_USED)) {
|
||||
|
@ -895,13 +819,13 @@ static int extract_logic(struct extract_state* es)
|
|||
cfg_ml.ce_used = 1;
|
||||
mi2526 &= ~(1ULL<<XC6_ML_CE_USED);
|
||||
}
|
||||
if (mi2526 & (1ULL<<XC6_X_D_FFMUX_DX)) {
|
||||
if (mi2526 & (1ULL<<XC6_X_D_FFMUX_X)) {
|
||||
cfg_x.a2d[LUT_D].ff_mux = MUX_X;
|
||||
mi2526 &= ~(1ULL<<XC6_X_D_FFMUX_DX);
|
||||
mi2526 &= ~(1ULL<<XC6_X_D_FFMUX_X);
|
||||
}
|
||||
if (mi2526 & (1ULL<<XC6_X_C_FFMUX_CX)) {
|
||||
if (mi2526 & (1ULL<<XC6_X_C_FFMUX_X)) {
|
||||
cfg_x.a2d[LUT_C].ff_mux = MUX_X;
|
||||
mi2526 &= ~(1ULL<<XC6_X_C_FFMUX_CX);
|
||||
mi2526 &= ~(1ULL<<XC6_X_C_FFMUX_X);
|
||||
}
|
||||
if (mi2526 & (1ULL<<XC6_X_CE_USED)) {
|
||||
cfg_x.ce_used = 1;
|
||||
|
@ -976,13 +900,13 @@ static int extract_logic(struct extract_state* es)
|
|||
}
|
||||
mi2526 &= ~XC6_ML_B_OUTMUX_MASK;
|
||||
}
|
||||
if (mi2526 & (1ULL<<XC6_X_B_FFMUX_CX)) {
|
||||
if (mi2526 & (1ULL<<XC6_X_B_FFMUX_X)) {
|
||||
cfg_x.a2d[LUT_B].ff_mux = MUX_X;
|
||||
mi2526 &= ~(1ULL<<XC6_X_B_FFMUX_CX);
|
||||
mi2526 &= ~(1ULL<<XC6_X_B_FFMUX_X);
|
||||
}
|
||||
if (mi2526 & (1ULL<<XC6_X_A_FFMUX_CX)) {
|
||||
if (mi2526 & (1ULL<<XC6_X_A_FFMUX_X)) {
|
||||
cfg_x.a2d[LUT_A].ff_mux = MUX_X;
|
||||
mi2526 &= ~(1ULL<<XC6_X_A_FFMUX_CX);
|
||||
mi2526 &= ~(1ULL<<XC6_X_A_FFMUX_X);
|
||||
}
|
||||
if (mi2526 & (1ULL<<XC6_X_B_FFSRINIT_1)) {
|
||||
cfg_x.a2d[LUT_B].ff_srinit = FF_SRINIT1;
|
||||
|
@ -1001,7 +925,7 @@ static int extract_logic(struct extract_state* es)
|
|||
mi2526 &= ~(1ULL<<XC6_X_SYNC);
|
||||
}
|
||||
if (mi2526 & (1ULL<<XC6_X_ALL_LATCH)) {
|
||||
x_latch = 1;
|
||||
latch_x = 1;
|
||||
mi2526 &= ~(1ULL<<XC6_X_ALL_LATCH);
|
||||
}
|
||||
if (mi2526 & (1ULL<<XC6_ML_CLK_B)) {
|
||||
|
@ -1099,7 +1023,7 @@ static int extract_logic(struct extract_state* es)
|
|||
mi2526 &= ~(1ULL<<XC6_ML_A_CY0_O5);
|
||||
}
|
||||
if (mi2526 & (1ULL<<XC6_L_A_FFSRINIT_1)) {
|
||||
if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_M)) {
|
||||
if (!l_col) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
|
@ -1107,34 +1031,45 @@ static int extract_logic(struct extract_state* es)
|
|||
mi2526 &= ~(1ULL<<XC6_L_A_FFSRINIT_1);
|
||||
}
|
||||
|
||||
// abort if bits remain
|
||||
//
|
||||
// Step 4:
|
||||
//
|
||||
// If any bits remain in the configuration, do not
|
||||
// instantiate the logic devices.
|
||||
//
|
||||
|
||||
if (mi20 || mi23_M || mi2526) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
|
||||
// if srinit=1, the matching ff/latch must be on
|
||||
// handle all_latch
|
||||
// todo: cfg_ml.cout_used must be determined from switches
|
||||
// fdev_is_pin_connected()
|
||||
//
|
||||
// todo: srinit=0, ffmux=06
|
||||
// todo: in ML, if srinit=0 cannot decide between ff_mux=O6 or direct-out, need to check connectivity!
|
||||
//
|
||||
// Step 5:
|
||||
//
|
||||
// Do device-global sanity checking pre-LUT
|
||||
//
|
||||
|
||||
// todo: cfg_ml.cout_used must be determined from switches
|
||||
// todo: if srinit=1, the matching ff/latch must be on
|
||||
// todo: handle all_latch
|
||||
// todo: precyinit=0 has no bits
|
||||
// todo: cy0=X has no bits, check connectivity
|
||||
// todo: the x-device ffmux must not be left as MUX_X unless the ff is really in use
|
||||
|
||||
//
|
||||
// Step 6:
|
||||
//
|
||||
// Determine lut5_usage and read the luts.
|
||||
//
|
||||
|
||||
// todo: in ML, if srinit=0 cannot decide between ff_mux=O6 or
|
||||
// direct-out, need to check pin connectivity, is_pin_connected()
|
||||
// todo: in ML devs, ffmux=O6 has no bits set
|
||||
// todo: 5Q-ff in X devices
|
||||
|
||||
// cout_used, a_used-d_used, srinit=0, non-inverted clock,
|
||||
// async attribute, precyinit=0, ffmux=O6, cy0=X, enabling
|
||||
// 5Q-ff in X devices
|
||||
// ML-A
|
||||
if (lut_ML[LUT_A]
|
||||
|| !all_zero(&cfg_ml.a2d[LUT_A], sizeof(cfg_ml.a2d[LUT_A]))) {
|
||||
lut5_used = (cfg_ml.a2d[LUT_A].ff_mux == MUX_O5
|
||||
|| 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);
|
||||
// We have to determine out_used from the
|
||||
// environment.
|
||||
// todo: check outpin connectivity
|
||||
// todo: ffmux=O6 has no bits set
|
||||
if (lut_ML[LUT_A]
|
||||
&& cfg_ml.a2d[LUT_A].out_mux != MUX_O6
|
||||
&& cfg_ml.a2d[LUT_A].out_mux != MUX_XOR
|
||||
|
@ -1146,35 +1081,210 @@ static int extract_logic(struct extract_state* es)
|
|||
&& cfg_ml.a2d[LUT_A].ff_mux != MUX_F7)
|
||||
cfg_ml.a2d[LUT_A].out_used = 1;
|
||||
|
||||
// minimum: a_used, a_lut
|
||||
// decide: lut5/6 pair or just lut6?
|
||||
if (lut5_used) {
|
||||
} else {
|
||||
}
|
||||
lut5_used = (cfg_ml.a2d[LUT_A].ff_mux == MUX_O5
|
||||
|| 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,
|
||||
lut5_used,
|
||||
lut6_ml[LUT_A], &cfg_ml.a2d[LUT_A].lut6,
|
||||
lut5_ml[LUT_A], &cfg_ml.a2d[LUT_A].lut5);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
// ML-B
|
||||
if (lut_ML[LUT_B]
|
||||
|| !all_zero(&cfg_ml.a2d[LUT_B], sizeof(cfg_ml.a2d[LUT_B]))) {
|
||||
if (lut_ML[LUT_B]
|
||||
&& cfg_ml.a2d[LUT_B].out_mux != MUX_O6
|
||||
&& cfg_ml.a2d[LUT_B].out_mux != MUX_XOR
|
||||
&& cfg_ml.a2d[LUT_B].out_mux != MUX_CY
|
||||
&& cfg_ml.a2d[LUT_B].out_mux != MUX_F7
|
||||
&& cfg_ml.a2d[LUT_B].ff_mux != MUX_O6
|
||||
&& cfg_ml.a2d[LUT_B].ff_mux != MUX_XOR
|
||||
&& cfg_ml.a2d[LUT_B].ff_mux != MUX_CY
|
||||
&& cfg_ml.a2d[LUT_B].ff_mux != MUX_F7)
|
||||
cfg_ml.a2d[LUT_B].out_used = 1;
|
||||
|
||||
lut5_used = (cfg_ml.a2d[LUT_B].ff_mux == MUX_O5
|
||||
|| 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,
|
||||
lut5_used,
|
||||
lut6_ml[LUT_B], &cfg_ml.a2d[LUT_B].lut6,
|
||||
lut5_ml[LUT_B], &cfg_ml.a2d[LUT_B].lut5);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
// ML-C
|
||||
if (lut_ML[LUT_C]
|
||||
|| !all_zero(&cfg_ml.a2d[LUT_C], sizeof(cfg_ml.a2d[LUT_C]))) {
|
||||
if (lut_ML[LUT_C]
|
||||
&& cfg_ml.a2d[LUT_C].out_mux != MUX_O6
|
||||
&& cfg_ml.a2d[LUT_C].out_mux != MUX_XOR
|
||||
&& cfg_ml.a2d[LUT_C].out_mux != MUX_CY
|
||||
&& cfg_ml.a2d[LUT_C].out_mux != MUX_F7
|
||||
&& cfg_ml.a2d[LUT_C].ff_mux != MUX_O6
|
||||
&& cfg_ml.a2d[LUT_C].ff_mux != MUX_XOR
|
||||
&& cfg_ml.a2d[LUT_C].ff_mux != MUX_CY
|
||||
&& cfg_ml.a2d[LUT_C].ff_mux != MUX_F7)
|
||||
cfg_ml.a2d[LUT_C].out_used = 1;
|
||||
|
||||
lut5_used = (cfg_ml.a2d[LUT_C].ff_mux == MUX_O5
|
||||
|| 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,
|
||||
lut5_used,
|
||||
lut6_ml[LUT_C], &cfg_ml.a2d[LUT_C].lut6,
|
||||
lut5_ml[LUT_C], &cfg_ml.a2d[LUT_C].lut5);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
// ML-D
|
||||
if (lut_ML[LUT_D]
|
||||
|| !all_zero(&cfg_ml.a2d[LUT_D], sizeof(cfg_ml.a2d[LUT_D]))) {
|
||||
if (lut_ML[LUT_D]
|
||||
&& cfg_ml.a2d[LUT_D].out_mux != MUX_O6
|
||||
&& cfg_ml.a2d[LUT_D].out_mux != MUX_XOR
|
||||
&& cfg_ml.a2d[LUT_D].out_mux != MUX_CY
|
||||
&& cfg_ml.a2d[LUT_D].out_mux != MUX_F7
|
||||
&& cfg_ml.a2d[LUT_D].ff_mux != MUX_O6
|
||||
&& cfg_ml.a2d[LUT_D].ff_mux != MUX_XOR
|
||||
&& cfg_ml.a2d[LUT_D].ff_mux != MUX_CY
|
||||
&& cfg_ml.a2d[LUT_D].ff_mux != MUX_F7)
|
||||
cfg_ml.a2d[LUT_D].out_used = 1;
|
||||
|
||||
lut5_used = (cfg_ml.a2d[LUT_D].ff_mux == MUX_O5
|
||||
|| 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,
|
||||
lut5_used,
|
||||
lut6_ml[LUT_D], &cfg_ml.a2d[LUT_D].lut6,
|
||||
lut5_ml[LUT_D], &cfg_ml.a2d[LUT_D].lut5);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
// X-A
|
||||
if (lut_X[LUT_A]
|
||||
|| !all_zero(&cfg_x.a2d[LUT_A], sizeof(cfg_x.a2d[LUT_A]))) {
|
||||
if (lut_X[LUT_A]
|
||||
&& cfg_x.a2d[LUT_A].ff_mux != MUX_O6)
|
||||
cfg_x.a2d[LUT_A].out_used = 1;
|
||||
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,
|
||||
lut5_used,
|
||||
lut6_x[LUT_A], &cfg_x.a2d[LUT_A].lut6,
|
||||
lut5_x[LUT_A], &cfg_x.a2d[LUT_A].lut5);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
}
|
||||
// X-B
|
||||
if (lut_X[LUT_B]
|
||||
|| !all_zero(&cfg_x.a2d[LUT_B], sizeof(cfg_x.a2d[LUT_B]))) {
|
||||
if (lut_X[LUT_B]
|
||||
&& cfg_x.a2d[LUT_B].ff_mux != MUX_O6)
|
||||
cfg_x.a2d[LUT_B].out_used = 1;
|
||||
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,
|
||||
lut5_used,
|
||||
lut6_x[LUT_B], &cfg_x.a2d[LUT_B].lut6,
|
||||
lut5_x[LUT_B], &cfg_x.a2d[LUT_B].lut5);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
}
|
||||
// X-C
|
||||
if (lut_X[LUT_C]
|
||||
|| !all_zero(&cfg_x.a2d[LUT_C], sizeof(cfg_x.a2d[LUT_C]))) {
|
||||
if (lut_X[LUT_C]
|
||||
&& cfg_x.a2d[LUT_C].ff_mux != MUX_O6)
|
||||
cfg_x.a2d[LUT_C].out_used = 1;
|
||||
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,
|
||||
lut5_used,
|
||||
lut6_x[LUT_C], &cfg_x.a2d[LUT_C].lut6,
|
||||
lut5_x[LUT_C], &cfg_x.a2d[LUT_C].lut5);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
}
|
||||
// X-D
|
||||
if (lut_X[LUT_D]
|
||||
|| !all_zero(&cfg_x.a2d[LUT_D], sizeof(cfg_x.a2d[LUT_D]))) {
|
||||
if (lut_X[LUT_D]
|
||||
&& cfg_x.a2d[LUT_D].ff_mux != MUX_O6)
|
||||
cfg_x.a2d[LUT_D].out_used = 1;
|
||||
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,
|
||||
lut5_used,
|
||||
lut6_x[LUT_D], &cfg_x.a2d[LUT_D].lut6,
|
||||
lut5_x[LUT_D], &cfg_x.a2d[LUT_D].lut5);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
}
|
||||
|
||||
// If any ff_mux 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
|
||||
//
|
||||
// Step 7:
|
||||
//
|
||||
// Do more and final sanity checks before instantiation.
|
||||
//
|
||||
|
||||
// remove all bits
|
||||
// todo: latch cannot be combined with out_mux=5Q or ff5_srinit
|
||||
if (latch_ml
|
||||
&& !cfg_ml.a2d[LUT_A].ff_mux
|
||||
&& !cfg_ml.a2d[LUT_B].ff_mux
|
||||
&& !cfg_ml.a2d[LUT_C].ff_mux
|
||||
&& !cfg_ml.a2d[LUT_D].ff_mux) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
if (latch_x
|
||||
&& !cfg_x.a2d[LUT_A].ff_mux
|
||||
&& !cfg_x.a2d[LUT_B].ff_mux
|
||||
&& !cfg_x.a2d[LUT_C].ff_mux
|
||||
&& !cfg_x.a2d[LUT_D].ff_mux) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
// 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)
|
||||
cfg_ml.a2d[lut].ff = latch_ml ? FF_LATCH : FF_FF;
|
||||
if (cfg_x.a2d[lut].ff_mux)
|
||||
cfg_x.a2d[lut].ff = latch_x ? FF_LATCH : FF_FF;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
//
|
||||
// Step 8:
|
||||
//
|
||||
// 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 = has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_M) ? 30 : 29;
|
||||
last_minor = l_col ? 29 : 30;
|
||||
for (i = 21; i <= last_minor; i++)
|
||||
frame_set_u64(u8_p + i*FRAME_SIZE + byte_off, 0);
|
||||
|
||||
// instantiate configuration
|
||||
//
|
||||
// Step 9:
|
||||
//
|
||||
// Instantiate configuration.
|
||||
//
|
||||
|
||||
if (!all_zero(&cfg_ml, sizeof(cfg_ml))) {
|
||||
rc = fdev_logic_setconf(es->model, y, x, DEV_LOG_M_OR_L, &cfg_ml);
|
||||
if (rc) FAIL(rc);
|
||||
|
|
185
libs/helper.c
185
libs/helper.c
|
@ -178,15 +178,15 @@ fail:
|
|||
return -1;
|
||||
}
|
||||
|
||||
uint64_t map_bits(uint64_t u64, int num_bits, int* dest_pos)
|
||||
uint64_t map_bits(uint64_t u64, int num_bits, int* src_pos)
|
||||
{
|
||||
uint64_t result;
|
||||
int i;
|
||||
|
||||
result = 0;
|
||||
for (i = 0; i < num_bits; i++) {
|
||||
if (u64 & (1ULL<<i))
|
||||
result |= 1ULL<<(dest_pos[i]);
|
||||
if (u64 & (1ULL<<(src_pos[i])))
|
||||
result |= 1ULL<<i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -350,142 +350,6 @@ int parse_boolexpr(const char* expr, uint64_t* lut)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// bits is tested only for 32 and 64
|
||||
const char* lut2bool(const uint64_t lut, int bits,
|
||||
int (*logic_base)[6], int flip_b0)
|
||||
{
|
||||
// round 0 needs 64 entries
|
||||
// round 1 (size2): 192
|
||||
// round 2 (size4): 240
|
||||
// round 3 (size8): 160
|
||||
// round 4 (size16): 60
|
||||
// round 5 (size32): 12
|
||||
// round 6 (size64): 1
|
||||
minterm_entry mt[7][256];
|
||||
int mt_size[7];
|
||||
int i, j, k, round, only_diff_bit;
|
||||
int str_end, first_op;
|
||||
static char str[2048];
|
||||
|
||||
if (!lut) return "0";
|
||||
if (lut == 0xFFFFFFFFFFFFFFFFULL) return "1";
|
||||
|
||||
memset(mt, 0, sizeof(mt));
|
||||
memset(mt_size, 0, sizeof(mt_size));
|
||||
|
||||
for (i = 0; i < bits; i++) {
|
||||
if (lut & (1LL<<i)) {
|
||||
mt[0][mt_size[0]].a[0] = (*logic_base)[0];
|
||||
mt[0][mt_size[0]].a[1] = (*logic_base)[1];
|
||||
mt[0][mt_size[0]].a[2] = (*logic_base)[2];
|
||||
mt[0][mt_size[0]].a[3] = (*logic_base)[3];
|
||||
mt[0][mt_size[0]].a[4] = (*logic_base)[4];
|
||||
mt[0][mt_size[0]].a[5] = (*logic_base)[5];
|
||||
for (j = 0; j < 6; j++) {
|
||||
if (j != 2 && (i&(1<<j)))
|
||||
mt[0][mt_size[0]].a[j]
|
||||
= !mt[0][mt_size[0]].a[j];
|
||||
}
|
||||
if (((i&8) != 0) ^ ((i&4) != 0))
|
||||
mt[0][mt_size[0]].a[2] = 1;
|
||||
if (flip_b0
|
||||
&& (mt[0][mt_size[0]].a[2] ^ mt[0][mt_size[0]].a[3]))
|
||||
mt[0][mt_size[0]].a[0] = !mt[0][mt_size[0]].a[0];
|
||||
mt_size[0]++;
|
||||
}
|
||||
}
|
||||
|
||||
// special case: no minterms -> empty string
|
||||
if (mt_size[0] == 0) {
|
||||
str[0] = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
// go through five rounds of merging
|
||||
for (round = 1; round < 7; round++) {
|
||||
for (i = 0; i < mt_size[round-1]; i++) {
|
||||
for (j = i+1; j < mt_size[round-1]; j++) {
|
||||
only_diff_bit = -1;
|
||||
for (k = 0; k < 6; k++) {
|
||||
if (mt[round-1][i].a[k] != mt[round-1][j].a[k]) {
|
||||
if (only_diff_bit != -1) {
|
||||
only_diff_bit = -1;
|
||||
break;
|
||||
}
|
||||
only_diff_bit = k;
|
||||
}
|
||||
}
|
||||
if (only_diff_bit != -1) {
|
||||
char new_term[6];
|
||||
|
||||
for (k = 0; k < 6; k++)
|
||||
new_term[k] =
|
||||
(k == only_diff_bit) ? 2
|
||||
: mt[round-1][i].a[k];
|
||||
for (k = 0; k < mt_size[round]; k++) {
|
||||
if (new_term[0] == mt[round][k].a[0]
|
||||
&& new_term[1] == mt[round][k].a[1]
|
||||
&& new_term[2] == mt[round][k].a[2]
|
||||
&& new_term[3] == mt[round][k].a[3]
|
||||
&& new_term[4] == mt[round][k].a[4]
|
||||
&& new_term[5] == mt[round][k].a[5])
|
||||
break;
|
||||
}
|
||||
if (k >= mt_size[round]) {
|
||||
mt[round][mt_size[round]].a[0] = new_term[0];
|
||||
mt[round][mt_size[round]].a[1] = new_term[1];
|
||||
mt[round][mt_size[round]].a[2] = new_term[2];
|
||||
mt[round][mt_size[round]].a[3] = new_term[3];
|
||||
mt[round][mt_size[round]].a[4] = new_term[4];
|
||||
mt[round][mt_size[round]].a[5] = new_term[5];
|
||||
mt_size[round]++;
|
||||
}
|
||||
mt[round-1][i].merged = 1;
|
||||
mt[round-1][j].merged = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// special case: 222222 -> (A6+~A6)
|
||||
for (i = 0; i < mt_size[6]; i++) {
|
||||
if (mt[6][i].a[0] == 2
|
||||
&& mt[6][i].a[1] == 2
|
||||
&& mt[6][i].a[2] == 2
|
||||
&& mt[6][i].a[3] == 2
|
||||
&& mt[6][i].a[4] == 2
|
||||
&& mt[6][i].a[5] == 2) {
|
||||
strcpy(str, "A6+~A6");
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
str_end = 0;
|
||||
for (round = 0; round < 7; round++) {
|
||||
for (i = 0; i < mt_size[round]; i++) {
|
||||
if (!mt[round][i].merged) {
|
||||
if (str_end)
|
||||
str[str_end++] = '+';
|
||||
first_op = 1;
|
||||
for (j = 0; j < 6; j++) {
|
||||
if (mt[round][i].a[j] != 2) {
|
||||
if (!first_op)
|
||||
str[str_end++] = '*';
|
||||
if (!mt[round][i].a[j])
|
||||
str[str_end++] = '~';
|
||||
str[str_end++] = 'A';
|
||||
str[str_end++] = '1' + j;
|
||||
first_op = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
str[str_end] = 0;
|
||||
// TODO: This could be further simplified, see Petrick's method.
|
||||
// XOR don't simplify well, try A2@A3
|
||||
return str;
|
||||
}
|
||||
|
||||
int printf_iob(uint8_t* d, int len, int inpos, int num_entries)
|
||||
{
|
||||
int i, num_printed;
|
||||
|
@ -829,24 +693,6 @@ void printf_extrabits(const uint8_t* maj_bits, int start_minor, int num_minors,
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t read_lut64(const uint8_t* two_minors, int bit_off_in_frame)
|
||||
{
|
||||
uint64_t lut64 = 0;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
if (frame_get_bit(two_minors, bit_off_in_frame+j*2))
|
||||
lut64 |= 1LL << (j*4);
|
||||
if (frame_get_bit(two_minors, bit_off_in_frame+(j*2)+1))
|
||||
lut64 |= 1LL << (j*4+1);
|
||||
if (frame_get_bit(&two_minors[130], bit_off_in_frame+j*2))
|
||||
lut64 |= 1LL << (j*4+2);
|
||||
if (frame_get_bit(&two_minors[130], bit_off_in_frame+(j*2)+1))
|
||||
lut64 |= 1LL << (j*4+3);
|
||||
}
|
||||
return lut64;
|
||||
}
|
||||
|
||||
void write_lut64(uint8_t* two_minors, int off_in_frame, uint64_t u64)
|
||||
{
|
||||
int i;
|
||||
|
@ -986,31 +832,6 @@ int all_zero(const void* d, int num_bytes)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int get_nibble(uint64_t u64, int nibble_bit0_off)
|
||||
{
|
||||
int n, i;
|
||||
|
||||
n = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (u64 & (1ULL << (nibble_bit0_off+i)))
|
||||
n |= 1<<i;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
uint64_t set_nibble(uint64_t u64, int nibble_bit0_off, int nibble_val)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (nibble_val & (1<<i))
|
||||
u64 |= 1ULL << (nibble_bit0_off+i);
|
||||
else
|
||||
u64 &= ~(1ULL << (nibble_bit0_off+i));
|
||||
}
|
||||
return u64;
|
||||
}
|
||||
|
||||
void printf_wrap(FILE* f, char* line, int prefix_len,
|
||||
const char* fmt, ...)
|
||||
{
|
||||
|
|
|
@ -57,14 +57,11 @@ typedef struct _cfg_atom
|
|||
int atom_found(char* bits, const cfg_atom_t* atom);
|
||||
void atom_remove(char* bits, const cfg_atom_t* atom);
|
||||
|
||||
uint64_t map_bits(uint64_t u64, int num_bits, int* dest_pos);
|
||||
uint64_t map_bits(uint64_t u64, int num_bits, int* src_pos);
|
||||
int bool_str2bits(const char* str, uint64_t* u64, int num_bits);
|
||||
const char* bool_bits2str(uint64_t u64, int num_bits);
|
||||
|
||||
int parse_boolexpr(const char* expr, uint64_t* lut);
|
||||
// bits is tested only for 32 and 64
|
||||
const char* lut2bool(const uint64_t lut, int bits,
|
||||
int (*logic_base)[6], int flip_b0);
|
||||
|
||||
int printf_iob(uint8_t* d, int len, int inpos, int num_entries);
|
||||
void printf_ramb16_data(uint8_t* bits, int inpos);
|
||||
|
@ -100,7 +97,6 @@ void printf_clock(const uint8_t* frame, int row, int major, int minor);
|
|||
int clb_empty(uint8_t* maj_bits, int idx);
|
||||
void printf_extrabits(const uint8_t* maj_bits, int start_minor, int num_minors,
|
||||
int start_bit, int num_bits, int row, int major);
|
||||
uint64_t read_lut64(const uint8_t* two_minors, int bit_off_in_frame);
|
||||
void write_lut64(uint8_t* two_minors, int off_in_frame, uint64_t u64);
|
||||
|
||||
int get_vm_mb(void);
|
||||
|
@ -116,8 +112,6 @@ int all_digits(const char* a, int len);
|
|||
int to_i(const char* s, int len);
|
||||
int mod4_calc(int a, int b);
|
||||
int all_zero(const void* d, int num_bytes);
|
||||
int get_nibble(uint64_t u64, int nibble_bit0_off);
|
||||
uint64_t set_nibble(uint64_t u64, int nibble_bit0_off, int nibble_val);
|
||||
|
||||
void printf_wrap(FILE* f, char* line, int prefix_len,
|
||||
const char* fmt, ...);
|
||||
|
|
|
@ -414,6 +414,7 @@ enum { WEMUX_WE = 1, WEMUX_CE };
|
|||
enum { PRECYINIT_0 = 1, PRECYINIT_1, PRECYINIT_AX };
|
||||
|
||||
#define MAX_LUT_LEN 2048
|
||||
#define NUM_LUTS 4
|
||||
|
||||
struct fpgadev_logic_a2d
|
||||
{
|
||||
|
@ -430,7 +431,7 @@ struct fpgadev_logic_a2d
|
|||
|
||||
struct fpgadev_logic
|
||||
{
|
||||
struct fpgadev_logic_a2d a2d[4];
|
||||
struct fpgadev_logic_a2d a2d[NUM_LUTS];
|
||||
int clk_inv; // CLKINV_B, CLKINV_CLK
|
||||
int sync_attr; // SYNCATTR_SYNC, SYNCATTR_ASYNC
|
||||
int ce_used;
|
||||
|
|
10
libs/parts.c
10
libs/parts.c
|
@ -810,7 +810,7 @@ void free_xc6_routing_bitpos(struct xc6_routing_bitpos* bitpos)
|
|||
free(bitpos);
|
||||
}
|
||||
|
||||
void xc6_lut_bitmap(int lut_pos, int* map, int num_bits)
|
||||
void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits)
|
||||
{
|
||||
static const int xc6_lut_wiring[4][16] = {
|
||||
// xm-m a; xm-m c;
|
||||
|
@ -839,12 +839,12 @@ void xc6_lut_bitmap(int lut_pos, int* map, 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];
|
||||
(*map)[i] = map32[i]%32;
|
||||
(*map)[32+i] = 32+(*map)[i];
|
||||
} else {
|
||||
if (num_bits != 64) HERE();
|
||||
map[i] = map32[i];
|
||||
map[32+i] = (map[i]+32)%64;
|
||||
(*map)[i] = map32[i];
|
||||
(*map)[32+i] = ((*map)[i]+32)%64;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
libs/parts.h
10
libs/parts.h
|
@ -176,7 +176,7 @@ void free_xc6_routing_bitpos(struct xc6_routing_bitpos* bitpos);
|
|||
// 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, int num_bits);
|
||||
void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits);
|
||||
|
||||
//
|
||||
// logic configuration
|
||||
|
@ -248,9 +248,9 @@ void xc6_lut_bitmap(int lut_pos, int* map, int num_bits);
|
|||
#define XC6_ML_SYNC 19
|
||||
#define XC6_ML_CE_USED 20
|
||||
// X_D_FFMUX=O6 -
|
||||
#define XC6_X_D_FFMUX_DX 21 // default-set, does not imply lut5
|
||||
#define XC6_X_D_FFMUX_X 21 // default-set, does not imply lut5
|
||||
// X_C_FFMUX=O6 -
|
||||
#define XC6_X_C_FFMUX_CX 22 // default-set, does not imply lut5
|
||||
#define XC6_X_C_FFMUX_X 22 // default-set, does not imply lut5
|
||||
#define XC6_X_CE_USED 23
|
||||
|
||||
#define XC6_ML_C_OUTMUX_MASK 0x000000000F000000ULL
|
||||
|
@ -281,9 +281,9 @@ void xc6_lut_bitmap(int lut_pos, int* map, int num_bits);
|
|||
#define XC6_ML_B_OUTMUX_O5 9 // 1001, implies lut5 on ML-B
|
||||
|
||||
// X_B_FFMUX=O6 -
|
||||
#define XC6_X_B_FFMUX_CX 36 // default-set, does not imply lut5
|
||||
#define XC6_X_B_FFMUX_X 36 // default-set, does not imply lut5
|
||||
// X_A_FFMUX=O6 -
|
||||
#define XC6_X_A_FFMUX_CX 37 // default-set, does not imply lut5
|
||||
#define XC6_X_A_FFMUX_X 37 // default-set, does not imply lut5
|
||||
#define XC6_X_B_FFSRINIT_1 38
|
||||
// X_A_OUTMUX=5Q - // implies lut5 on X-A
|
||||
#define XC6_X_A_OUTMUX_O5 39 // default-set, does not imply lut5
|
||||
|
|
Loading…
Reference in New Issue
Block a user