diff --git a/README b/README index c9fe2ac..8514117 100644 --- a/README +++ b/README @@ -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 diff --git a/autotest.c b/autotest.c index 3c82230..ef66e78 100644 --- a/autotest.c +++ b/autotest.c @@ -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); diff --git a/blinking_led.c b/blinking_led.c index 8bdeaae..a684647 100644 --- a/blinking_led.c +++ b/blinking_led.c @@ -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; diff --git a/hello_world.c b/hello_world.c index 9c7e696..a5734cd 100644 --- a/hello_world.c +++ b/hello_world.c @@ -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, diff --git a/libs/bit_frames.c b/libs/bit_frames.c index 9f2ab80..968d6ab 100644 --- a/libs/bit_frames.c +++ b/libs/bit_frames.c @@ -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]); } // diff --git a/libs/control.c b/libs/control.c index 4107d6b..78a46cf 100644 --- a/libs/control.c +++ b/libs/control.c @@ -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<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<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; diff --git a/libs/helper.c b/libs/helper.c index 55b3357..1602d8c 100644 --- a/libs/helper.c +++ b/libs/helper.c @@ -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<