more logic variable reorg

This commit is contained in:
Wolfgang Spraul 2013-02-14 08:42:08 -05:00
parent a6aa341772
commit 740903a09c
11 changed files with 510 additions and 397 deletions

8
README
View File

@ -60,10 +60,12 @@ Design Principles
- automatic test suite
- public domain software
TODO (as of January, 2013)
TODO (as of February, 2013)
short-term (1 month):
* support distributed and block memory
* finish lut_encoding test
* finish dist_mem test
* support block memory
* example: counter (including clock, jtag)
mid-term (6 months):
@ -71,7 +73,7 @@ mid-term (6 months):
* llvm backend
* maybe fp2bit should natively write ieee1532 and separate tools convert
from ieee1532 to .bit and other formats
* configuration of bram and macc blocks, bram initialization data
* macc
* more cases in logic block configuration
* autotest: fix bugs in lut_encoding, logic_cfg, routing_sw, io_sw tests
* autotest: protect stderr of diff executable in autotest log

View File

@ -530,13 +530,14 @@ fail:
return rc;
}
static int test_routing_sw_from_logic(struct test_state* tstate,
swidx_t* done_list, int* done_list_len)
static int test_routing_sw_from_logic(struct test_state *tstate,
swidx_t *done_list, int *done_list_len)
{
struct fpga_device* dev;
struct fpga_device *dev;
struct fpgadev_logic logic_cfg;
struct switch_to_rel swto;
struct sw_conns conns;
const char* str;
const char *str;
net_idx_t net;
int y, x, rel_y, i, rc;
@ -548,13 +549,13 @@ static int test_routing_sw_from_logic(struct test_state* tstate,
// from below, or sr1/sl1 wires from above.
for (rel_y = -1; rel_y <= 1; rel_y += 2) {
for (i = '1'; i <= '6'; i++) {
rc = fdev_logic_set_lutstr(tstate->model, y, x,
DEV_LOG_M_OR_L, LUT_A, /*lut6_str*/ pf("A%c", i), /*lut5_str*/ 0);
CLEAR(logic_cfg);
logic_cfg.a2d[LUT_A].flags |= OUT_USED | LUT6VAL_SET;
rc = bool_str2u64(pf("A%c", i), &logic_cfg.a2d[LUT_A].lut6_val);
if (rc) FAIL(rc);
rc = fdev_set_required_pins(tstate->model, y, x,
DEV_LOGIC, DEV_LOG_M_OR_L);
rc = fdev_logic_setconf(tstate->model, y, x, DEV_LOG_M_OR_L, &logic_cfg);
if (rc) FAIL(rc);
if (tstate->dry_run)
fdev_print_required_pins(tstate->model,
y, x, DEV_LOGIC, DEV_LOG_M_OR_L);
@ -628,6 +629,7 @@ fail:
static int test_routing_switches(struct test_state* tstate)
{
int idx_enum[] = { DEV_LOG_M_OR_L, DEV_LOG_X };
struct fpgadev_logic logic_cfg;
int y, x, i, j, k, r, rc;
swidx_t done_sw_list[MAX_SWITCHBOX_SIZE];
int done_sw_len;
@ -649,10 +651,13 @@ static int test_routing_switches(struct test_state* tstate)
// A1-A6 to A (same for lut B-D)
for (k = '1'; k <= '6'; k++) {
rc = fdev_logic_set_lutstr(tstate->model, y, x,
idx_enum[i], j, /*lut6_str*/ pf("A%c", k), /*lut5_str*/ 0);
CLEAR(logic_cfg);
logic_cfg.a2d[j].flags |= OUT_USED | LUT6VAL_SET;
rc = bool_str2u64(pf("A%c", k), &logic_cfg.a2d[j].lut6_val);
if (rc) FAIL(rc);
rc = fdev_logic_setconf(tstate->model, y, x, idx_enum[i], &logic_cfg);
if (rc) FAIL(rc);
if (!r)
rc = test_logic_net_l1(tstate, y, x, DEV_LOGIC,
idx_enum[i], done_pinw_list, &done_pinw_len,
@ -666,9 +671,13 @@ static int test_routing_switches(struct test_state* tstate)
}
// A1->O6->FF->AQ (same for lut B-D)
rc = fdev_logic_set_lutstr(tstate->model, y, x,
idx_enum[i], j, /*lut6_str*/ "A1", /*lut5_str*/ 0);
CLEAR(logic_cfg);
logic_cfg.a2d[j].flags |= OUT_USED | LUT6VAL_SET;
rc = bool_str2u64("A1", &logic_cfg.a2d[j].lut6_val);
if (rc) FAIL(rc);
rc = fdev_logic_setconf(tstate->model, y, x, idx_enum[i], &logic_cfg);
if (rc) FAIL(rc);
rc = fdev_logic_a2d_ff(tstate->model, y, x, idx_enum[i],
j, MUX_O6, FF_SRINIT0);
if (rc) FAIL(rc);
@ -1233,24 +1242,22 @@ static int test_lut_encoding(struct test_state* tstate)
for (type_i = 0; type_i < sizeof(idx_enum)/sizeof(*idx_enum); type_i++) {
for (lut = LUT_A; lut <= LUT_D; lut++) {
CLEAR(logic_cfg);
logic_cfg.a2d[lut].lut_mode = LUTMODE_LUT;
logic_cfg.a2d[lut].out_used = 1;
logic_cfg.a2d[lut].flags |= OUT_USED | LUT6VAL_SET;
// lut6 only
rc = lutstr_to_val(/*lut6_str*/ "0", /*lut5_str*/ 0, &logic_cfg.a2d[lut].lut_val);
rc = bool_str2u64("0", &logic_cfg.a2d[lut].lut6_val);
if (rc) FAIL(rc);
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
&logic_cfg);
if (rc) FAIL(rc);
rc = lutstr_to_val(/*lut6_str*/ "1", /*lut5_str*/ 0, &logic_cfg.a2d[lut].lut_val);
rc = bool_str2u64("1", &logic_cfg.a2d[lut].lut6_val);
if (rc) FAIL(rc);
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
&logic_cfg);
if (rc) FAIL(rc);
for (i = '1'; i <= '6'; i++) {
rc = lutstr_to_val(/*lut6_str*/ pf("A%c", i),
/*lut5_str*/ 0, &logic_cfg.a2d[lut].lut_val);
rc = bool_str2u64(pf("A%c", i), &logic_cfg.a2d[lut].lut6_val);
if (rc) FAIL(rc);
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
&logic_cfg);
@ -1258,25 +1265,30 @@ static int test_lut_encoding(struct test_state* tstate)
}
// lut6 and lut5 pairs
logic_cfg.a2d[lut].flags |= LUT5VAL_SET; // LUT6VAL_SET already on
logic_cfg.a2d[lut].out_mux = MUX_O5;
rc = lutstr_to_val(/*lut6_str*/ "(A6+~A6)*1",
/*lut5_str*/ "0", &logic_cfg.a2d[lut].lut_val);
logic_cfg.a2d[lut].lut6_val = 0;
rc = bool_str2lut_pair("(A6+~A6)*1", "0",
&logic_cfg.a2d[lut].lut6_val,
&logic_cfg.a2d[lut].lut5_val);
if (rc) FAIL(rc);
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
&logic_cfg);
if (rc) FAIL(rc);
rc = lutstr_to_val(/*lut6_str*/ "(A6+~A6)*0",
/*lut5_str*/ "1", &logic_cfg.a2d[lut].lut_val);
rc = bool_str2lut_pair("(A6+~A6)*0", "1",
&logic_cfg.a2d[lut].lut6_val,
&logic_cfg.a2d[lut].lut5_val);
if (rc) FAIL(rc);
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
&logic_cfg);
if (rc) FAIL(rc);
for (i = '1'; i <= '5'; i++) {
rc = lutstr_to_val(
/*lut6_str*/ pf("(A6+~A6)*A%c", (i == '5') ? '1' : i+1),
/*lut5_str*/ pf("A%c", i),
&logic_cfg.a2d[lut].lut_val);
rc = bool_str2lut_pair(
pf("(A6+~A6)*A%c", (i == '5') ? '1' : i+1),
pf("A%c", i),
&logic_cfg.a2d[lut].lut6_val,
&logic_cfg.a2d[lut].lut5_val);
if (rc) FAIL(rc);
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
&logic_cfg);
@ -1291,8 +1303,7 @@ static int test_lut_encoding(struct test_state* tstate)
for (type_i = 0; type_i < sizeof(idx_enum)/sizeof(*idx_enum); type_i++) {
for (lut = LUT_A; lut <= LUT_D; lut++) {
CLEAR(logic_cfg);
logic_cfg.a2d[lut].lut_mode = LUTMODE_LUT;
logic_cfg.a2d[lut].out_used = 1;
logic_cfg.a2d[lut].flags |= OUT_USED | LUT6VAL_SET;
for (i = 0; i < 64; i++) {
lut_str_len = 0;
@ -1305,10 +1316,7 @@ static int test_lut_encoding(struct test_state* tstate)
lut_str[lut_str_len++] = '1' + j;
}
lut_str[lut_str_len] = 0;
rc = lutstr_to_val(
/*lut6_str*/ lut_str,
/*lut5_str*/ 0,
&logic_cfg.a2d[lut].lut_val);
rc = bool_str2u64(lut_str, &logic_cfg.a2d[lut].lut6_val);
if (rc) FAIL(rc);
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
&logic_cfg);
@ -1320,8 +1328,7 @@ static int test_lut_encoding(struct test_state* tstate)
// --skip=1264 --count=64 - separate bits for lut5 (32) and lut6 (32) (xm-m-a only)
CLEAR(logic_cfg);
logic_cfg.a2d[LUT_A].lut_mode = LUTMODE_LUT;
logic_cfg.a2d[LUT_A].out_used = 1;
logic_cfg.a2d[LUT_A].flags |= OUT_USED | LUT6VAL_SET | LUT5VAL_SET;
logic_cfg.a2d[LUT_A].out_mux = MUX_O5;
// 32 bits in lut5 with lut6=0
for (i = 0; i < 32; i++) {
@ -1335,10 +1342,9 @@ static int test_lut_encoding(struct test_state* tstate)
lut_str[lut_str_len++] = '1' + j;
}
lut_str[lut_str_len] = 0;
rc = lutstr_to_val(
/*lut6_str*/ "(A6+~A6)*0",
/*lut5_str*/ lut_str,
&logic_cfg.a2d[LUT_A].lut_val);
rc = bool_str2lut_pair("(A6+~A6)*0", lut_str,
&logic_cfg.a2d[LUT_A].lut6_val,
&logic_cfg.a2d[LUT_A].lut5_val);
if (rc) FAIL(rc);
rc = test_logic(tstate, y, /*XM*/ 13, DEV_LOG_M_OR_L, &logic_cfg);
if (rc) FAIL(rc);
@ -1355,10 +1361,9 @@ static int test_lut_encoding(struct test_state* tstate)
lut_str[lut_str_len++] = '1' + j;
}
lut_str[lut_str_len] = 0;
rc = lutstr_to_val(
/*lut6_str*/ lut_str,
/*lut5_str*/ "0",
&logic_cfg.a2d[LUT_A].lut_val);
rc = bool_str2lut_pair(lut_str, "0",
&logic_cfg.a2d[LUT_A].lut6_val,
&logic_cfg.a2d[LUT_A].lut5_val);
if (rc) FAIL(rc);
rc = test_logic(tstate, y, /*XM*/ 13, DEV_LOG_M_OR_L, &logic_cfg);
if (rc) FAIL(rc);
@ -1369,8 +1374,8 @@ static int test_lut_encoding(struct test_state* tstate)
// ROM test in LUT_A
CLEAR(logic_cfg);
logic_cfg.clk_inv = CLKINV_CLK;
logic_cfg.a2d[LUT_A].lut_mode = LUTMODE_ROM;
logic_cfg.a2d[LUT_A].lut_val = 1ULL << i;
logic_cfg.a2d[LUT_A].flags |= LUT6VAL_SET | LUTMODE_ROM;
logic_cfg.a2d[LUT_A].lut6_val = 1ULL << i;
rc = test_logic(tstate, y, /*XM*/ 13, DEV_LOG_M_OR_L,
&logic_cfg);
if (rc) FAIL(rc);
@ -1380,8 +1385,8 @@ static int test_lut_encoding(struct test_state* tstate)
CLEAR(logic_cfg);
logic_cfg.we_mux = WEMUX_WE;
logic_cfg.clk_inv = CLKINV_CLK;
logic_cfg.a2d[LUT_D].lut_mode = LUTMODE_RAM;
logic_cfg.a2d[LUT_D].lut_val = 1ULL << i;
logic_cfg.a2d[LUT_D].flags |= LUT6VAL_SET;
logic_cfg.a2d[LUT_D].lut6_val = 1ULL << i;
logic_cfg.a2d[LUT_D].ram_mode = DPRAM64;
rc = test_logic(tstate, y, /*XM*/ 13, DEV_LOG_M_OR_L,
&logic_cfg);
@ -1414,12 +1419,9 @@ static int test_logic_config(struct test_state* tstate)
// lut6, direct-out
CLEAR(logic_cfg);
logic_cfg.a2d[lut].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "A1",
/*lut5_str*/ 0,
&logic_cfg.a2d[lut].lut_val))) FAIL(rc);
logic_cfg.a2d[lut].out_used = 1;
logic_cfg.a2d[lut].flags |= OUT_USED | LUT6VAL_SET;
rc = bool_str2u64("A1", &logic_cfg.a2d[lut].lut6_val);
if (rc) FAIL(rc);
rc = test_logic(tstate, y, x_enum[x_i],
idx_enum[type_i], &logic_cfg);
@ -1430,11 +1432,9 @@ static int test_logic_config(struct test_state* tstate)
// O6 over mux-out seems not supported
// on an X device.
CLEAR(logic_cfg);
logic_cfg.a2d[lut].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "A1",
/*lut5_str*/ 0,
&logic_cfg.a2d[lut].lut_val))) FAIL(rc);
logic_cfg.a2d[lut].flags |= LUT6VAL_SET;
rc = bool_str2u64("A1", &logic_cfg.a2d[lut].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[lut].out_mux = MUX_O6;
rc = test_logic(tstate, y, x_enum[x_i],
@ -1473,11 +1473,9 @@ static int test_logic_config(struct test_state* tstate)
// lut6, ff-out
CLEAR(logic_cfg);
logic_cfg.a2d[lut].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "A1",
/*lut5_str*/ 0,
&logic_cfg.a2d[lut].lut_val))) FAIL(rc);
logic_cfg.a2d[lut].flags |= LUT6VAL_SET;
rc = bool_str2u64("A1", &logic_cfg.a2d[lut].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[lut].ff = FF_FF;
logic_cfg.a2d[lut].ff_mux = MUX_O6;
logic_cfg.a2d[lut].ff_srinit = FF_SRINIT0;
@ -1520,11 +1518,9 @@ static int test_logic_config(struct test_state* tstate)
// lut6, latch-out
CLEAR(logic_cfg);
logic_cfg.a2d[lut].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "A1",
/*lut5_str*/ 0,
&logic_cfg.a2d[lut].lut_val))) FAIL(rc);
logic_cfg.a2d[lut].flags |= LUT6VAL_SET;
rc = bool_str2u64("A1", &logic_cfg.a2d[lut].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[lut].ff = FF_LATCH;
logic_cfg.a2d[lut].ff_mux = MUX_O6;
logic_cfg.a2d[lut].ff_srinit = FF_SRINIT0;
@ -1548,11 +1544,9 @@ static int test_logic_config(struct test_state* tstate)
// lut6, and-latch
CLEAR(logic_cfg);
logic_cfg.a2d[lut].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "A1",
/*lut5_str*/ 0,
&logic_cfg.a2d[lut].lut_val))) FAIL(rc);
logic_cfg.a2d[lut].flags |= LUT6VAL_SET;
rc = bool_str2u64("A1", &logic_cfg.a2d[lut].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[lut].ff = FF_AND2L;
logic_cfg.a2d[lut].ff_mux = MUX_O6;
// AND2L requires SRINIT=0
@ -1569,11 +1563,9 @@ static int test_logic_config(struct test_state* tstate)
// lut6, or-latch
CLEAR(logic_cfg);
logic_cfg.a2d[lut].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "A1",
/*lut5_str*/ 0,
&logic_cfg.a2d[lut].lut_val))) FAIL(rc);
logic_cfg.a2d[lut].flags |= LUT6VAL_SET;
rc = bool_str2u64("A1", &logic_cfg.a2d[lut].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[lut].ff = FF_OR2L;
logic_cfg.a2d[lut].ff_mux = MUX_O6;
// OR2L requires SRINIT=1
@ -1601,16 +1593,13 @@ static int test_logic_config(struct test_state* tstate)
if (rc) FAIL(rc);
// . o6-direct
logic_cfg.a2d[lut].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "A1",
/*lut5_str*/ 0,
&logic_cfg.a2d[lut].lut_val))) FAIL(rc);
logic_cfg.a2d[lut].out_used = 1;
logic_cfg.a2d[lut].flags |= OUT_USED | LUT6VAL_SET;
rc = bool_str2u64("A1", &logic_cfg.a2d[lut].lut6_val);
if (rc) FAIL(rc);
rc = test_logic(tstate, y, x_enum[x_i],
idx_enum[type_i], &logic_cfg);
if (rc) FAIL(rc);
logic_cfg.a2d[lut].out_used = 1;
logic_cfg.a2d[lut].flags |= OUT_USED;
if (idx_enum[type_i] == DEV_LOG_M_OR_L) {
// . o6-outmux
@ -1627,12 +1616,13 @@ static int test_logic_config(struct test_state* tstate)
// lut6 direct-out, lut5 mux-out
CLEAR(logic_cfg);
logic_cfg.a2d[lut].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A6+~A6)*A1",
/*lut5_str*/ "A1*A2",
&logic_cfg.a2d[lut].lut_val))) FAIL(rc);
logic_cfg.a2d[lut].out_used = 1;
logic_cfg.a2d[lut].flags |= OUT_USED | LUT6VAL_SET | LUT5VAL_SET;
rc = bool_str2lut_pair(
/*lut6*/ "(A6+~A6)*A1",
/*lut5*/ "A1*A2",
&logic_cfg.a2d[lut].lut6_val,
&logic_cfg.a2d[lut].lut5_val);
if (rc) FAIL(rc);
logic_cfg.a2d[lut].out_mux = MUX_O5;
rc = test_logic(tstate, y, x_enum[x_i],
idx_enum[type_i], &logic_cfg);
@ -1706,41 +1696,52 @@ static int test_logic_config(struct test_state* tstate)
if (idx_enum[type_i] == DEV_LOG_X) {
// minimum-config X device
CLEAR(logic_cfg);
logic_cfg.a2d[LUT_A].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A6+~A6)*A1",
/*lut5_str*/ "A2",
&logic_cfg.a2d[LUT_A].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_A].flags |= LUT6VAL_SET | LUT5VAL_SET;
rc = bool_str2lut_pair(
/*lut6*/ "(A6+~A6)*A1",
/*lut5*/ "A2",
&logic_cfg.a2d[LUT_A].lut6_val,
&logic_cfg.a2d[LUT_A].lut5_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_A].out_mux = MUX_5Q;
logic_cfg.a2d[LUT_A].ff5_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_A].ff = FF_FF;
logic_cfg.a2d[LUT_A].ff_mux = MUX_O6;
logic_cfg.a2d[LUT_A].ff_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_B].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A6+~A6)*A4",
/*lut5_str*/ "A3",
&logic_cfg.a2d[LUT_B].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_B].flags |= LUT6VAL_SET | LUT5VAL_SET;
rc = bool_str2lut_pair(
/*lut6*/ "(A6+~A6)*A4",
/*lut5*/ "A3",
&logic_cfg.a2d[LUT_B].lut6_val,
&logic_cfg.a2d[LUT_B].lut5_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_B].out_mux = MUX_5Q;
logic_cfg.a2d[LUT_B].ff5_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_B].ff = FF_FF;
logic_cfg.a2d[LUT_B].ff_mux = MUX_O6;
logic_cfg.a2d[LUT_B].ff_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_C].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A6+~A6)*(A2+A5)",
/*lut5_str*/ "A3+A4",
&logic_cfg.a2d[LUT_C].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_C].flags |= LUT6VAL_SET | LUT5VAL_SET;
rc = bool_str2lut_pair(
/*lut6*/ "(A6+~A6)*(A2+A5)",
/*lut5*/ "A3+A4",
&logic_cfg.a2d[LUT_C].lut6_val,
&logic_cfg.a2d[LUT_C].lut5_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_C].out_mux = MUX_5Q;
logic_cfg.a2d[LUT_C].ff5_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_C].ff = FF_FF;
logic_cfg.a2d[LUT_C].ff_mux = MUX_O6;
logic_cfg.a2d[LUT_C].ff_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_D].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A6+~A6)*A3",
/*lut5_str*/ "A3+A5",
&logic_cfg.a2d[LUT_D].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_D].flags |= LUT6VAL_SET | LUT5VAL_SET;
rc = bool_str2lut_pair(
/*lut6*/ "(A6+~A6)*A3",
/*lut5*/ "A3+A5",
&logic_cfg.a2d[LUT_D].lut6_val,
&logic_cfg.a2d[LUT_D].lut5_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_D].out_mux = MUX_5Q;
logic_cfg.a2d[LUT_D].ff5_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_D].ff = FF_FF;
@ -1757,38 +1758,49 @@ static int test_logic_config(struct test_state* tstate)
}
// cout
CLEAR(logic_cfg);
logic_cfg.a2d[LUT_A].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A6+~A6)*(~A5)",
/*lut5_str*/ "1",
&logic_cfg.a2d[LUT_A].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_A].flags |= LUT6VAL_SET | LUT5VAL_SET;
rc = bool_str2lut_pair(
/*lut6*/ "(A6+~A6)*(~A5)",
/*lut5*/ "1",
&logic_cfg.a2d[LUT_A].lut6_val,
&logic_cfg.a2d[LUT_A].lut5_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_A].cy0 = CY0_O5;
logic_cfg.a2d[LUT_A].ff = FF_FF;
logic_cfg.a2d[LUT_A].ff_mux = MUX_XOR;
logic_cfg.a2d[LUT_A].ff_srinit = FF_SRINIT0;
logic_cfg.a2d[LUT_B].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A6+~A6)*(A5)",
/*lut5_str*/ "1",
&logic_cfg.a2d[LUT_B].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_B].flags |= LUT6VAL_SET | LUT5VAL_SET;
rc = bool_str2lut_pair(
/*lut6*/ "(A6+~A6)*(A5)",
/*lut5*/ "1",
&logic_cfg.a2d[LUT_B].lut6_val,
&logic_cfg.a2d[LUT_B].lut5_val);
if (rc) FAIL(rc);
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].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A6+~A6)*(A5)",
/*lut5_str*/ "1",
&logic_cfg.a2d[LUT_C].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_C].flags |= LUT6VAL_SET | LUT5VAL_SET;
rc = bool_str2lut_pair(
/*lut6*/ "(A6+~A6)*(A5)",
/*lut5*/ "1",
&logic_cfg.a2d[LUT_C].lut6_val,
&logic_cfg.a2d[LUT_C].lut5_val);
if (rc) FAIL(rc);
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].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A6+~A6)*(A5)",
/*lut5_str*/ "1",
&logic_cfg.a2d[LUT_D].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_D].flags |= LUT6VAL_SET | LUT5VAL_SET;
rc = bool_str2lut_pair(
/*lut6*/ "(A6+~A6)*(A5)",
/*lut5*/ "1",
&logic_cfg.a2d[LUT_D].lut6_val,
&logic_cfg.a2d[LUT_D].lut5_val);
if (rc) FAIL(rc);
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;
@ -1805,26 +1817,18 @@ static int test_logic_config(struct test_state* tstate)
// f8 out-mux
CLEAR(logic_cfg);
logic_cfg.a2d[LUT_A].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "~A5",
/*lut5_str*/ 0,
&logic_cfg.a2d[LUT_A].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_B].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A5)",
/*lut5_str*/ 0,
&logic_cfg.a2d[LUT_B].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_C].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "A5",
/*lut5_str*/ 0,
&logic_cfg.a2d[LUT_C].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_D].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "((A5))",
/*lut5_str*/ 0,
&logic_cfg.a2d[LUT_D].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_A].flags |= LUT6VAL_SET;
rc = bool_str2u64("~A5", &logic_cfg.a2d[LUT_A].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_B].flags |= LUT6VAL_SET;
rc = bool_str2u64("(A5)", &logic_cfg.a2d[LUT_B].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_C].flags |= LUT6VAL_SET;
rc = bool_str2u64("A5", &logic_cfg.a2d[LUT_C].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_D].flags |= LUT6VAL_SET;
rc = bool_str2u64("((A5))", &logic_cfg.a2d[LUT_D].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_B].out_mux = MUX_F8;
rc = test_logic(tstate, y, x_enum[x_i],
idx_enum[type_i], &logic_cfg);
@ -1843,16 +1847,12 @@ static int test_logic_config(struct test_state* tstate)
// f7amux
CLEAR(logic_cfg);
logic_cfg.a2d[LUT_A].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "~A5",
/*lut5_str*/ 0,
&logic_cfg.a2d[LUT_A].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_B].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A5)",
/*lut5_str*/ 0,
&logic_cfg.a2d[LUT_B].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_A].flags |= LUT6VAL_SET;
rc = bool_str2u64("~A5", &logic_cfg.a2d[LUT_A].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_B].flags |= LUT6VAL_SET;
rc = bool_str2u64("(A5)", &logic_cfg.a2d[LUT_B].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_A].out_mux = MUX_F7;
rc = test_logic(tstate, y, x_enum[x_i],
idx_enum[type_i], &logic_cfg);
@ -1871,16 +1871,12 @@ static int test_logic_config(struct test_state* tstate)
// f7bmux
CLEAR(logic_cfg);
logic_cfg.a2d[LUT_C].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "~A5",
/*lut5_str*/ 0,
&logic_cfg.a2d[LUT_C].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_D].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A5)",
/*lut5_str*/ 0,
&logic_cfg.a2d[LUT_D].lut_val))) FAIL(rc);
logic_cfg.a2d[LUT_C].flags |= LUT6VAL_SET;
rc = bool_str2u64("~A5", &logic_cfg.a2d[LUT_C].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_D].flags |= LUT6VAL_SET;
rc = bool_str2u64("(A5)", &logic_cfg.a2d[LUT_D].lut6_val);
if (rc) FAIL(rc);
logic_cfg.a2d[LUT_C].out_mux = MUX_F7;
rc = test_logic(tstate, y, x_enum[x_i],
idx_enum[type_i], &logic_cfg);
@ -1976,8 +1972,8 @@ fail:
static int test_clock_routing(struct test_state *tstate)
{
int rc, i, t2_io_idx, iob_clk_y, iob_clk_x, iob_clk_type_idx;
int logic_y, logic_x, logic_type_idx;
int y;
int y, logic_y, logic_x, logic_type_idx;
struct fpgadev_logic logic_cfg;
net_idx_t clock_net;
tstate->diff_to_null = 1;
@ -2003,11 +1999,10 @@ static int test_clock_routing(struct test_state *tstate)
logic_x = 13;
logic_type_idx = DEV_LOG_M_OR_L;
fdev_logic_set_lutstr(tstate->model, logic_y, logic_x,
logic_type_idx, LUT_A, /*lut6_str*/ "A1", /*lut5_str*/ 0);
fdev_set_required_pins(tstate->model, logic_y, logic_x,
DEV_LOGIC, logic_type_idx);
CLEAR(logic_cfg);
logic_cfg.a2d[LUT_A].flags |= OUT_USED | LUT6VAL_SET;
bool_str2u64("A1", &logic_cfg.a2d[LUT_A].lut6_val);
fdev_logic_setconf(tstate->model, logic_y, logic_x, logic_type_idx, &logic_cfg);
if (tstate->dry_run)
fdev_print_required_pins(tstate->model,
logic_y, logic_x, DEV_LOGIC, logic_type_idx);
@ -2055,11 +2050,10 @@ static int test_clock_routing(struct test_state *tstate)
logic_type_idx = DEV_LOG_M_OR_L;
logic_y = y-3; // up from hclk
for (logic_x = 13; logic_x <= 26; logic_x += 13) {
fdev_logic_set_lutstr(tstate->model, logic_y, logic_x,
logic_type_idx, LUT_A, /*lut6_str*/ "A1", /*lut5_str*/ 0);
fdev_set_required_pins(tstate->model, logic_y, logic_x,
DEV_LOGIC, logic_type_idx);
CLEAR(logic_cfg);
logic_cfg.a2d[LUT_A].flags |= OUT_USED | LUT6VAL_SET;
bool_str2u64("A1", &logic_cfg.a2d[LUT_A].lut6_val);
fdev_logic_setconf(tstate->model, logic_y, logic_x, logic_type_idx, &logic_cfg);
if (tstate->dry_run)
fdev_print_required_pins(tstate->model,
logic_y, logic_x, DEV_LOGIC, logic_type_idx);
@ -2103,8 +2097,8 @@ static int test_dist_mem(struct test_state *tstate)
CLEAR(logic_cfg);
logic_cfg.we_mux = WEMUX_WE;
logic_cfg.clk_inv = CLKINV_CLK;
logic_cfg.a2d[LUT_D].lut_mode = LUTMODE_RAM;
logic_cfg.a2d[LUT_D].lut_val = 0x00000000000000FF;
logic_cfg.a2d[LUT_D].flags |= LUT6VAL_SET;
logic_cfg.a2d[LUT_D].lut6_val = 0x00000000000000FF;
logic_cfg.a2d[LUT_D].ram_mode = DPRAM64;
rc = test_logic(tstate, y, x, type_i, &logic_cfg);
if (rc) FAIL(rc);
@ -2130,8 +2124,8 @@ static int test_dist_mem(struct test_state *tstate)
logic_cfg.we_mux = WEMUX_WE;
logic_cfg.clk_inv = CLKINV_CLK;
logic_cfg.a2d[lut].lut_mode = LUTMODE_RAM;
logic_cfg.a2d[lut].lut_val = 0x00000000000000FF;
logic_cfg.a2d[lut].flags |= LUT6VAL_SET;
logic_cfg.a2d[lut].lut6_val = 0x00000000000000FF;
logic_cfg.a2d[lut].ram_mode = ram_modes[ram_mode_i];
if (lut != LUT_D
@ -2139,8 +2133,8 @@ static int test_dist_mem(struct test_state *tstate)
|| ram_modes[ram_mode_i] == DPRAM32
|| ram_modes[ram_mode_i] == SPRAM64
|| ram_modes[ram_mode_i] == SPRAM32)) {
logic_cfg.a2d[LUT_D].lut_mode = LUTMODE_RAM;
logic_cfg.a2d[LUT_D].lut_val = 0x00000000000000FF;
logic_cfg.a2d[LUT_D].flags |= LUT6VAL_SET;
logic_cfg.a2d[LUT_D].lut6_val = 0x00000000000000FF;
logic_cfg.a2d[LUT_D].ram_mode = DPRAM64;
}
@ -2154,8 +2148,8 @@ static int test_dist_mem(struct test_state *tstate)
logic_cfg.we_mux = WEMUX_WE;
logic_cfg.clk_inv = CLKINV_CLK;
logic_cfg.a2d[lut].lut_mode = LUTMODE_RAM;
logic_cfg.a2d[lut].lut_val = 0x00000000000000FF;
logic_cfg.a2d[lut].flags |= LUT6VAL_SET;
logic_cfg.a2d[lut].lut6_val = 0x00000000000000FF;
logic_cfg.a2d[lut].ram_mode = SRL32;
for (dimux_i = 0; dimux_i < sizeof(dimux_modes)/sizeof(*dimux_modes);
@ -2175,8 +2169,8 @@ static int test_dist_mem(struct test_state *tstate)
CLEAR(logic_cfg);
logic_cfg.clk_inv = CLKINV_CLK;
logic_cfg.a2d[lut].lut_mode = LUTMODE_ROM;
logic_cfg.a2d[lut].lut_val = 0x00000000000000FF;
logic_cfg.a2d[lut].flags |= LUT6VAL_SET | LUTMODE_ROM;
logic_cfg.a2d[lut].lut6_val = 0x00000000000000FF;
rc = test_logic(tstate, y, x, type_i, &logic_cfg);
if (rc) FAIL(rc);

View File

@ -101,30 +101,30 @@ int main(int argc, char** argv)
}
if (!cur_bit) { // first bit
logic_cfg.precyinit = PRECYINIT_0;
logic_cfg.a2d[LUT_A].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A6+~A6)*(~A5)",
/*lut5_str*/ "1",
&logic_cfg.a2d[LUT_A].lut_val))) RC_FAIL(&model, rc);
logic_cfg.a2d[LUT_A].flags |= LUT5VAL_SET | LUT6VAL_SET;
if ((rc = bool_str2lut_pair(
/*lut6*/ "(A6+~A6)*(~A5)",
/*lut5*/ "1",
&logic_cfg.a2d[LUT_A].lut6_val,
&logic_cfg.a2d[LUT_A].lut5_val))) RC_FAIL(&model, rc);
logic_cfg.a2d[LUT_A].cy0 = CY0_O5;
logic_cfg.a2d[LUT_A].ff = FF_FF;
logic_cfg.a2d[LUT_A].ff_mux = MUX_XOR;
logic_cfg.a2d[LUT_A].ff_srinit = FF_SRINIT0;
} else if (cur_bit == param_highest_bit) {
logic_cfg.a2d[cur_bit%4].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "A5",
/*lut5_str*/ 0,
&logic_cfg.a2d[cur_bit%4].lut_val))) RC_FAIL(&model, rc);
logic_cfg.a2d[cur_bit%4].flags |= LUT6VAL_SET;
if ((rc = bool_str2u64("A5", &logic_cfg.a2d[cur_bit%4].lut6_val)))
RC_FAIL(&model, rc);
logic_cfg.a2d[cur_bit%4].ff = FF_FF;
logic_cfg.a2d[cur_bit%4].ff_mux = MUX_XOR;
logic_cfg.a2d[cur_bit%4].ff_srinit = FF_SRINIT0;
} else {
logic_cfg.a2d[cur_bit%4].lut_mode = LUTMODE_LUT;
if ((rc = lutstr_to_val(
/*lut6_str*/ "(A6+~A6)*(A5)",
/*lut5_str*/ "0",
&logic_cfg.a2d[cur_bit%4].lut_val))) RC_FAIL(&model, rc);
logic_cfg.a2d[cur_bit%4].flags |= LUT5VAL_SET | LUT6VAL_SET;
if ((rc = bool_str2lut_pair(
/*lut6*/ "(A6+~A6)*(A5)",
/*lut5*/ "0",
&logic_cfg.a2d[cur_bit%4].lut6_val,
&logic_cfg.a2d[cur_bit%4].lut5_val))) RC_FAIL(&model, rc);
logic_cfg.a2d[cur_bit%4].cy0 = CY0_O5;
logic_cfg.a2d[cur_bit%4].ff = FF_FF;
logic_cfg.a2d[cur_bit%4].ff_mux = MUX_XOR;

View File

@ -29,7 +29,8 @@ int main(int argc, char** argv)
int iob_inA_y, iob_inA_x, iob_inA_type_idx;
int iob_inB_y, iob_inB_x, iob_inB_type_idx;
int iob_out_y, iob_out_x, iob_out_type_idx;
int logic_y, logic_x, logic_type_idx;
int logic_y, logic_x, logic_type_idx, rc;
struct fpgadev_logic logic_cfg;
net_idx_t inA_net, inB_net, out_net;
fpga_build_model(&model, XC6SLX9, TQG144);
@ -52,8 +53,12 @@ int main(int argc, char** argv)
logic_y = 68;
logic_x = 13;
logic_type_idx = DEV_LOG_X;
fdev_logic_set_lutstr(&model, logic_y, logic_x, logic_type_idx,
LUT_D, /*lut6_str*/ "A3*A5", /*lut5_str*/ 0);
CLEAR(logic_cfg);
logic_cfg.a2d[LUT_D].flags |= OUT_USED | LUT6VAL_SET;
if ((rc = bool_str2u64("A3*A5", &logic_cfg.a2d[LUT_D].lut6_val)))
RC_FAIL(&model, rc);
fdev_logic_setconf(&model, logic_y, logic_x, logic_type_idx, &logic_cfg);
fnet_new(&model, &inA_net);
fnet_add_port(&model, inA_net, iob_inA_y, iob_inA_x,

View File

@ -1189,8 +1189,21 @@ static int extract_logic(struct extract_state* es)
&& cfg_ml.a2d[LUT_A].ff_mux != MUX_XOR
&& cfg_ml.a2d[LUT_A].ff_mux != MUX_CY
&& cfg_ml.a2d[LUT_A].ff_mux != MUX_F7)
cfg_ml.a2d[LUT_A].out_used = 1;
cfg_ml.a2d[LUT_A].lut_val = lut_ML[LUT_A];
cfg_ml.a2d[LUT_A].flags |= OUT_USED;
if (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) {
// lut5/6 pair
cfg_ml.a2d[LUT_A].flags |= LUT6VAL_SET;
cfg_ml.a2d[LUT_A].lut6_val = ULL_HIGH32(lut_ML[LUT_A]);
cfg_ml.a2d[LUT_A].flags |= LUT5VAL_SET;
cfg_ml.a2d[LUT_A].lut5_val = ULL_LOW32(lut_ML[LUT_A]);
} else { // lut6 only
cfg_ml.a2d[LUT_A].flags |= LUT6VAL_SET;
cfg_ml.a2d[LUT_A].lut6_val = lut_ML[LUT_A];
}
}
// ML-B
if (lut_ML[LUT_B]
@ -1204,8 +1217,21 @@ static int extract_logic(struct extract_state* es)
&& 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;
cfg_ml.a2d[LUT_B].lut_val = lut_ML[LUT_B];
cfg_ml.a2d[LUT_B].flags |= OUT_USED;
if (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) {
// lut5/6 pair
cfg_ml.a2d[LUT_B].flags |= LUT6VAL_SET;
cfg_ml.a2d[LUT_B].lut6_val = ULL_HIGH32(lut_ML[LUT_B]);
cfg_ml.a2d[LUT_B].flags |= LUT5VAL_SET;
cfg_ml.a2d[LUT_B].lut5_val = ULL_LOW32(lut_ML[LUT_B]);
} else { // lut6 only
cfg_ml.a2d[LUT_B].flags |= LUT6VAL_SET;
cfg_ml.a2d[LUT_B].lut6_val = lut_ML[LUT_B];
}
}
// ML-C
if (lut_ML[LUT_C]
@ -1219,8 +1245,21 @@ static int extract_logic(struct extract_state* es)
&& 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;
cfg_ml.a2d[LUT_C].lut_val = lut_ML[LUT_C];
cfg_ml.a2d[LUT_C].flags |= OUT_USED;
if (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) {
// lut5/6 pair
cfg_ml.a2d[LUT_C].flags |= LUT6VAL_SET;
cfg_ml.a2d[LUT_C].lut6_val = ULL_HIGH32(lut_ML[LUT_C]);
cfg_ml.a2d[LUT_C].flags |= LUT5VAL_SET;
cfg_ml.a2d[LUT_C].lut5_val = ULL_LOW32(lut_ML[LUT_C]);
} else { // lut6 only
cfg_ml.a2d[LUT_C].flags |= LUT6VAL_SET;
cfg_ml.a2d[LUT_C].lut6_val = lut_ML[LUT_C];
}
}
// ML-D
if (lut_ML[LUT_D]
@ -1234,40 +1273,93 @@ static int extract_logic(struct extract_state* es)
&& 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;
cfg_ml.a2d[LUT_D].lut_val = lut_ML[LUT_D];
cfg_ml.a2d[LUT_D].flags |= OUT_USED;
if (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) {
// lut5/6 pair
cfg_ml.a2d[LUT_D].flags |= LUT6VAL_SET;
cfg_ml.a2d[LUT_D].lut6_val = ULL_HIGH32(lut_ML[LUT_D]);
cfg_ml.a2d[LUT_D].flags |= LUT5VAL_SET;
cfg_ml.a2d[LUT_D].lut5_val = ULL_LOW32(lut_ML[LUT_D]);
} else { // lut6 only
cfg_ml.a2d[LUT_D].flags |= LUT6VAL_SET;
cfg_ml.a2d[LUT_D].lut6_val = lut_ML[LUT_D];
}
}
// 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;
cfg_x.a2d[LUT_A].lut_val = lut_X[LUT_A];
cfg_x.a2d[LUT_A].flags |= OUT_USED;
if (cfg_x.a2d[LUT_A].out_mux) {
// lut5/6 pair
cfg_x.a2d[LUT_A].flags |= LUT6VAL_SET;
cfg_x.a2d[LUT_A].lut6_val = ULL_HIGH32(lut_X[LUT_A]);
cfg_x.a2d[LUT_A].flags |= LUT5VAL_SET;
cfg_x.a2d[LUT_A].lut5_val = ULL_LOW32(lut_X[LUT_A]);
} else { // lut6 only
cfg_x.a2d[LUT_A].flags |= LUT6VAL_SET;
cfg_x.a2d[LUT_A].lut6_val = lut_X[LUT_A];
}
}
// 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;
cfg_x.a2d[LUT_B].lut_val = lut_X[LUT_B];
cfg_x.a2d[LUT_B].flags |= OUT_USED;
if (cfg_x.a2d[LUT_B].out_mux) {
// lut5/6 pair
cfg_x.a2d[LUT_B].flags |= LUT6VAL_SET;
cfg_x.a2d[LUT_B].lut6_val = ULL_HIGH32(lut_X[LUT_B]);
cfg_x.a2d[LUT_B].flags |= LUT5VAL_SET;
cfg_x.a2d[LUT_B].lut5_val = ULL_LOW32(lut_X[LUT_B]);
} else { // lut6 only
cfg_x.a2d[LUT_B].flags |= LUT6VAL_SET;
cfg_x.a2d[LUT_B].lut6_val = lut_X[LUT_B];
}
}
// 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;
cfg_x.a2d[LUT_C].lut_val = lut_X[LUT_C];
cfg_x.a2d[LUT_C].flags |= OUT_USED;
if (cfg_x.a2d[LUT_C].out_mux) {
// lut5/6 pair
cfg_x.a2d[LUT_C].flags |= LUT6VAL_SET;
cfg_x.a2d[LUT_C].lut6_val = ULL_HIGH32(lut_X[LUT_C]);
cfg_x.a2d[LUT_C].flags |= LUT5VAL_SET;
cfg_x.a2d[LUT_C].lut5_val = ULL_LOW32(lut_X[LUT_C]);
} else { // lut6 only
cfg_x.a2d[LUT_C].flags |= LUT6VAL_SET;
cfg_x.a2d[LUT_C].lut6_val = lut_X[LUT_C];
}
}
// 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;
cfg_x.a2d[LUT_D].lut_val = lut_X[LUT_D];
cfg_x.a2d[LUT_D].flags |= OUT_USED;
if (cfg_x.a2d[LUT_D].out_mux) {
// lut5/6 pair
cfg_x.a2d[LUT_D].flags |= LUT6VAL_SET;
cfg_x.a2d[LUT_D].lut6_val = ULL_HIGH32(lut_X[LUT_D]);
cfg_x.a2d[LUT_D].flags |= LUT5VAL_SET;
cfg_x.a2d[LUT_D].lut5_val = ULL_LOW32(lut_X[LUT_D]);
} else { // lut6 only
cfg_x.a2d[LUT_D].flags |= LUT6VAL_SET;
cfg_x.a2d[LUT_D].lut6_val = lut_X[LUT_D];
}
}
//
@ -2937,17 +3029,17 @@ static int write_logic(struct fpga_bits* bits, struct fpga_model* model)
// X device
if (dev_x->instantiated) {
lut_X[LUT_A] = dev_x->u.logic.a2d[LUT_A].lut_val;
lut_X[LUT_B] = dev_x->u.logic.a2d[LUT_B].lut_val;
lut_X[LUT_C] = dev_x->u.logic.a2d[LUT_C].lut_val;
lut_X[LUT_D] = dev_x->u.logic.a2d[LUT_D].lut_val;
fdev_logic_lut_dieval(model, y, x, DEV_LOG_X, LUT_A, &lut_X[LUT_A]);
fdev_logic_lut_dieval(model, y, x, DEV_LOG_X, LUT_B, &lut_X[LUT_B]);
fdev_logic_lut_dieval(model, y, x, DEV_LOG_X, LUT_C, &lut_X[LUT_C]);
fdev_logic_lut_dieval(model, y, x, DEV_LOG_X, LUT_D, &lut_X[LUT_D]);
}
// M or L device
if (dev_ml->instantiated) {
lut_ML[LUT_A] = dev_ml->u.logic.a2d[LUT_A].lut_val;
lut_ML[LUT_B] = dev_ml->u.logic.a2d[LUT_B].lut_val;
lut_ML[LUT_C] = dev_ml->u.logic.a2d[LUT_C].lut_val;
lut_ML[LUT_D] = dev_ml->u.logic.a2d[LUT_D].lut_val;
fdev_logic_lut_dieval(model, y, x, DEV_LOG_M_OR_L, LUT_A, &lut_ML[LUT_A]);
fdev_logic_lut_dieval(model, y, x, DEV_LOG_M_OR_L, LUT_B, &lut_ML[LUT_B]);
fdev_logic_lut_dieval(model, y, x, DEV_LOG_M_OR_L, LUT_C, &lut_ML[LUT_C]);
fdev_logic_lut_dieval(model, y, x, DEV_LOG_M_OR_L, LUT_D, &lut_ML[LUT_D]);
}
//

View File

@ -421,36 +421,23 @@ int fdev_logic_setconf(struct fpga_model *model, int y, int x,
RC_RETURN(model);
}
int fdev_logic_set_lutstr(struct fpga_model *model, int y, int x,
int type_idx, int lut_pos, const char *lut6_str, const char *lut5_str)
{
struct fpga_device *dev;
int rc;
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
RC_ASSERT(model, dev);
rc = lutstr_to_val(lut6_str, lut5_str, &dev->u.logic.a2d[lut_pos].lut_val);
if (rc) RC_FAIL(model, rc);
RC_RETURN(model);
}
int fdev_logic_a2d_out_used(struct fpga_model* model, int y, int x,
int type_idx, int lut_a2d, int used)
{
struct fpga_device* dev;
int rc;
RC_CHECK(model);
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
if (!dev) FAIL(EINVAL);
RC_ASSERT(model, dev);
rc = reset_required_pins(dev);
if (rc) FAIL(rc);
if (rc) RC_FAIL(model, rc);
dev->u.logic.a2d[lut_a2d].out_used = used;
if (used)
dev->u.logic.a2d[lut_a2d].flags |= OUT_USED;
else
dev->u.logic.a2d[lut_a2d].flags &= ~OUT_USED;
dev->instantiated = 1;
return 0;
fail:
return rc;
RC_RETURN(model);
}
int fdev_logic_a2d_ff(struct fpga_model* model, int y, int x, int type_idx,
@ -678,38 +665,23 @@ int fdev_logic_o5_used(struct fpga_model *model, int y, int x, int type_idx,
|| dev->u.logic.a2d[lut_a2d].cy0 == CY0_O5));
}
int fdev_logic_get_lutstr(struct fpga_model *model, int y, int x, int type_idx,
int lut_a2d, const char **lut6_str, const char **lut5_str)
int fdev_logic_lut_dieval(struct fpga_model *model, int y, int x, int type_idx,
int lut_a2d, uint64_t *die_val)
{
static char lut6_buf[MAX_LUT_LEN], lut5_buf[MAX_LUT_LEN];
struct fpga_device *dev;
int lut5_used;
const char *str;
lut6_buf[0] = 0;
lut5_buf[0] = 0;
*lut6_str = lut6_buf;
*lut5_str = lut5_buf;
*die_val = 0;
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
RC_ASSERT(model, dev);
lut5_used = fdev_logic_o5_used(model, y, x, type_idx, lut_a2d);
if (lut5_used) {
// lut6
str = bool_bits2str(ULL_HIGH32(dev->u.logic.a2d[lut_a2d].lut_val), 32);
RC_ASSERT(model, str);
snprintf(lut6_buf, sizeof(lut6_buf), "(A6+~A6)*(%s)", str);
// lut5
str = bool_bits2str(ULL_LOW32(dev->u.logic.a2d[lut_a2d].lut_val), 32);
RC_ASSERT(model, str);
strcpy(lut5_buf, str);
} else {
str = bool_bits2str(dev->u.logic.a2d[lut_a2d].lut_val, 64);
RC_ASSERT(model, str);
strcpy(lut6_buf, str);
}
if (dev->u.logic.a2d[lut_a2d].flags & LUT5VAL_SET) {
*die_val = dev->u.logic.a2d[lut_a2d].lut5_val;
if (dev->u.logic.a2d[lut_a2d].flags & LUT6VAL_SET) {
if (ULL_HIGH32(dev->u.logic.a2d[lut_a2d].lut6_val))
HERE();
*die_val |= ULL_LOW32(dev->u.logic.a2d[lut_a2d].lut6_val << 32);
}
} else if (dev->u.logic.a2d[lut_a2d].flags & LUT6VAL_SET)
*die_val = dev->u.logic.a2d[lut_a2d].lut6_val;
RC_RETURN(model);
}
@ -906,7 +878,7 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
if (dev->u.logic.wa8_used)
add_req_inpin(dev, LI_BX);
for (i = LUT_A; i <= LUT_D; i++) {
if (dev->u.logic.a2d[i].out_used) {
if (dev->u.logic.a2d[i].flags & OUT_USED) {
// LO_A..LO_D are in sequence
add_req_outpin(dev, LO_A+i);
}
@ -927,21 +899,21 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
for (j = 0; j < 6; j++)
req_inpins[j] = 0;
if (fdev_logic_o5_used(model, y, x, type_idx, i)) {
if (dev->u.logic.a2d[i].flags & LUT5VAL_SET) {
// A6 must be high/vcc if lut5 is used
req_inpins[5] = 1;
for (j = 0; j < 32; j++) {
if (!(dev->u.logic.a2d[i].lut_val & (1ULL << j))
&& !(dev->u.logic.a2d[i].lut_val & (1ULL << (32+j))))
if (!(dev->u.logic.a2d[i].lut5_val & (1ULL << j)))
continue;
for (k = 0; k < 5; k++) {
if (j & (1<<k))
req_inpins[k] = 1;
}
}
} else {
}
if (dev->u.logic.a2d[i].flags & LUT6VAL_SET) {
for (j = 0; j < 64; j++) {
if (!(dev->u.logic.a2d[i].lut_val & (1ULL << j)))
if (!(dev->u.logic.a2d[i].lut6_val & (1ULL << j)))
continue;
for (k = 0; k < 6; k++) {
if (j & (1<<k))

View File

@ -54,8 +54,6 @@ str16_t fdev_logic_pinstr_i(struct fpga_model* model, pinw_idx_t idx, int ld1_ty
int fdev_logic_setconf(struct fpga_model* model, int y, int x,
int type_idx, const struct fpgadev_logic* logic_cfg);
int fdev_logic_set_lutstr(struct fpga_model *model, int y, int x,
int type_idx, int lut_pos, const char *lut6_str, const char *lut5_str);
// lut_a2d is LUT_A to LUT_D
int fdev_logic_a2d_out_used(struct fpga_model* model, int y, int x,
@ -91,8 +89,8 @@ int fdev_logic_precyinit(struct fpga_model* model, int y, int x,
// fdev_logic_o5_used() returns no error code, only 0 or 1
int fdev_logic_o5_used(struct fpga_model *model, int y, int x, int type_idx,
int lut_a2d);
int fdev_logic_get_lutstr(struct fpga_model *model, int y, int x, int type_idx,
int lut_a2d, const char **lut6_str, const char **lut5_str);
int fdev_logic_lut_dieval(struct fpga_model *model, int y, int x, int type_idx,
int lut_a2d, uint64_t *die_val);
int fdev_iob_input(struct fpga_model* model, int y, int x,
int type_idx, const char* io_std);

View File

@ -286,6 +286,7 @@ int printf_LOGIC(FILE* f, struct fpga_model* model,
struct fpga_tile *tile;
struct fpgadev_logic *cfg;
char pref[256];
const char *str;
int dev_i, j;
dev_i = fpga_dev_idx(model, y, x, DEV_LOGIC, type_idx);
@ -312,26 +313,45 @@ int printf_LOGIC(FILE* f, struct fpga_model* model,
cfg = &tile->devs[dev_i].u.logic;
for (j = LUT_D; j >= LUT_A; j--) {
switch (cfg->a2d[j].lut_mode) {
case LUTMODE_LUT:
fprintf(f, "%s %c_mode LUT\n", pref, 'A'+j);
// todo: A6_lut_str, A5_lut_str
break;
case LUTMODE_ROM:
fprintf(f, "%s %c_mode ROM\n", pref, 'A'+j);
fprintf(f, "%s %c_val 0x%016lX\n", pref, 'A'+j, cfg->a2d[j].lut_val);
// todo: A6_lut_val, A5_lut_val ?
break;
case LUTMODE_RAM:
fprintf(f, "%s %c_mode RAM\n", pref, 'A'+j);
fprintf(f, "%s %c_val 0x%016lX\n", pref, 'A'+j, cfg->a2d[j].lut_val);
break;
default: RC_FAIL(model, EINVAL);
int print_hex_vals =
cfg->a2d[j].ram_mode || cfg->a2d[j].flags & LUTMODE_ROM;
if (cfg->a2d[j].flags & LUT5VAL_SET) {
if (cfg->a2d[j].flags & LUT6VAL_SET) {
RC_ASSERT(model, !ULL_HIGH32(cfg->a2d[j].lut6_val));
if (print_hex_vals)
fprintf(f, "%s %c6_lut_val 0x%016lX\n",
pref, 'A'+j, cfg->a2d[j].lut6_val);
else {
str = bool_bits2str(cfg->a2d[j].lut6_val, 32);
RC_ASSERT(model, str);
fprintf(f, "%s %c6_lut_str (A6+~A6)*(%s)\n",
pref, 'A'+j, str);
}
}
if (print_hex_vals)
fprintf(f, "%s %c5_lut_val 0x%08X\n",
pref, 'A'+j, ULL_LOW32(cfg->a2d[j].lut5_val));
else {
str = bool_bits2str(cfg->a2d[j].lut5_val, 32);
RC_ASSERT(model, str);
fprintf(f, "%s %c5_lut_str %s\n",
pref, 'A'+j, str);
}
} else {
if (cfg->a2d[j].flags & LUT6VAL_SET) {
if (print_hex_vals)
fprintf(f, "%s %c6_lut_val 0x%016lX\n",
pref, 'A'+j, cfg->a2d[j].lut6_val);
else {
str = bool_bits2str(cfg->a2d[j].lut6_val, 64);
RC_ASSERT(model, str);
fprintf(f, "%s %c6_lut_str %s\n",
pref, 'A'+j, str);
}
}
}
if (cfg->a2d[j].out_used)
if (cfg->a2d[j].flags & OUT_USED)
fprintf(f, "%s %c_used\n", pref, 'A'+j);
switch (cfg->a2d[j].ff) {
case FF_OR2L:
fprintf(f, "%s %c_ff OR2L\n", pref, 'A'+j);
@ -525,7 +545,7 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
char cmp_str[128], buf[32];
char *endptr;
uint64_t val;
int i, j;
int i, j, rc;
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
if (!dev) { HERE(); return 0; }
@ -534,7 +554,7 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
for (i = LUT_A; i <= LUT_D; i++) {
snprintf(cmp_str, sizeof(cmp_str), "%c_used", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
dev->u.logic.a2d[i].out_used = 1;
dev->u.logic.a2d[i].flags |= OUT_USED;
goto inst_1;
}
}
@ -565,20 +585,67 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
return 2; // no reason for instantiation
for (i = LUT_A; i <= LUT_D; i++) {
#if 0
snprintf(cmp_str, sizeof(cmp_str), "%c6_lut_str", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
rc = fdev_logic_a2d_lut(model, y, x, type_idx, i, 6, w2, w2_len);
if (rc) return 0;
rc = bool_str2bits(w2, w2_len, &val, 64);
if (rc) { HERE(); return 0; }
dev->u.logic.a2d[i].lut6_val = val;
dev->u.logic.a2d[i].flags |= LUT6VAL_SET;
goto inst_2;
}
snprintf(cmp_str, sizeof(cmp_str), "%c5_lut_str", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
rc = fdev_logic_a2d_lut(model, y, x, type_idx, i, 5, w2, w2_len);
if (rc) return 0;
rc = bool_str2bits(w2, w2_len, &val, 32);
if (rc) { HERE(); return 0; }
dev->u.logic.a2d[i].lut5_val = val;
dev->u.logic.a2d[i].flags |= LUT5VAL_SET;
goto inst_2;
}
snprintf(cmp_str, sizeof(cmp_str), "%c6_lut_val", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
if (w2_len < 3
|| w2[0] != '0'
|| (w2[1] != 'x' && w2[1] != 'X')
|| w2_len > 2+16) { HERE(); return 0; }
errno = 0;
for (j = 2; j < w2_len; j++)
buf[j-2] = w2[j];
buf[j-2] = 0;
val = strtoull(buf, &endptr, /*base*/ 16);
if (errno || *endptr) {
fprintf(stderr, "#E %s:%i errno %i endptr '%s'\n",
__FILE__, __LINE__, errno, endptr);
return 0;
}
dev->u.logic.a2d[i].lut6_val = val;
dev->u.logic.a2d[i].flags |= LUT6VAL_SET;
if (!dev->u.logic.a2d[i].ram_mode)
dev->u.logic.a2d[i].flags |= LUTMODE_ROM;
goto inst_2;
}
snprintf(cmp_str, sizeof(cmp_str), "%c5_lut_val", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
if (w2_len < 3
|| w2[0] != '0'
|| (w2[1] != 'x' && w2[1] != 'X')
|| w2_len > 2+8) { HERE(); return 0; }
errno = 0;
for (j = 2; j < w2_len; j++)
buf[j-2] = w2[j];
buf[j-2] = 0;
val = strtoul(buf, &endptr, /*base*/ 16);
if (errno || *endptr) {
fprintf(stderr, "#E %s:%i errno %i endptr '%s'\n",
__FILE__, __LINE__, errno, endptr);
return 0;
}
dev->u.logic.a2d[i].lut5_val = val;
dev->u.logic.a2d[i].flags |= LUT5VAL_SET;
if (!dev->u.logic.a2d[i].ram_mode)
dev->u.logic.a2d[i].flags |= LUTMODE_ROM;
goto inst_2;
}
#endif
snprintf(cmp_str, sizeof(cmp_str), "%c_ffmux", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
if (!str_cmp(w2, w2_len, "O6", ZTERM))
@ -676,46 +743,10 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
else if (!str_cmp(w2, w2_len, "SRL16", ZTERM))
dev->u.logic.a2d[i].ram_mode = SRL16;
else return 0;
if (dev->u.logic.a2d[i].flags & LUTMODE_ROM)
dev->u.logic.a2d[i].flags &= ~LUTMODE_ROM;
goto inst_2;
}
snprintf(cmp_str, sizeof(cmp_str), "%c6_lut_val", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
if (w2_len < 3
|| w2[0] != '0'
|| (w2[1] != 'x' && w2[1] != 'X')
|| w2_len > 2+16) { HERE(); return 0; }
errno = 0;
for (j = 2; j < w2_len; j++)
buf[j-2] = w2[j];
buf[j-2] = 0;
val = strtoull(buf, &endptr, /*base*/ 16);
if (errno || *endptr) {
fprintf(stderr, "#E %s:%i errno %i endptr '%s'\n",
__FILE__, __LINE__, errno, endptr);
return 0;
}
dev->u.logic.a2d[i].lut_val = val;
goto inst_2;
}
#if 0
snprintf(cmp_str, sizeof(cmp_str), "%c5_lut_val", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
if (w2_len < 3
|| w2[0] != '0'
|| (w2[1] != 'x' && w2[1] != 'X')
|| w2_len > 2+8) return 0;
errno = 0;
for (j = 2; j < w2_len; j++)
buf[j-2] = w2[j];
buf[j-2] = 0;
val = strtoul(buf, &endptr, /*base*/ 16);
if (errno || *endptr) return 0;
dev->u.logic.a2d[i].lut5_val = val;
dev->u.logic.a2d[i].flags |= LUT5VAL_SET;
goto inst_2;
}
#endif
snprintf(cmp_str, sizeof(cmp_str), "%c_di_mux", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
if (!str_cmp(w2, w2_len, "MC31", ZTERM))
@ -1380,8 +1411,8 @@ static void read_dev_line(struct fpga_model* model, const char* line, int start)
return;
}
if (!words_consumed)
fprintf(stderr, "error %i w1 %.*s w2 %.*s: %s",
__LINE__, next_end-next_beg, &line[next_beg],
fprintf(stderr, "#E %s:%i w1 %.*s w2 %.*s: %s",
__FILE__, __LINE__, next_end-next_beg, &line[next_beg],
second_end-second_beg, &line[second_beg], line);
else if (words_consumed == 2)
next_end = second_end;

View File

@ -194,9 +194,35 @@ uint64_t map_bits(uint64_t u64, int num_bits, int *src_pos)
return result;
}
int bool_str2bits(const char *str, uint64_t *u64, int num_bits)
int bool_str2u64(const char *str, uint64_t *u64)
{
int i, j, bool_res, rc, str_len, vars[6];
return bool_str2bits(str, ZTERM, u64, 64);
}
int bool_str2u32(const char *str, uint32_t *u32)
{
uint64_t v;
int rc;
rc = bool_str2bits(str, ZTERM, &v, 32);
*u32 = ULL_LOW32(v);
return rc;
}
int bool_str2lut_pair(const char *str6, const char *str5, uint64_t *lut6_val, uint32_t *lut5_val)
{
int rc;
*lut6_val = 0; // needed to zero upper 32 bits
rc = bool_str2bits(str6, ZTERM, lut6_val, 32);
if (rc) return rc;
rc = bool_str2u32(str5, lut5_val);
if (rc) return rc;
return 0;
}
int bool_str2bits(const char *str, int str_len, uint64_t *u64, int num_bits)
{
int i, j, bool_res, rc, vars[6];
if (num_bits == 64)
*u64 = 0;
@ -204,7 +230,8 @@ int bool_str2bits(const char *str, uint64_t *u64, int num_bits)
*u64 &= 0xFFFFFFFF00000000;
else FAIL(EINVAL);
str_len = strlen(str);
if (str_len == ZTERM)
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;
@ -343,29 +370,6 @@ const char* bool_bits2str(uint64_t u64, int num_bits)
return str;
}
int lutstr_to_val(const char *lut6_str, const char *lut5_str, uint64_t *val)
{
int rc;
*val = 0;
if (lut5_str && *lut5_str) {
if (lut6_str && lut6_str[0]) {
rc = bool_str2bits(lut6_str, val, 32);
if (rc) FAIL(rc);
*val <<= 32;
}
rc = bool_str2bits(lut5_str, val, 32);
if (rc) FAIL(rc);
} else {
// lut6 only
rc = bool_str2bits(lut6_str, val, 64);
if (rc) FAIL(rc);
}
return 0;
fail:
return rc;
}
void printf_type2(uint8_t *d, int len, int inpos, int num_entries)
{
uint64_t u64;

View File

@ -66,10 +66,12 @@ 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* 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 lutstr_to_val(const char *lut6_str, const char *lut5_str, uint64_t *val);
int bool_str2u64(const char *str, uint64_t *u64);
int bool_str2u32(const char *str, uint32_t *u32);
int bool_str2lut_pair(const char *str6, const char *str5, uint64_t *lut6_val, uint32_t *lut5_val);
int bool_str2bits(const char* str, int str_len, uint64_t* u64, int num_bits);
const char* bool_bits2str(uint64_t u64, int num_bits);
void printf_type2(uint8_t* d, int len, int inpos, int num_entries);
void printf_ramb16_data(uint8_t* bits, int inpos);

View File

@ -417,6 +417,10 @@ enum {
enum { LUT_A = 0, LUT_B, LUT_C, LUT_D }; // offset into a2d[]
enum { LUTMODE_LUT = 1, LUTMODE_ROM, LUTMODE_RAM };
#define OUT_USED 0x0001
#define LUT5VAL_SET 0x0002
#define LUT6VAL_SET 0x0004
#define LUTMODE_ROM 0x0008
enum { FF_SRINIT0 = 1, FF_SRINIT1 };
enum { MUX_O6 = 1, MUX_O5, MUX_5Q, MUX_X, MUX_CY, MUX_XOR, MUX_F7, MUX_F8, MUX_MC31 };
enum { FF_OR2L = 1, FF_AND2L, FF_LATCH, FF_FF };
@ -433,15 +437,24 @@ enum { DIMUX_MC31 = 1, DIMUX_X, DIMUX_DX, DIMUX_BDI1 };
struct fpgadev_logic_a2d
{
// lut_mode should always be set for a used lut.
// The lut can be in one of 3 modes: LUT, ROM, RAM.
// ROM and LUT are almost identical, RAM is a completely
// different mode for the entire slice (M only).
// By default, the lut is in LUT mode. If LUTMODE_ROM is
// set, it's ROM (and the lut values are stored as hexadecimals
// in the floorplan). If ram_mode != 0, the lut is in RAM mode
// (and the lut values are stored in hex as well).
// In LUT or ROM mode, DI1/DI2, MC31 and WA1..WA8
// should not be connected.
int lut_mode; // LUTMODE_LUT, LUTMODE_ROM, LUTMODE_RAM
int flags; // OUT_USED, LUT6VAL_SET, LUT5VAL_SET, LUTMODE_ROM
// If A6 is high/vcc, only the lower 32-bits of lut6_val are
// used (and they are stored in the upper 32-bits on the die).
// In that case, lut5_val (if set) contains an independent
// value that defines O5.
uint64_t lut6_val; // only valid if LUT6VAL_SET
uint32_t lut5_val; // only valid if LUT5VAL_SET and A6 is high/vcc
uint64_t lut_val;
int out_used;
int ff_mux; // O6, O5, X, F7(a/c), F8(b), MC31(d), CY, XOR
int ff_srinit; // SRINIT0, SRINIT1
int ff5_srinit; // SRINIT0, SRINIT1
@ -449,7 +462,7 @@ struct fpgadev_logic_a2d
int ff; // OR2L, AND2L, LATCH, FF
int cy0; // X, O5
// Requirements for LUTMODE_RAM:
// Requirements for functioning ram:
// - input on CLK and WE pins
// - SRL32 and SRL16 should have O6 or MC31 output
// - MC31 is only driven in SRL32 or SRL16 mode.
@ -461,7 +474,7 @@ 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.
int ram_mode; // only with LUTMODE_RAM
int ram_mode; // if set, the lut is in RAM mode
// DPRAM64, DPRAM32, SPRAM64, SPRAM32, SRL32, SRL16
int di_mux; // only for A-C
// DIMUX_MC31, DIMUX_X, DIMUX_DX (b/c), DIMUX_BDI1 (a)