more logic device cases

This commit is contained in:
Wolfgang Spraul 2012-12-15 14:59:05 -05:00
parent 19d5719c57
commit 9d84e5da23
6 changed files with 410 additions and 139 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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