more logic device cases
This commit is contained in:
parent
19d5719c57
commit
9d84e5da23
|
@ -59,19 +59,19 @@ int main(int argc, char** argv)
|
|||
logic_cfg.a2d[LUT_A].ff_mux = MUX_XOR;
|
||||
logic_cfg.a2d[LUT_A].ff_srinit = FF_SRINIT0;
|
||||
logic_cfg.a2d[LUT_B].lut6 = "(A6+~A6)*(A5)";
|
||||
logic_cfg.a2d[LUT_B].lut5 = "1";
|
||||
logic_cfg.a2d[LUT_B].lut5 = "0";
|
||||
logic_cfg.a2d[LUT_B].cy0 = CY0_O5;
|
||||
logic_cfg.a2d[LUT_B].ff = FF_FF;
|
||||
logic_cfg.a2d[LUT_B].ff_mux = MUX_XOR;
|
||||
logic_cfg.a2d[LUT_B].ff_srinit = FF_SRINIT0;
|
||||
logic_cfg.a2d[LUT_C].lut6 = "(A6+~A6)*(A5)";
|
||||
logic_cfg.a2d[LUT_C].lut5 = "1";
|
||||
logic_cfg.a2d[LUT_C].lut5 = "0";
|
||||
logic_cfg.a2d[LUT_C].cy0 = CY0_O5;
|
||||
logic_cfg.a2d[LUT_C].ff = FF_FF;
|
||||
logic_cfg.a2d[LUT_C].ff_mux = MUX_XOR;
|
||||
logic_cfg.a2d[LUT_C].ff_srinit = FF_SRINIT0;
|
||||
logic_cfg.a2d[LUT_D].lut6 = "(A6+~A6)*(A5)";
|
||||
logic_cfg.a2d[LUT_D].lut5 = "1";
|
||||
logic_cfg.a2d[LUT_D].lut5 = "0";
|
||||
logic_cfg.a2d[LUT_D].cy0 = CY0_O5;
|
||||
logic_cfg.a2d[LUT_D].ff = FF_FF;
|
||||
logic_cfg.a2d[LUT_D].ff_mux = MUX_XOR;
|
||||
|
@ -86,6 +86,7 @@ int main(int argc, char** argv)
|
|||
logic_y = 57;
|
||||
logic_cfg.precyinit = 0;
|
||||
logic_cfg.a2d[LUT_A].lut6 = "(A6+~A6)*(A5)";
|
||||
logic_cfg.a2d[LUT_A].lut5 = "0";
|
||||
fdev_logic_setconf(&model, logic_y, logic_x, logic_type_idx, &logic_cfg);
|
||||
|
||||
logic_y = 56;
|
||||
|
|
|
@ -2614,93 +2614,376 @@ static int write_switches(struct fpga_bits* bits, struct fpga_model* model)
|
|||
RC_RETURN(model);
|
||||
}
|
||||
|
||||
static int is_latch(struct fpga_device *dev)
|
||||
{
|
||||
int i;
|
||||
// todo: there are a lot more checks we can do to determine whether
|
||||
// the entire device is properly configured as a latch or not...
|
||||
for (i = LUT_A; i <= LUT_D; i++) {
|
||||
if (dev->u.logic.a2d[i].ff == FF_LATCH
|
||||
|| dev->u.logic.a2d[i].ff == FF_OR2L
|
||||
|| dev->u.logic.a2d[i].ff == FF_AND2L)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
lut6_used = a2d->lut6 && a2d->lut6[0];
|
||||
lut5_used = a2d->lut5 && a2d->lut5[0];
|
||||
if (!lut6_used && !lut5_used)
|
||||
return 0;
|
||||
|
||||
if (lut5_used) {
|
||||
if (!lut6_used) u64 = 0;
|
||||
else {
|
||||
rc = bool_str2bits(a2d->lut6, &u64, 32);
|
||||
if (rc) FAIL(rc);
|
||||
u64 <<= 32;
|
||||
}
|
||||
rc = bool_str2bits(a2d->lut5, &u64, 32);
|
||||
if (rc) FAIL(rc);
|
||||
xc6_lut_bitmap(lut_pos, &lut_map, 32);
|
||||
} else {
|
||||
// lut6_used only
|
||||
rc = bool_str2bits(a2d->lut6, &u64, 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;
|
||||
}
|
||||
|
||||
static int write_logic(struct fpga_bits* bits, struct fpga_model* model)
|
||||
{
|
||||
int dev_idx, row, row_pos, xm_col, rc;
|
||||
int x, y, byte_off;
|
||||
struct fpga_device* dev;
|
||||
uint64_t u64;
|
||||
int dev_idx, row, row_pos, xm_col;
|
||||
int x, y, byte_off, rc;
|
||||
uint64_t lut_X[4], lut_ML[4]; // LUT_A-LUT_D
|
||||
uint64_t mi20, mi23_M, mi2526;
|
||||
uint8_t* u8_p;
|
||||
struct fpga_device* dev_ml, *dev_x;
|
||||
|
||||
RC_CHECK(model);
|
||||
for (x = LEFT_SIDE_WIDTH; x < model->x_width-RIGHT_SIDE_WIDTH; x++) {
|
||||
xm_col = is_atx(X_FABRIC_LOGIC_XM_COL, model, x);
|
||||
if (!xm_col && !is_atx(X_FABRIC_LOGIC_XL_COL, model, x))
|
||||
continue;
|
||||
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
if (!has_device(model, y, x, DEV_LOGIC))
|
||||
continue;
|
||||
|
||||
row = which_row(y, model);
|
||||
row_pos = pos_in_row(y, model);
|
||||
if (row == -1 || row_pos == -1 || row_pos == 8) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
if (row_pos > 8) row_pos--;
|
||||
is_in_row(model, y, &row, &row_pos);
|
||||
RC_ASSERT(model, row != -1 && row_pos != -1 && row_pos != HCLK_POS);
|
||||
if (row_pos > HCLK_POS) row_pos--;
|
||||
|
||||
u8_p = get_first_minor(bits, row, model->x_major[x]);
|
||||
byte_off = row_pos * 8;
|
||||
if (row_pos >= 8) byte_off += XC6_HCLK_BYTES;
|
||||
|
||||
//
|
||||
// 1) check current bits
|
||||
//
|
||||
|
||||
mi20 = frame_get_u64(u8_p + 20*FRAME_SIZE + byte_off) & XC6_MI20_LOGIC_MASK;
|
||||
if (xm_col) {
|
||||
// X device
|
||||
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOG_X);
|
||||
if (dev_idx == NO_DEV) FAIL(EINVAL);
|
||||
dev = FPGA_DEV(model, y, x, dev_idx);
|
||||
if (dev->instantiated) {
|
||||
u64 = 0x000000B000600086ULL;
|
||||
frame_set_u64(u8_p + 26*FRAME_SIZE + byte_off, u64);
|
||||
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);
|
||||
} 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);
|
||||
}
|
||||
// Except for XC6_ML_CIN_USED (which is set by a switch elsewhere),
|
||||
// everything else should be 0.
|
||||
if (mi20 || mi23_M || (mi2526 & ~XC6_ML_CIN_USED)
|
||||
|| lut_ML[LUT_A] || lut_ML[LUT_B] || lut_ML[LUT_C] || lut_ML[LUT_D]
|
||||
|| lut_X[LUT_A] || lut_X[LUT_B] || lut_X[LUT_C] || lut_X[LUT_D]) {
|
||||
HERE();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dev->u.logic.a2d[LUT_A].lut6
|
||||
&& dev->u.logic.a2d[LUT_A].lut6[0]) {
|
||||
HERE(); // not supported
|
||||
}
|
||||
if (dev->u.logic.a2d[LUT_B].lut6
|
||||
&& dev->u.logic.a2d[LUT_B].lut6[0]) {
|
||||
HERE(); // not supported
|
||||
}
|
||||
if (dev->u.logic.a2d[LUT_C].lut6
|
||||
&& dev->u.logic.a2d[LUT_C].lut6[0]) {
|
||||
HERE(); // not supported
|
||||
}
|
||||
if (dev->u.logic.a2d[LUT_D].lut6
|
||||
&& dev->u.logic.a2d[LUT_D].lut6[0]) {
|
||||
rc = parse_boolexpr(dev->u.logic.a2d[LUT_D].lut6, &u64);
|
||||
if (rc) FAIL(rc);
|
||||
write_lut64(u8_p + 29*FRAME_SIZE, byte_off*8, u64);
|
||||
}
|
||||
}
|
||||
//
|
||||
// 2) go through config to assemble bits
|
||||
//
|
||||
|
||||
// M device
|
||||
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
|
||||
if (dev_idx == NO_DEV) FAIL(EINVAL);
|
||||
dev = FPGA_DEV(model, y, x, dev_idx);
|
||||
if (dev->instantiated) {
|
||||
HERE();
|
||||
}
|
||||
} else {
|
||||
// X device
|
||||
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOG_X);
|
||||
if (dev_idx == NO_DEV) FAIL(EINVAL);
|
||||
dev = FPGA_DEV(model, y, x, dev_idx);
|
||||
if (dev->instantiated) {
|
||||
HERE();
|
||||
}
|
||||
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOG_X);
|
||||
dev_x = FPGA_DEV(model, y, x, dev_idx);
|
||||
RC_ASSERT(model, dev_x);
|
||||
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
|
||||
dev_ml = FPGA_DEV(model, y, x, dev_idx);
|
||||
RC_ASSERT(model, dev_ml);
|
||||
|
||||
// L device
|
||||
dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
|
||||
if (dev_idx == NO_DEV) FAIL(EINVAL);
|
||||
dev = FPGA_DEV(model, y, x, dev_idx);
|
||||
if (dev->instantiated) {
|
||||
HERE();
|
||||
//
|
||||
// 2.1) mi20
|
||||
//
|
||||
|
||||
// X device
|
||||
if (dev_x->instantiated) {
|
||||
if (dev_x->u.logic.a2d[LUT_A].ff5_srinit == FF_SRINIT1)
|
||||
mi20 |= 1ULL << XC6_X_A5_FFSRINIT_1;
|
||||
if (dev_x->u.logic.a2d[LUT_B].ff5_srinit == FF_SRINIT1)
|
||||
mi20 |= 1ULL << XC6_X_B5_FFSRINIT_1;
|
||||
if (dev_x->u.logic.a2d[LUT_C].ff5_srinit == FF_SRINIT1)
|
||||
mi20 |= 1ULL << XC6_X_C5_FFSRINIT_1;
|
||||
if (dev_x->u.logic.a2d[LUT_D].ff5_srinit == FF_SRINIT1)
|
||||
mi20 |= 1ULL << XC6_X_D5_FFSRINIT_1;
|
||||
|
||||
if (dev_x->u.logic.a2d[LUT_C].ff_srinit == FF_SRINIT1)
|
||||
mi20 |= 1ULL << XC6_X_C_FFSRINIT_1;
|
||||
}
|
||||
|
||||
// M or L device
|
||||
if (dev_ml->instantiated) {
|
||||
if (dev_ml->u.logic.a2d[LUT_A].ff5_srinit == FF_SRINIT1)
|
||||
mi20 |= 1ULL << XC6_ML_A5_FFSRINIT_1;
|
||||
if (dev_ml->u.logic.a2d[LUT_B].ff5_srinit == FF_SRINIT1)
|
||||
mi20 |= 1ULL << XC6_ML_B5_FFSRINIT_1;
|
||||
if (dev_ml->u.logic.a2d[LUT_C].ff5_srinit == FF_SRINIT1)
|
||||
mi20 |= 1ULL << XC6_ML_C5_FFSRINIT_1;
|
||||
if (dev_ml->u.logic.a2d[LUT_D].ff5_srinit == FF_SRINIT1)
|
||||
mi20 |= 1ULL << XC6_ML_D5_FFSRINIT_1;
|
||||
|
||||
if (xm_col // M-device only
|
||||
&& dev_ml->u.logic.a2d[LUT_A].ff_srinit == FF_SRINIT1)
|
||||
mi20 |= 1ULL << XC6_M_A_FFSRINIT_1;
|
||||
}
|
||||
|
||||
//
|
||||
// 2.2) mi2526
|
||||
//
|
||||
|
||||
// X device
|
||||
if (dev_x->instantiated) {
|
||||
if (dev_x->u.logic.a2d[LUT_D].out_mux != MUX_5Q)
|
||||
mi2526 |= 1ULL << XC6_X_D_OUTMUX_O5; // default-set
|
||||
if (dev_x->u.logic.a2d[LUT_C].out_mux != MUX_5Q)
|
||||
mi2526 |= 1ULL << XC6_X_C_OUTMUX_O5; // default-set
|
||||
if (dev_x->u.logic.a2d[LUT_D].ff_srinit == FF_SRINIT1)
|
||||
mi2526 |= 1ULL << XC6_X_D_FFSRINIT_1;
|
||||
if (dev_x->u.logic.a2d[LUT_B].out_mux != MUX_5Q)
|
||||
mi2526 |= 1ULL << XC6_X_B_OUTMUX_O5; // default-set
|
||||
if (dev_x->u.logic.clk_inv == CLKINV_B)
|
||||
mi2526 |= 1ULL << XC6_X_CLK_B;
|
||||
if (dev_x->u.logic.a2d[LUT_D].ff_mux != MUX_O6)
|
||||
mi2526 |= 1ULL << XC6_X_D_FFMUX_X; // default-set
|
||||
if (dev_x->u.logic.a2d[LUT_C].ff_mux != MUX_O6)
|
||||
mi2526 |= 1ULL << XC6_X_C_FFMUX_X; // default-set
|
||||
if (dev_x->u.logic.ce_used)
|
||||
mi2526 |= 1ULL << XC6_X_CE_USED;
|
||||
if (dev_x->u.logic.a2d[LUT_B].ff_mux != MUX_O6)
|
||||
mi2526 |= 1ULL << XC6_X_B_FFMUX_X; // default-set
|
||||
if (dev_x->u.logic.a2d[LUT_A].ff_mux != MUX_O6)
|
||||
mi2526 |= 1ULL << XC6_X_A_FFMUX_X; // default-set
|
||||
if (dev_x->u.logic.a2d[LUT_B].ff_srinit == FF_SRINIT1)
|
||||
mi2526 |= 1ULL << XC6_X_B_FFSRINIT_1;
|
||||
if (dev_x->u.logic.a2d[LUT_A].out_mux != MUX_5Q)
|
||||
mi2526 |= 1ULL << XC6_X_A_OUTMUX_O5; // default-set
|
||||
if (dev_x->u.logic.sr_used)
|
||||
mi2526 |= 1ULL << XC6_X_SR_USED;
|
||||
if (dev_x->u.logic.sync_attr == SYNCATTR_SYNC)
|
||||
mi2526 |= 1ULL << XC6_X_SYNC;
|
||||
if (is_latch(dev_x))
|
||||
mi2526 |= 1ULL << XC6_X_ALL_LATCH;
|
||||
if (dev_x->u.logic.a2d[LUT_A].ff_srinit == FF_SRINIT1)
|
||||
mi2526 |= 1ULL << XC6_X_A_FFSRINIT_1;
|
||||
}
|
||||
|
||||
// M or L device
|
||||
if (dev_ml->instantiated) {
|
||||
if (dev_ml->u.logic.a2d[LUT_D].cy0 == CY0_O5)
|
||||
mi2526 |= 1ULL << XC6_ML_D_CY0_O5;
|
||||
if (dev_ml->u.logic.a2d[LUT_D].ff_srinit == FF_SRINIT1)
|
||||
mi2526 |= 1ULL << XC6_ML_D_FFSRINIT_1;
|
||||
if (dev_ml->u.logic.a2d[LUT_C].ff_srinit == FF_SRINIT1)
|
||||
mi2526 |= 1ULL << XC6_ML_C_FFSRINIT_1;
|
||||
if (dev_ml->u.logic.a2d[LUT_C].cy0 == CY0_O5)
|
||||
mi2526 |= 1ULL << XC6_ML_C_CY0_O5;
|
||||
switch (dev_ml->u.logic.a2d[LUT_D].out_mux) {
|
||||
case MUX_O6: mi2526 |= XC6_ML_D_OUTMUX_O6 << XC6_ML_D_OUTMUX_O; break;
|
||||
case MUX_XOR: mi2526 |= XC6_ML_D_OUTMUX_XOR << XC6_ML_D_OUTMUX_O; break;
|
||||
case MUX_O5: mi2526 |= XC6_ML_D_OUTMUX_O5 << XC6_ML_D_OUTMUX_O; break;
|
||||
case MUX_CY: mi2526 |= XC6_ML_D_OUTMUX_CY << XC6_ML_D_OUTMUX_O; break;
|
||||
case MUX_5Q: mi2526 |= XC6_ML_D_OUTMUX_5Q << XC6_ML_D_OUTMUX_O; break;
|
||||
}
|
||||
switch (dev_ml->u.logic.a2d[LUT_D].ff_mux) {
|
||||
// XC6_ML_D_FFMUX_O6 is 0
|
||||
case MUX_O5: mi2526 |= XC6_ML_D_FFMUX_O5 << XC6_ML_D_FFMUX_O; break;
|
||||
case MUX_X: mi2526 |= XC6_ML_D_FFMUX_X << XC6_ML_D_FFMUX_O; break;
|
||||
case MUX_XOR: mi2526 |= XC6_ML_D_FFMUX_XOR << XC6_ML_D_FFMUX_O; break;
|
||||
case MUX_CY: mi2526 |= XC6_ML_D_FFMUX_CY << XC6_ML_D_FFMUX_O; break;
|
||||
}
|
||||
if (is_latch(dev_ml))
|
||||
mi2526 |= 1ULL << XC6_ML_ALL_LATCH;
|
||||
if (dev_ml->u.logic.sr_used)
|
||||
mi2526 |= 1ULL << XC6_ML_SR_USED;
|
||||
if (dev_ml->u.logic.sync_attr == SYNCATTR_SYNC)
|
||||
mi2526 |= 1ULL << XC6_ML_SYNC;
|
||||
if (dev_ml->u.logic.ce_used)
|
||||
mi2526 |= 1ULL << XC6_ML_CE_USED;
|
||||
switch (dev_ml->u.logic.a2d[LUT_C].out_mux) {
|
||||
case MUX_XOR: mi2526 |= XC6_ML_C_OUTMUX_XOR << XC6_ML_C_OUTMUX_O; break;
|
||||
case MUX_O6: mi2526 |= XC6_ML_C_OUTMUX_O6 << XC6_ML_C_OUTMUX_O; break;
|
||||
case MUX_5Q: mi2526 |= XC6_ML_C_OUTMUX_5Q << XC6_ML_C_OUTMUX_O; break;
|
||||
case MUX_CY: mi2526 |= XC6_ML_C_OUTMUX_CY << XC6_ML_C_OUTMUX_O; break;
|
||||
case MUX_O5: mi2526 |= XC6_ML_C_OUTMUX_O5 << XC6_ML_C_OUTMUX_O; break;
|
||||
case MUX_F7: mi2526 |= XC6_ML_C_OUTMUX_F7 << XC6_ML_C_OUTMUX_O; break;
|
||||
}
|
||||
switch (dev_ml->u.logic.a2d[LUT_C].ff_mux) {
|
||||
// XC6_ML_C_FFMUX_O6 is 0
|
||||
case MUX_O5: mi2526 |= XC6_ML_C_FFMUX_O5 << XC6_ML_C_FFMUX_O; break;
|
||||
case MUX_X: mi2526 |= XC6_ML_C_FFMUX_X << XC6_ML_C_FFMUX_O; break;
|
||||
case MUX_F7: mi2526 |= XC6_ML_C_FFMUX_F7 << XC6_ML_C_FFMUX_O; break;
|
||||
case MUX_XOR: mi2526 |= XC6_ML_C_FFMUX_XOR << XC6_ML_C_FFMUX_O; break;
|
||||
case MUX_CY: mi2526 |= XC6_ML_C_FFMUX_CY << XC6_ML_C_FFMUX_O; break;
|
||||
}
|
||||
switch (dev_ml->u.logic.a2d[LUT_B].out_mux) {
|
||||
case MUX_5Q: mi2526 |= XC6_ML_B_OUTMUX_5Q << XC6_ML_B_OUTMUX_O; break;
|
||||
case MUX_F8: mi2526 |= XC6_ML_B_OUTMUX_F8 << XC6_ML_B_OUTMUX_O; break;
|
||||
case MUX_XOR: mi2526 |= XC6_ML_B_OUTMUX_XOR << XC6_ML_B_OUTMUX_O; break;
|
||||
case MUX_CY: mi2526 |= XC6_ML_B_OUTMUX_CY << XC6_ML_B_OUTMUX_O; break;
|
||||
case MUX_O6: mi2526 |= XC6_ML_B_OUTMUX_O6 << XC6_ML_B_OUTMUX_O; break;
|
||||
case MUX_O5: mi2526 |= XC6_ML_B_OUTMUX_O5 << XC6_ML_B_OUTMUX_O; break;
|
||||
}
|
||||
if (dev_ml->u.logic.clk_inv == CLKINV_B)
|
||||
mi2526 |= 1ULL << XC6_ML_CLK_B;
|
||||
switch (dev_ml->u.logic.a2d[LUT_B].ff_mux) {
|
||||
// XC6_ML_B_FFMUX_O6 is 0
|
||||
case MUX_XOR: mi2526 |= XC6_ML_B_FFMUX_XOR << XC6_ML_B_FFMUX_O; break;
|
||||
case MUX_O5: mi2526 |= XC6_ML_B_FFMUX_O5 << XC6_ML_B_FFMUX_O; break;
|
||||
case MUX_CY: mi2526 |= XC6_ML_B_FFMUX_CY << XC6_ML_B_FFMUX_O; break;
|
||||
case MUX_X: mi2526 |= XC6_ML_B_FFMUX_X << XC6_ML_B_FFMUX_O; break;
|
||||
case MUX_F8: mi2526 |= XC6_ML_B_FFMUX_F8 << XC6_ML_B_FFMUX_O; break;
|
||||
}
|
||||
switch (dev_ml->u.logic.a2d[LUT_A].ff_mux) {
|
||||
// XC6_ML_A_FFMUX_O6 is 0
|
||||
case MUX_XOR: mi2526 |= XC6_ML_A_FFMUX_XOR << XC6_ML_A_FFMUX_O; break;
|
||||
case MUX_X: mi2526 |= XC6_ML_A_FFMUX_X << XC6_ML_A_FFMUX_O; break;
|
||||
case MUX_O5: mi2526 |= XC6_ML_A_FFMUX_O5 << XC6_ML_A_FFMUX_O; break;
|
||||
case MUX_CY: mi2526 |= XC6_ML_A_FFMUX_CY << XC6_ML_A_FFMUX_O; break;
|
||||
case MUX_F7: mi2526 |= XC6_ML_A_FFMUX_F7 << XC6_ML_A_FFMUX_O; break;
|
||||
}
|
||||
switch (dev_ml->u.logic.a2d[LUT_A].out_mux) {
|
||||
case MUX_5Q: mi2526 |= XC6_ML_A_OUTMUX_5Q << XC6_ML_A_OUTMUX_O; break;
|
||||
case MUX_F7: mi2526 |= XC6_ML_A_OUTMUX_F7 << XC6_ML_A_OUTMUX_O; break;
|
||||
case MUX_XOR: mi2526 |= XC6_ML_A_OUTMUX_XOR << XC6_ML_A_OUTMUX_O; break;
|
||||
case MUX_CY: mi2526 |= XC6_ML_A_OUTMUX_CY << XC6_ML_A_OUTMUX_O; break;
|
||||
case MUX_O6: mi2526 |= XC6_ML_A_OUTMUX_O6 << XC6_ML_A_OUTMUX_O; break;
|
||||
case MUX_O5: mi2526 |= XC6_ML_A_OUTMUX_O5 << XC6_ML_A_OUTMUX_O; break;
|
||||
}
|
||||
if (dev_ml->u.logic.a2d[LUT_B].cy0 == CY0_O5)
|
||||
mi2526 |= 1ULL << XC6_ML_B_CY0_O5;
|
||||
if (dev_ml->u.logic.precyinit == PRECYINIT_AX)
|
||||
mi2526 |= 1ULL << XC6_ML_PRECYINIT_AX;
|
||||
else if (dev_ml->u.logic.precyinit == PRECYINIT_1)
|
||||
mi2526 |= 1ULL << XC6_ML_PRECYINIT_1;
|
||||
if (dev_ml->u.logic.a2d[LUT_B].ff_srinit == FF_SRINIT1)
|
||||
mi2526 |= 1ULL << XC6_ML_B_FFSRINIT_1;
|
||||
if (dev_ml->u.logic.a2d[LUT_A].cy0 == CY0_O5)
|
||||
mi2526 |= 1ULL << XC6_ML_A_CY0_O5;
|
||||
if (!xm_col && dev_ml->u.logic.a2d[LUT_A].ff_srinit == FF_SRINIT1)
|
||||
mi2526 |= 1ULL << XC6_L_A_FFSRINIT_1;
|
||||
}
|
||||
|
||||
//
|
||||
// 2.3) luts
|
||||
//
|
||||
|
||||
// X device
|
||||
if (dev_x->instantiated) {
|
||||
rc = str2lut(&lut_X[LUT_A], xm_col
|
||||
? XC6_LMAP_XM_X_A : XC6_LMAP_XL_X_A,
|
||||
&dev_x->u.logic.a2d[LUT_A]);
|
||||
RC_ASSERT(model, !rc);
|
||||
rc = str2lut(&lut_X[LUT_B], xm_col
|
||||
? XC6_LMAP_XM_X_B : XC6_LMAP_XL_X_B,
|
||||
&dev_x->u.logic.a2d[LUT_B]);
|
||||
RC_ASSERT(model, !rc);
|
||||
rc = str2lut(&lut_X[LUT_C], xm_col
|
||||
? XC6_LMAP_XM_X_C : XC6_LMAP_XL_X_C,
|
||||
&dev_x->u.logic.a2d[LUT_C]);
|
||||
RC_ASSERT(model, !rc);
|
||||
rc = str2lut(&lut_X[LUT_D], xm_col
|
||||
? XC6_LMAP_XM_X_D : XC6_LMAP_XL_X_D,
|
||||
&dev_x->u.logic.a2d[LUT_D]);
|
||||
RC_ASSERT(model, !rc);
|
||||
}
|
||||
// M or L device
|
||||
if (dev_ml->instantiated) {
|
||||
rc = str2lut(&lut_ML[LUT_A], xm_col
|
||||
? XC6_LMAP_XM_M_A : XC6_LMAP_XL_L_A,
|
||||
&dev_ml->u.logic.a2d[LUT_A]);
|
||||
RC_ASSERT(model, !rc);
|
||||
rc = str2lut(&lut_ML[LUT_B], xm_col
|
||||
? XC6_LMAP_XM_M_B : XC6_LMAP_XL_L_B,
|
||||
&dev_ml->u.logic.a2d[LUT_B]);
|
||||
RC_ASSERT(model, !rc);
|
||||
rc = str2lut(&lut_ML[LUT_C], xm_col
|
||||
? XC6_LMAP_XM_M_C : XC6_LMAP_XL_L_C,
|
||||
&dev_ml->u.logic.a2d[LUT_C]);
|
||||
RC_ASSERT(model, !rc);
|
||||
rc = str2lut(&lut_ML[LUT_D], xm_col
|
||||
? XC6_LMAP_XM_M_D : XC6_LMAP_XL_L_D,
|
||||
&dev_ml->u.logic.a2d[LUT_D]);
|
||||
RC_ASSERT(model, !rc);
|
||||
}
|
||||
|
||||
//
|
||||
// 3) write bits
|
||||
//
|
||||
|
||||
// logic devs occupy only some bits in mi20, so we merge
|
||||
// with the others (switches).
|
||||
frame_set_u64(u8_p + 20*FRAME_SIZE + byte_off,
|
||||
(frame_get_u64(u8_p + 20*FRAME_SIZE + byte_off) & ~XC6_MI20_LOGIC_MASK)
|
||||
| mi20);
|
||||
if (xm_col) {
|
||||
frame_set_u64(u8_p + 23*FRAME_SIZE + byte_off, mi23_M);
|
||||
frame_set_u64(u8_p + 26*FRAME_SIZE + byte_off, mi2526);
|
||||
frame_set_lut64(u8_p + 24*FRAME_SIZE, row_pos*2+1, lut_ML[LUT_A]);
|
||||
frame_set_lut64(u8_p + 21*FRAME_SIZE, row_pos*2+1, lut_ML[LUT_B]);
|
||||
frame_set_lut64(u8_p + 24*FRAME_SIZE, row_pos*2, lut_ML[LUT_C]);
|
||||
frame_set_lut64(u8_p + 21*FRAME_SIZE, row_pos*2, lut_ML[LUT_D]);
|
||||
frame_set_lut64(u8_p + 27*FRAME_SIZE, row_pos*2+1, lut_X[LUT_A]);
|
||||
frame_set_lut64(u8_p + 29*FRAME_SIZE, row_pos*2+1, lut_X[LUT_B]);
|
||||
frame_set_lut64(u8_p + 27*FRAME_SIZE, row_pos*2, lut_X[LUT_C]);
|
||||
frame_set_lut64(u8_p + 29*FRAME_SIZE, row_pos*2, lut_X[LUT_D]);
|
||||
} else { // xl
|
||||
// mi23 is unused in xl cols - no need to write it
|
||||
RC_ASSERT(model, !mi23_M);
|
||||
frame_set_u64(u8_p + 25*FRAME_SIZE + byte_off, mi2526);
|
||||
frame_set_lut64(u8_p + 23*FRAME_SIZE, row_pos*2+1, lut_ML[LUT_A]);
|
||||
frame_set_lut64(u8_p + 21*FRAME_SIZE, row_pos*2+1, lut_ML[LUT_B]);
|
||||
frame_set_lut64(u8_p + 23*FRAME_SIZE, row_pos*2, lut_ML[LUT_C]);
|
||||
frame_set_lut64(u8_p + 21*FRAME_SIZE, row_pos*2, lut_ML[LUT_D]);
|
||||
frame_set_lut64(u8_p + 26*FRAME_SIZE, row_pos*2+1, lut_X[LUT_A]);
|
||||
frame_set_lut64(u8_p + 28*FRAME_SIZE, row_pos*2+1, lut_X[LUT_B]);
|
||||
frame_set_lut64(u8_p + 26*FRAME_SIZE, row_pos*2, lut_X[LUT_C]);
|
||||
frame_set_lut64(u8_p + 28*FRAME_SIZE, row_pos*2, lut_X[LUT_D]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
RC_RETURN(model);
|
||||
}
|
||||
|
||||
int write_model(struct fpga_bits* bits, struct fpga_model* model)
|
||||
|
|
|
@ -131,6 +131,10 @@ static int bool_eval(const char *expr, int len, const int *var)
|
|||
{
|
||||
int i, negate, result, oplen;
|
||||
|
||||
if (len == 1) {
|
||||
if (*expr == '1') return 1;
|
||||
if (*expr == '0') return 0;
|
||||
}
|
||||
oplen = bool_nextlen(expr, len);
|
||||
if (oplen < 1) goto fail;
|
||||
i = 0;
|
||||
|
@ -192,14 +196,19 @@ 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)
|
||||
{
|
||||
int i, j, bool_res, rc, vars[6];
|
||||
int i, j, bool_res, rc, str_len, vars[6];
|
||||
|
||||
if (num_bits != 32 && num_bits != 64) HERE();
|
||||
*u64 = 0;
|
||||
if (num_bits == 64)
|
||||
*u64 = 0;
|
||||
else if (num_bits == 32)
|
||||
*u64 &= 0xFFFFFFFF00000000;
|
||||
else FAIL(EINVAL);
|
||||
|
||||
str_len = strlen(str);
|
||||
for (i = 0; i < num_bits; i++) {
|
||||
for (j = 0; j < sizeof(vars)/sizeof(*vars); j++)
|
||||
vars[j] = (i & (1<<j)) != 0;
|
||||
bool_res = bool_eval(str, strlen(str), vars);
|
||||
bool_res = bool_eval(str, str_len, vars);
|
||||
if (bool_res == -1) FAIL(EINVAL);
|
||||
if (bool_res) *u64 |= 1ULL<<i;
|
||||
}
|
||||
|
@ -334,27 +343,6 @@ const char* bool_bits2str(uint64_t u64, int num_bits)
|
|||
return str;
|
||||
}
|
||||
|
||||
int parse_boolexpr(const char *expr, uint64_t *lut)
|
||||
{
|
||||
int i, j, result, vars[6];
|
||||
|
||||
*lut = 0;
|
||||
for (i = 0; i < 64; i++) {
|
||||
memcpy(vars, lut_base_vars, sizeof(vars));
|
||||
for (j = 0; j < 6; j++) {
|
||||
if (j != 2 && (i & (1<<j)))
|
||||
vars[j] = !vars[j];
|
||||
}
|
||||
if (((i&8) != 0) ^ ((i&4) != 0))
|
||||
vars[2] = 1;
|
||||
// todo: flip_b0 and different base values missing
|
||||
result = bool_eval(expr, strlen(expr), vars);
|
||||
if (result == -1) return -1;
|
||||
if (result) *lut |= 1LL<<i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void printf_type2(uint8_t *d, int len, int inpos, int num_entries)
|
||||
{
|
||||
uint64_t u64;
|
||||
|
|
|
@ -67,8 +67,6 @@ 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);
|
||||
|
||||
void printf_type2(uint8_t* d, int len, int inpos, int num_entries);
|
||||
void printf_ramb16_data(uint8_t* bits, int inpos);
|
||||
|
||||
|
|
|
@ -346,7 +346,8 @@ typedef int dev_idx_t;
|
|||
typedef int dev_type_idx_t;
|
||||
|
||||
#define NO_DEV -1
|
||||
#define FPGA_DEV(model, y, x, dev_idx) (&YX_TILE(model, y, x)->devs[dev_idx])
|
||||
#define FPGA_DEV(model, y, x, dev_idx) \
|
||||
((dev_idx == NO_DEV) ? 0 : (&YX_TILE(model, y, x)->devs[dev_idx]))
|
||||
|
||||
//
|
||||
// DEV_LOGIC
|
||||
|
|
92
libs/parts.h
92
libs/parts.h
|
@ -328,19 +328,19 @@ void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits);
|
|||
|
||||
#define XC6_ML_D_OUTMUX_MASK 0x0000000000000F00ULL
|
||||
#define XC6_ML_D_OUTMUX_O 8
|
||||
#define XC6_ML_D_OUTMUX_O6 1 // 0001
|
||||
#define XC6_ML_D_OUTMUX_XOR 2 // 0010
|
||||
#define XC6_ML_D_OUTMUX_O5 5 // 0101, implies lut5 on ML-D
|
||||
#define XC6_ML_D_OUTMUX_CY 6 // 0110
|
||||
#define XC6_ML_D_OUTMUX_5Q 8 // 1000, implies lut5 on ML-D
|
||||
#define XC6_ML_D_OUTMUX_O6 1ULL // 0001
|
||||
#define XC6_ML_D_OUTMUX_XOR 2ULL // 0010
|
||||
#define XC6_ML_D_OUTMUX_O5 5ULL // 0101, implies lut5 on ML-D
|
||||
#define XC6_ML_D_OUTMUX_CY 6ULL // 0110
|
||||
#define XC6_ML_D_OUTMUX_5Q 8ULL // 1000, implies lut5 on ML-D
|
||||
|
||||
#define XC6_ML_D_FFMUX_MASK 0x000000000000F000ULL
|
||||
#define XC6_ML_D_FFMUX_O 12
|
||||
#define XC6_ML_D_FFMUX_O6 0 // 0000
|
||||
#define XC6_ML_D_FFMUX_O5 1 // 0001, implies lut5 on ML-D
|
||||
#define XC6_ML_D_FFMUX_X 10 // 1010
|
||||
#define XC6_ML_D_FFMUX_XOR 12 // 1100
|
||||
#define XC6_ML_D_FFMUX_CY 13 // 1101
|
||||
#define XC6_ML_D_FFMUX_O6 0ULL // 0000
|
||||
#define XC6_ML_D_FFMUX_O5 1ULL // 0001, implies lut5 on ML-D
|
||||
#define XC6_ML_D_FFMUX_X 10ULL // 1010
|
||||
#define XC6_ML_D_FFMUX_XOR 12ULL // 1100
|
||||
#define XC6_ML_D_FFMUX_CY 13ULL // 1101
|
||||
|
||||
#define XC6_X_CLK_B 16
|
||||
#define XC6_ML_ALL_LATCH 17
|
||||
|
@ -355,30 +355,30 @@ void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits);
|
|||
|
||||
#define XC6_ML_C_OUTMUX_MASK 0x000000000F000000ULL
|
||||
#define XC6_ML_C_OUTMUX_O 24
|
||||
#define XC6_ML_C_OUTMUX_XOR 1 // 0001
|
||||
#define XC6_ML_C_OUTMUX_O6 2 // 0010
|
||||
#define XC6_ML_C_OUTMUX_5Q 4 // 0100, implies lut5 on ML-C
|
||||
#define XC6_ML_C_OUTMUX_CY 9 // 1001
|
||||
#define XC6_ML_C_OUTMUX_O5 10 // 1010, implies lut5 on ML-C
|
||||
#define XC6_ML_C_OUTMUX_F7 12 // 1100
|
||||
#define XC6_ML_C_OUTMUX_XOR 1ULL // 0001
|
||||
#define XC6_ML_C_OUTMUX_O6 2ULL // 0010
|
||||
#define XC6_ML_C_OUTMUX_5Q 4ULL // 0100, implies lut5 on ML-C
|
||||
#define XC6_ML_C_OUTMUX_CY 9ULL // 1001
|
||||
#define XC6_ML_C_OUTMUX_O5 10ULL // 1010, implies lut5 on ML-C
|
||||
#define XC6_ML_C_OUTMUX_F7 12ULL // 1100
|
||||
|
||||
#define XC6_ML_C_FFMUX_MASK 0x00000000F0000000ULL
|
||||
#define XC6_ML_C_FFMUX_O 28
|
||||
#define XC6_ML_C_FFMUX_O6 0 // 0000
|
||||
#define XC6_ML_C_FFMUX_O5 2 // 0010, implies lut5 on ML-C
|
||||
#define XC6_ML_C_FFMUX_X 5 // 0101
|
||||
#define XC6_ML_C_FFMUX_F7 7 // 0111
|
||||
#define XC6_ML_C_FFMUX_XOR 12 // 1100
|
||||
#define XC6_ML_C_FFMUX_CY 14 // 1110
|
||||
#define XC6_ML_C_FFMUX_O6 0ULL // 0000
|
||||
#define XC6_ML_C_FFMUX_O5 2ULL // 0010, implies lut5 on ML-C
|
||||
#define XC6_ML_C_FFMUX_X 5ULL // 0101
|
||||
#define XC6_ML_C_FFMUX_F7 7ULL // 0111
|
||||
#define XC6_ML_C_FFMUX_XOR 12ULL // 1100
|
||||
#define XC6_ML_C_FFMUX_CY 14ULL // 1110
|
||||
|
||||
#define XC6_ML_B_OUTMUX_MASK 0x0000000F00000000ULL
|
||||
#define XC6_ML_B_OUTMUX_O 32
|
||||
#define XC6_ML_B_OUTMUX_5Q 2 // 0010, implies lut5 on ML-B
|
||||
#define XC6_ML_B_OUTMUX_F8 3 // 0011
|
||||
#define XC6_ML_B_OUTMUX_XOR 4 // 0100
|
||||
#define XC6_ML_B_OUTMUX_CY 5 // 0101
|
||||
#define XC6_ML_B_OUTMUX_O6 8 // 1000
|
||||
#define XC6_ML_B_OUTMUX_O5 9 // 1001, implies lut5 on ML-B
|
||||
#define XC6_ML_B_OUTMUX_5Q 2ULL // 0010, implies lut5 on ML-B
|
||||
#define XC6_ML_B_OUTMUX_F8 3ULL // 0011
|
||||
#define XC6_ML_B_OUTMUX_XOR 4ULL // 0100
|
||||
#define XC6_ML_B_OUTMUX_CY 5ULL // 0101
|
||||
#define XC6_ML_B_OUTMUX_O6 8ULL // 1000
|
||||
#define XC6_ML_B_OUTMUX_O5 9ULL // 1001, implies lut5 on ML-B
|
||||
|
||||
// X_B_FFMUX=O6 -
|
||||
#define XC6_X_B_FFMUX_X 36 // default-set, does not imply lut5
|
||||
|
@ -394,30 +394,30 @@ void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits);
|
|||
|
||||
#define XC6_ML_B_FFMUX_MASK 0x0000F00000000000ULL
|
||||
#define XC6_ML_B_FFMUX_O 44
|
||||
#define XC6_ML_B_FFMUX_O6 0 // 0000
|
||||
#define XC6_ML_B_FFMUX_XOR 3 // 0011
|
||||
#define XC6_ML_B_FFMUX_O5 4 // 0100, implies lut5 on ML-B
|
||||
#define XC6_ML_B_FFMUX_CY 7 // 0111
|
||||
#define XC6_ML_B_FFMUX_X 10 // 1010
|
||||
#define XC6_ML_B_FFMUX_F8 14 // 1110
|
||||
#define XC6_ML_B_FFMUX_O6 0ULL // 0000
|
||||
#define XC6_ML_B_FFMUX_XOR 3ULL // 0011
|
||||
#define XC6_ML_B_FFMUX_O5 4ULL // 0100, implies lut5 on ML-B
|
||||
#define XC6_ML_B_FFMUX_CY 7ULL // 0111
|
||||
#define XC6_ML_B_FFMUX_X 10ULL // 1010
|
||||
#define XC6_ML_B_FFMUX_F8 14ULL // 1110
|
||||
|
||||
#define XC6_ML_A_FFMUX_MASK 0x000F000000000000ULL
|
||||
#define XC6_ML_A_FFMUX_O 48
|
||||
#define XC6_ML_A_FFMUX_O6 0 // 0000
|
||||
#define XC6_ML_A_FFMUX_XOR 3 // 0011
|
||||
#define XC6_ML_A_FFMUX_X 5 // 0101
|
||||
#define XC6_ML_A_FFMUX_O5 8 // 1000, implies lut5 on ML-A
|
||||
#define XC6_ML_A_FFMUX_CY 11 // 1011
|
||||
#define XC6_ML_A_FFMUX_F7 13 // 1101
|
||||
#define XC6_ML_A_FFMUX_O6 0ULL // 0000
|
||||
#define XC6_ML_A_FFMUX_XOR 3ULL // 0011
|
||||
#define XC6_ML_A_FFMUX_X 5ULL // 0101
|
||||
#define XC6_ML_A_FFMUX_O5 8ULL // 1000, implies lut5 on ML-A
|
||||
#define XC6_ML_A_FFMUX_CY 11ULL // 1011
|
||||
#define XC6_ML_A_FFMUX_F7 13ULL // 1101
|
||||
|
||||
#define XC6_ML_A_OUTMUX_MASK 0x00F0000000000000ULL
|
||||
#define XC6_ML_A_OUTMUX_O 52
|
||||
#define XC6_ML_A_OUTMUX_5Q 1 // 0001, implies lut5 on ML-A
|
||||
#define XC6_ML_A_OUTMUX_F7 3 // 0011
|
||||
#define XC6_ML_A_OUTMUX_XOR 4 // 0100
|
||||
#define XC6_ML_A_OUTMUX_CY 6 // 0110
|
||||
#define XC6_ML_A_OUTMUX_O6 8 // 1000
|
||||
#define XC6_ML_A_OUTMUX_O5 10 // 1010, implies lut5 on ML-A
|
||||
#define XC6_ML_A_OUTMUX_5Q 1ULL // 0001, implies lut5 on ML-A
|
||||
#define XC6_ML_A_OUTMUX_F7 3ULL // 0011
|
||||
#define XC6_ML_A_OUTMUX_XOR 4ULL // 0100
|
||||
#define XC6_ML_A_OUTMUX_CY 6ULL // 0110
|
||||
#define XC6_ML_A_OUTMUX_O6 8ULL // 1000
|
||||
#define XC6_ML_A_OUTMUX_O5 10ULL // 1010, implies lut5 on ML-A
|
||||
|
||||
// ML_B_CY0=BX -
|
||||
#define XC6_ML_B_CY0_O5 56 // implies lut5 on ML-B
|
||||
|
|
Loading…
Reference in New Issue
Block a user