cleanup logic device config vars
This commit is contained in:
parent
cc1cd89564
commit
a6aa341772
318
autotest.c
318
autotest.c
|
@ -548,8 +548,8 @@ 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_a2d_lut(tstate->model, y, x,
|
||||
DEV_LOG_M_OR_L, LUT_A, 6, pf("A%c", i), ZTERM);
|
||||
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);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fdev_set_required_pins(tstate->model, y, x,
|
||||
DEV_LOGIC, DEV_LOG_M_OR_L);
|
||||
|
@ -649,8 +649,8 @@ 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_a2d_lut(tstate->model, y, x,
|
||||
idx_enum[i], j, 6, pf("A%c", k), ZTERM);
|
||||
rc = fdev_logic_set_lutstr(tstate->model, y, x,
|
||||
idx_enum[i], j, /*lut6_str*/ pf("A%c", k), /*lut5_str*/ 0);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
if (!r)
|
||||
|
@ -666,8 +666,8 @@ static int test_routing_switches(struct test_state* tstate)
|
|||
}
|
||||
|
||||
// A1->O6->FF->AQ (same for lut B-D)
|
||||
rc = fdev_logic_a2d_lut(tstate->model, y, x,
|
||||
idx_enum[i], j, 6, "A1", ZTERM);
|
||||
rc = fdev_logic_set_lutstr(tstate->model, y, x,
|
||||
idx_enum[i], j, /*lut6_str*/ "A1", /*lut5_str*/ 0);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fdev_logic_a2d_ff(tstate->model, y, x, idx_enum[i],
|
||||
j, MUX_O6, FF_SRINIT0);
|
||||
|
@ -1104,17 +1104,13 @@ static int test_logic(struct test_state* tstate, int y, int x, int type_idx,
|
|||
}
|
||||
}
|
||||
if ((dev->pinw_req_for_cfg[i] == LI_A6
|
||||
&& dev->u.logic.a2d[LUT_A].lut5_str
|
||||
&& *dev->u.logic.a2d[LUT_A].lut5_str)
|
||||
&& fdev_logic_o5_used(tstate->model, y, x, type_idx, LUT_A))
|
||||
|| (dev->pinw_req_for_cfg[i] == LI_B6
|
||||
&& dev->u.logic.a2d[LUT_B].lut5_str
|
||||
&& *dev->u.logic.a2d[LUT_B].lut5_str)
|
||||
&& fdev_logic_o5_used(tstate->model, y, x, type_idx, LUT_B))
|
||||
|| (dev->pinw_req_for_cfg[i] == LI_C6
|
||||
&& dev->u.logic.a2d[LUT_C].lut5_str
|
||||
&& *dev->u.logic.a2d[LUT_C].lut5_str)
|
||||
&& fdev_logic_o5_used(tstate->model, y, x, type_idx, LUT_C))
|
||||
|| (dev->pinw_req_for_cfg[i] == LI_D6
|
||||
&& dev->u.logic.a2d[LUT_D].lut5_str
|
||||
&& *dev->u.logic.a2d[LUT_D].lut5_str)
|
||||
&& fdev_logic_o5_used(tstate->model, y, x, type_idx, LUT_D))
|
||||
|| (latch_logic
|
||||
&& (dev->pinw_req_for_cfg[i] == LI_CLK
|
||||
|| dev->pinw_req_for_cfg[i] == LI_CE))) {
|
||||
|
@ -1227,7 +1223,7 @@ static int test_lut_encoding(struct test_state* tstate)
|
|||
int y, x_i, i, j, lut_str_len, rc;
|
||||
struct fpgadev_logic logic_cfg;
|
||||
int type_i, lut;
|
||||
char lut6_str[128], lut5_str[128];
|
||||
char lut_str[MAX_LUT_LEN];
|
||||
|
||||
tstate->diff_to_null = 1;
|
||||
y = 68;
|
||||
|
@ -1237,42 +1233,51 @@ 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].lut6_str = lut6_str;
|
||||
logic_cfg.a2d[lut].flags |= OUT_USED;
|
||||
logic_cfg.a2d[lut].lut_mode = LUTMODE_LUT;
|
||||
logic_cfg.a2d[lut].out_used = 1;
|
||||
|
||||
// lut6 only
|
||||
sprintf(lut6_str, "0");
|
||||
rc = lutstr_to_val(/*lut6_str*/ "0", /*lut5_str*/ 0, &logic_cfg.a2d[lut].lut_val);
|
||||
if (rc) FAIL(rc);
|
||||
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
|
||||
&logic_cfg);
|
||||
if (rc) FAIL(rc);
|
||||
sprintf(lut6_str, "1");
|
||||
|
||||
rc = lutstr_to_val(/*lut6_str*/ "1", /*lut5_str*/ 0, &logic_cfg.a2d[lut].lut_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++) {
|
||||
sprintf(lut6_str, "A%c", i);
|
||||
rc = lutstr_to_val(/*lut6_str*/ pf("A%c", i),
|
||||
/*lut5_str*/ 0, &logic_cfg.a2d[lut].lut_val);
|
||||
if (rc) FAIL(rc);
|
||||
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
|
||||
&logic_cfg);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
|
||||
// lut6 and lut5 pairs
|
||||
logic_cfg.a2d[lut].lut5_str = lut5_str;
|
||||
logic_cfg.a2d[lut].out_mux = MUX_O5;
|
||||
|
||||
sprintf(lut6_str, "(A6+~A6)*1");
|
||||
sprintf(lut5_str, "0");
|
||||
rc = lutstr_to_val(/*lut6_str*/ "(A6+~A6)*1",
|
||||
/*lut5_str*/ "0", &logic_cfg.a2d[lut].lut_val);
|
||||
if (rc) FAIL(rc);
|
||||
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
|
||||
&logic_cfg);
|
||||
if (rc) FAIL(rc);
|
||||
sprintf(lut6_str, "(A6+~A6)*0");
|
||||
sprintf(lut5_str, "1");
|
||||
|
||||
rc = lutstr_to_val(/*lut6_str*/ "(A6+~A6)*0",
|
||||
/*lut5_str*/ "1", &logic_cfg.a2d[lut].lut_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++) {
|
||||
sprintf(lut5_str, "A%c", i);
|
||||
sprintf(lut6_str, "(A6+~A6)*A%c", (i == '5') ? '1' : i+1);
|
||||
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);
|
||||
if (rc) FAIL(rc);
|
||||
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
|
||||
&logic_cfg);
|
||||
if (rc) FAIL(rc);
|
||||
|
@ -1286,20 +1291,25 @@ 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].lut6_str = lut6_str;
|
||||
logic_cfg.a2d[lut].flags |= OUT_USED;
|
||||
logic_cfg.a2d[lut].lut_mode = LUTMODE_LUT;
|
||||
logic_cfg.a2d[lut].out_used = 1;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
lut_str_len = 0;
|
||||
for (j = 0; j < 6; j++) {
|
||||
if (lut_str_len)
|
||||
lut6_str[lut_str_len++] = '*';
|
||||
lut_str[lut_str_len++] = '*';
|
||||
if (!(i & (1<<j)))
|
||||
lut6_str[lut_str_len++] = '~';
|
||||
lut6_str[lut_str_len++] = 'A';
|
||||
lut6_str[lut_str_len++] = '1' + j;
|
||||
lut_str[lut_str_len++] = '~';
|
||||
lut_str[lut_str_len++] = 'A';
|
||||
lut_str[lut_str_len++] = '1' + j;
|
||||
}
|
||||
lut6_str[lut_str_len] = 0;
|
||||
lut_str[lut_str_len] = 0;
|
||||
rc = lutstr_to_val(
|
||||
/*lut6_str*/ lut_str,
|
||||
/*lut5_str*/ 0,
|
||||
&logic_cfg.a2d[lut].lut_val);
|
||||
if (rc) FAIL(rc);
|
||||
rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i],
|
||||
&logic_cfg);
|
||||
if (rc) FAIL(rc);
|
||||
|
@ -1310,39 +1320,46 @@ 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].lut6_str = lut6_str;
|
||||
logic_cfg.a2d[LUT_A].lut5_str = lut5_str;
|
||||
logic_cfg.a2d[LUT_A].flags |= OUT_USED;
|
||||
logic_cfg.a2d[LUT_A].lut_mode = LUTMODE_LUT;
|
||||
logic_cfg.a2d[LUT_A].out_used = 1;
|
||||
logic_cfg.a2d[LUT_A].out_mux = MUX_O5;
|
||||
// 32 bits in lut5 with lut6=0
|
||||
for (i = 0; i < 32; i++) {
|
||||
lut_str_len = 0;
|
||||
for (j = 0; j < 5; j++) {
|
||||
if (lut_str_len)
|
||||
lut5_str[lut_str_len++] = '*';
|
||||
lut_str[lut_str_len++] = '*';
|
||||
if (!(i & (1<<j)))
|
||||
lut5_str[lut_str_len++] = '~';
|
||||
lut5_str[lut_str_len++] = 'A';
|
||||
lut5_str[lut_str_len++] = '1' + j;
|
||||
lut_str[lut_str_len++] = '~';
|
||||
lut_str[lut_str_len++] = 'A';
|
||||
lut_str[lut_str_len++] = '1' + j;
|
||||
}
|
||||
lut5_str[lut_str_len] = 0;
|
||||
strcpy(lut6_str, "(A6+~A6)*0");
|
||||
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);
|
||||
if (rc) FAIL(rc);
|
||||
rc = test_logic(tstate, y, /*XM*/ 13, DEV_LOG_M_OR_L, &logic_cfg);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
// 32 bits in lut6 with lut5=0
|
||||
for (i = 0; i < 32; i++) {
|
||||
strcpy(lut6_str, "(A6+~A6)");
|
||||
lut_str_len = strlen(lut6_str);
|
||||
strcpy(lut_str, "(A6+~A6)");
|
||||
lut_str_len = strlen(lut_str);
|
||||
for (j = 0; j < 5; j++) {
|
||||
lut6_str[lut_str_len++] = '*';
|
||||
lut_str[lut_str_len++] = '*';
|
||||
if (!(i & (1<<j)))
|
||||
lut6_str[lut_str_len++] = '~';
|
||||
lut6_str[lut_str_len++] = 'A';
|
||||
lut6_str[lut_str_len++] = '1' + j;
|
||||
lut_str[lut_str_len++] = '~';
|
||||
lut_str[lut_str_len++] = 'A';
|
||||
lut_str[lut_str_len++] = '1' + j;
|
||||
}
|
||||
lut6_str[lut_str_len] = 0;
|
||||
strcpy(lut5_str, "0");
|
||||
lut_str[lut_str_len] = 0;
|
||||
rc = lutstr_to_val(
|
||||
/*lut6_str*/ lut_str,
|
||||
/*lut5_str*/ "0",
|
||||
&logic_cfg.a2d[LUT_A].lut_val);
|
||||
if (rc) FAIL(rc);
|
||||
rc = test_logic(tstate, y, /*XM*/ 13, DEV_LOG_M_OR_L, &logic_cfg);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
|
@ -1352,8 +1369,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].lut6_val = 1ULL << i;
|
||||
logic_cfg.a2d[LUT_A].flags |= LUT6VAL_SET | LUTMODE_ROM2;
|
||||
logic_cfg.a2d[LUT_A].lut_mode = LUTMODE_ROM;
|
||||
logic_cfg.a2d[LUT_A].lut_val = 1ULL << i;
|
||||
rc = test_logic(tstate, y, /*XM*/ 13, DEV_LOG_M_OR_L,
|
||||
&logic_cfg);
|
||||
if (rc) FAIL(rc);
|
||||
|
@ -1363,8 +1380,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].lut6_val = 1ULL << i;
|
||||
logic_cfg.a2d[LUT_D].flags |= LUT6VAL_SET;
|
||||
logic_cfg.a2d[LUT_D].lut_mode = LUTMODE_RAM;
|
||||
logic_cfg.a2d[LUT_D].lut_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);
|
||||
|
@ -1397,8 +1414,12 @@ static int test_logic_config(struct test_state* tstate)
|
|||
|
||||
// lut6, direct-out
|
||||
CLEAR(logic_cfg);
|
||||
logic_cfg.a2d[lut].lut6_str = "A1";
|
||||
logic_cfg.a2d[lut].flags |= OUT_USED;
|
||||
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;
|
||||
|
||||
rc = test_logic(tstate, y, x_enum[x_i],
|
||||
idx_enum[type_i], &logic_cfg);
|
||||
|
@ -1409,7 +1430,11 @@ 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].lut6_str = "A1";
|
||||
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_mux = MUX_O6;
|
||||
|
||||
rc = test_logic(tstate, y, x_enum[x_i],
|
||||
|
@ -1448,7 +1473,11 @@ static int test_logic_config(struct test_state* tstate)
|
|||
|
||||
// lut6, ff-out
|
||||
CLEAR(logic_cfg);
|
||||
logic_cfg.a2d[lut].lut6_str = "A1";
|
||||
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].ff = FF_FF;
|
||||
logic_cfg.a2d[lut].ff_mux = MUX_O6;
|
||||
logic_cfg.a2d[lut].ff_srinit = FF_SRINIT0;
|
||||
|
@ -1491,7 +1520,11 @@ static int test_logic_config(struct test_state* tstate)
|
|||
|
||||
// lut6, latch-out
|
||||
CLEAR(logic_cfg);
|
||||
logic_cfg.a2d[lut].lut6_str = "A1";
|
||||
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].ff = FF_LATCH;
|
||||
logic_cfg.a2d[lut].ff_mux = MUX_O6;
|
||||
logic_cfg.a2d[lut].ff_srinit = FF_SRINIT0;
|
||||
|
@ -1515,7 +1548,11 @@ static int test_logic_config(struct test_state* tstate)
|
|||
|
||||
// lut6, and-latch
|
||||
CLEAR(logic_cfg);
|
||||
logic_cfg.a2d[lut].lut6_str = "A1";
|
||||
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].ff = FF_AND2L;
|
||||
logic_cfg.a2d[lut].ff_mux = MUX_O6;
|
||||
// AND2L requires SRINIT=0
|
||||
|
@ -1532,7 +1569,11 @@ static int test_logic_config(struct test_state* tstate)
|
|||
|
||||
// lut6, or-latch
|
||||
CLEAR(logic_cfg);
|
||||
logic_cfg.a2d[lut].lut6_str = "A1";
|
||||
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].ff = FF_OR2L;
|
||||
logic_cfg.a2d[lut].ff_mux = MUX_O6;
|
||||
// OR2L requires SRINIT=1
|
||||
|
@ -1560,12 +1601,16 @@ static int test_logic_config(struct test_state* tstate)
|
|||
if (rc) FAIL(rc);
|
||||
|
||||
// . o6-direct
|
||||
logic_cfg.a2d[lut].lut6_str = "A1";
|
||||
logic_cfg.a2d[lut].flags |= OUT_USED;
|
||||
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;
|
||||
rc = test_logic(tstate, y, x_enum[x_i],
|
||||
idx_enum[type_i], &logic_cfg);
|
||||
if (rc) FAIL(rc);
|
||||
logic_cfg.a2d[lut].flags |= OUT_USED;
|
||||
logic_cfg.a2d[lut].out_used = 1;
|
||||
|
||||
if (idx_enum[type_i] == DEV_LOG_M_OR_L) {
|
||||
// . o6-outmux
|
||||
|
@ -1582,9 +1627,12 @@ static int test_logic_config(struct test_state* tstate)
|
|||
|
||||
// lut6 direct-out, lut5 mux-out
|
||||
CLEAR(logic_cfg);
|
||||
logic_cfg.a2d[lut].lut6_str = "(A6+~A6)*A1";
|
||||
logic_cfg.a2d[lut].flags |= OUT_USED;
|
||||
logic_cfg.a2d[lut].lut5_str = "A1*A2";
|
||||
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].out_mux = MUX_O5;
|
||||
rc = test_logic(tstate, y, x_enum[x_i],
|
||||
idx_enum[type_i], &logic_cfg);
|
||||
|
@ -1658,29 +1706,41 @@ 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].lut6_str = "(A6+~A6)*A1";
|
||||
logic_cfg.a2d[LUT_A].lut5_str = "A2";
|
||||
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].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].lut6_str = "(A6+~A6)*A4";
|
||||
logic_cfg.a2d[LUT_B].lut5_str = "A3";
|
||||
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].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].lut6_str = "(A6+~A6)*(A2+A5)";
|
||||
logic_cfg.a2d[LUT_C].lut5_str = "A3+A4";
|
||||
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].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].lut6_str = "(A6+~A6)*A3";
|
||||
logic_cfg.a2d[LUT_D].lut5_str = "A3+A5";
|
||||
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].out_mux = MUX_5Q;
|
||||
logic_cfg.a2d[LUT_D].ff5_srinit = FF_SRINIT0;
|
||||
logic_cfg.a2d[LUT_D].ff = FF_FF;
|
||||
|
@ -1697,26 +1757,38 @@ static int test_logic_config(struct test_state* tstate)
|
|||
}
|
||||
// cout
|
||||
CLEAR(logic_cfg);
|
||||
logic_cfg.a2d[LUT_A].lut6_str = "(A6+~A6)*(~A5)";
|
||||
logic_cfg.a2d[LUT_A].lut5_str = "1";
|
||||
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].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].lut6_str = "(A6+~A6)*(A5)";
|
||||
logic_cfg.a2d[LUT_B].lut5_str = "1";
|
||||
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].cy0 = CY0_O5;
|
||||
logic_cfg.a2d[LUT_B].ff = FF_FF;
|
||||
logic_cfg.a2d[LUT_B].ff_mux = MUX_XOR;
|
||||
logic_cfg.a2d[LUT_B].ff_srinit = FF_SRINIT0;
|
||||
logic_cfg.a2d[LUT_C].lut6_str = "(A6+~A6)*(A5)";
|
||||
logic_cfg.a2d[LUT_C].lut5_str = "1";
|
||||
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].cy0 = CY0_O5;
|
||||
logic_cfg.a2d[LUT_C].ff = FF_FF;
|
||||
logic_cfg.a2d[LUT_C].ff_mux = MUX_XOR;
|
||||
logic_cfg.a2d[LUT_C].ff_srinit = FF_SRINIT0;
|
||||
logic_cfg.a2d[LUT_D].lut6_str = "(A6+~A6)*(A5)";
|
||||
logic_cfg.a2d[LUT_D].lut5_str = "1";
|
||||
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].cy0 = CY0_O5;
|
||||
logic_cfg.a2d[LUT_D].ff = FF_FF;
|
||||
logic_cfg.a2d[LUT_D].ff_mux = MUX_XOR;
|
||||
|
@ -1733,10 +1805,26 @@ static int test_logic_config(struct test_state* tstate)
|
|||
|
||||
// f8 out-mux
|
||||
CLEAR(logic_cfg);
|
||||
logic_cfg.a2d[LUT_A].lut6_str = "~A5";
|
||||
logic_cfg.a2d[LUT_B].lut6_str = "(A5)";
|
||||
logic_cfg.a2d[LUT_C].lut6_str = "A5";
|
||||
logic_cfg.a2d[LUT_D].lut6_str = "((A5))";
|
||||
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_B].out_mux = MUX_F8;
|
||||
rc = test_logic(tstate, y, x_enum[x_i],
|
||||
idx_enum[type_i], &logic_cfg);
|
||||
|
@ -1755,8 +1843,16 @@ static int test_logic_config(struct test_state* tstate)
|
|||
|
||||
// f7amux
|
||||
CLEAR(logic_cfg);
|
||||
logic_cfg.a2d[LUT_A].lut6_str = "~A5";
|
||||
logic_cfg.a2d[LUT_B].lut6_str = "(A5)";
|
||||
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].out_mux = MUX_F7;
|
||||
rc = test_logic(tstate, y, x_enum[x_i],
|
||||
idx_enum[type_i], &logic_cfg);
|
||||
|
@ -1775,8 +1871,16 @@ static int test_logic_config(struct test_state* tstate)
|
|||
|
||||
// f7bmux
|
||||
CLEAR(logic_cfg);
|
||||
logic_cfg.a2d[LUT_C].lut6_str = "~A5";
|
||||
logic_cfg.a2d[LUT_D].lut6_str = "(A5)";
|
||||
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].out_mux = MUX_F7;
|
||||
rc = test_logic(tstate, y, x_enum[x_i],
|
||||
idx_enum[type_i], &logic_cfg);
|
||||
|
@ -1899,8 +2003,8 @@ static int test_clock_routing(struct test_state *tstate)
|
|||
logic_x = 13;
|
||||
logic_type_idx = DEV_LOG_M_OR_L;
|
||||
|
||||
fdev_logic_a2d_lut(tstate->model, logic_y, logic_x,
|
||||
logic_type_idx, LUT_A, 6, "A1", ZTERM);
|
||||
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);
|
||||
|
@ -1951,8 +2055,8 @@ 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_a2d_lut(tstate->model, logic_y, logic_x,
|
||||
logic_type_idx, LUT_A, 6, "A1", ZTERM);
|
||||
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);
|
||||
|
@ -1999,8 +2103,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].lut6_val = 0x00000000000000FF;
|
||||
logic_cfg.a2d[LUT_D].flags |= LUT6VAL_SET;
|
||||
logic_cfg.a2d[LUT_D].lut_mode = LUTMODE_RAM;
|
||||
logic_cfg.a2d[LUT_D].lut_val = 0x00000000000000FF;
|
||||
logic_cfg.a2d[LUT_D].ram_mode = DPRAM64;
|
||||
rc = test_logic(tstate, y, x, type_i, &logic_cfg);
|
||||
if (rc) FAIL(rc);
|
||||
|
@ -2026,8 +2130,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].lut6_val = 0x00000000000000FF;
|
||||
logic_cfg.a2d[lut].flags |= LUT6VAL_SET;
|
||||
logic_cfg.a2d[lut].lut_mode = LUTMODE_RAM;
|
||||
logic_cfg.a2d[lut].lut_val = 0x00000000000000FF;
|
||||
logic_cfg.a2d[lut].ram_mode = ram_modes[ram_mode_i];
|
||||
|
||||
if (lut != LUT_D
|
||||
|
@ -2035,8 +2139,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].lut6_val = 0x00000000000000FF;
|
||||
logic_cfg.a2d[LUT_D].flags |= LUT6VAL_SET;
|
||||
logic_cfg.a2d[LUT_D].lut_mode = LUTMODE_RAM;
|
||||
logic_cfg.a2d[LUT_D].lut_val = 0x00000000000000FF;
|
||||
logic_cfg.a2d[LUT_D].ram_mode = DPRAM64;
|
||||
}
|
||||
|
||||
|
@ -2050,8 +2154,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].lut6_val = 0x00000000000000FF;
|
||||
logic_cfg.a2d[lut].flags |= LUT6VAL_SET;
|
||||
logic_cfg.a2d[lut].lut_mode = LUTMODE_RAM;
|
||||
logic_cfg.a2d[lut].lut_val = 0x00000000000000FF;
|
||||
logic_cfg.a2d[lut].ram_mode = SRL32;
|
||||
|
||||
for (dimux_i = 0; dimux_i < sizeof(dimux_modes)/sizeof(*dimux_modes);
|
||||
|
@ -2071,8 +2175,8 @@ static int test_dist_mem(struct test_state *tstate)
|
|||
|
||||
CLEAR(logic_cfg);
|
||||
logic_cfg.clk_inv = CLKINV_CLK;
|
||||
logic_cfg.a2d[lut].lut6_val = 0x00000000000000FF;
|
||||
logic_cfg.a2d[lut].flags |= LUT6VAL_SET | LUTMODE_ROM2;
|
||||
logic_cfg.a2d[lut].lut_mode = LUTMODE_ROM;
|
||||
logic_cfg.a2d[lut].lut_val = 0x00000000000000FF;
|
||||
|
||||
rc = test_logic(tstate, y, x, type_i, &logic_cfg);
|
||||
if (rc) FAIL(rc);
|
||||
|
|
|
@ -35,7 +35,8 @@ int main(int argc, char** argv)
|
|||
int iob_clk_y, iob_clk_x, iob_clk_type_idx;
|
||||
int iob_led_y, iob_led_x, iob_led_type_idx;
|
||||
int logic_x, logic_type_idx, cur_bit;
|
||||
int cur_y, next_y, i;
|
||||
int cur_y, next_y, i, rc;
|
||||
int lut_a5_used, lut_b5_used, lut_c5_used, lut_d5_used;
|
||||
struct fpgadev_logic logic_cfg;
|
||||
net_idx_t clock_net, net;
|
||||
|
||||
|
@ -100,20 +101,30 @@ int main(int argc, char** argv)
|
|||
}
|
||||
if (!cur_bit) { // first bit
|
||||
logic_cfg.precyinit = PRECYINIT_0;
|
||||
logic_cfg.a2d[LUT_A].lut6_str = "(A6+~A6)*(~A5)";
|
||||
logic_cfg.a2d[LUT_A].lut5_str = "1";
|
||||
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].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].lut6_str = "A5";
|
||||
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].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].lut6_str = "(A6+~A6)*(A5)";
|
||||
logic_cfg.a2d[cur_bit%4].lut5_str = "0";
|
||||
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].cy0 = CY0_O5;
|
||||
logic_cfg.a2d[cur_bit%4].ff = FF_FF;
|
||||
logic_cfg.a2d[cur_bit%4].ff_mux = MUX_XOR;
|
||||
|
@ -139,18 +150,18 @@ int main(int argc, char** argv)
|
|||
fnet_add_port(&model, clock_net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, LI_CLK);
|
||||
|
||||
// lut5 net (drive vcc into A6 to enable lut5)
|
||||
if (logic_cfg.a2d[LUT_A].lut5_str
|
||||
|| logic_cfg.a2d[LUT_B].lut5_str
|
||||
|| logic_cfg.a2d[LUT_C].lut5_str
|
||||
|| logic_cfg.a2d[LUT_D].lut5_str) {
|
||||
fnet_new(&model, &net);
|
||||
if (logic_cfg.a2d[LUT_A].lut5_str)
|
||||
lut_a5_used = fdev_logic_o5_used(&model, cur_y, logic_x, logic_type_idx, LUT_A);
|
||||
lut_b5_used = fdev_logic_o5_used(&model, cur_y, logic_x, logic_type_idx, LUT_B);
|
||||
lut_c5_used = fdev_logic_o5_used(&model, cur_y, logic_x, logic_type_idx, LUT_C);
|
||||
lut_d5_used = fdev_logic_o5_used(&model, cur_y, logic_x, logic_type_idx, LUT_D);
|
||||
if (lut_a5_used || lut_b5_used || lut_c5_used || lut_d5_used) {
|
||||
if (lut_a5_used)
|
||||
fnet_add_port(&model, net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, LI_A6);
|
||||
if (logic_cfg.a2d[LUT_B].lut5_str)
|
||||
if (lut_b5_used)
|
||||
fnet_add_port(&model, net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, LI_B6);
|
||||
if (logic_cfg.a2d[LUT_C].lut5_str)
|
||||
if (lut_c5_used)
|
||||
fnet_add_port(&model, net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, LI_C6);
|
||||
if (logic_cfg.a2d[LUT_D].lut5_str)
|
||||
if (lut_d5_used)
|
||||
fnet_add_port(&model, net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, LI_D6);
|
||||
fnet_vcc_gnd(&model, net, /*is_vcc*/ 1);
|
||||
}
|
||||
|
|
|
@ -52,8 +52,8 @@ int main(int argc, char** argv)
|
|||
logic_y = 68;
|
||||
logic_x = 13;
|
||||
logic_type_idx = DEV_LOG_X;
|
||||
fdev_logic_a2d_lut(&model, logic_y, logic_x, logic_type_idx,
|
||||
LUT_D, 6, "A3*A5", ZTERM);
|
||||
fdev_logic_set_lutstr(&model, logic_y, logic_x, logic_type_idx,
|
||||
LUT_D, /*lut6_str*/ "A3*A5", /*lut5_str*/ 0);
|
||||
|
||||
fnet_new(&model, &inA_net);
|
||||
fnet_add_port(&model, inA_net, iob_inA_y, iob_inA_x,
|
||||
|
|
|
@ -644,35 +644,6 @@ static int extract_type2(struct extract_state* es)
|
|||
RC_RETURN(es->model);
|
||||
}
|
||||
|
||||
static int lut2str(uint64_t lut_val, int lut5_used,
|
||||
char *lut6_buf, char** lut6_p, char *lut5_buf, char** lut5_p)
|
||||
{
|
||||
const char* str;
|
||||
int rc;
|
||||
|
||||
if (lut5_used) {
|
||||
// lut6
|
||||
str = bool_bits2str(ULL_HIGH32(lut_val), 32);
|
||||
if (!str) FAIL(EINVAL);
|
||||
snprintf(lut6_buf, MAX_LUT_LEN, "(A6+~A6)*(%s)", str);
|
||||
*lut6_p = lut6_buf;
|
||||
|
||||
// lut5
|
||||
str = bool_bits2str(ULL_LOW32(lut_val), 32);
|
||||
if (!str) FAIL(EINVAL);
|
||||
strcpy(lut5_buf, str);
|
||||
*lut5_p = lut5_buf;
|
||||
} else {
|
||||
str = bool_bits2str(lut_val, 64);
|
||||
if (!str) FAIL(EINVAL);
|
||||
strcpy(lut6_buf, str);
|
||||
*lut6_p = lut6_buf;
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int back_to_cout(struct fpga_model *model, int cin_y, int cin_x,
|
||||
str16_t cin_str, int *cout_y, int *cout_x, str16_t *cout_str)
|
||||
{
|
||||
|
@ -695,16 +666,12 @@ static int back_to_cout(struct fpga_model *model, int cin_y, int cin_x,
|
|||
|
||||
static int extract_logic(struct extract_state* es)
|
||||
{
|
||||
int row, row_pos, x, y, i, byte_off, last_minor, lut5_used, rc;
|
||||
int row, row_pos, x, y, i, byte_off, last_minor, rc;
|
||||
int latch_ml, latch_x, l_col, lut;
|
||||
struct fpgadev_logic cfg_ml, cfg_x;
|
||||
uint64_t lut_X[4], lut_ML[4]; // LUT_A-LUT_D
|
||||
uint64_t mi20, mi23_M, mi2526;
|
||||
uint8_t* u8_p;
|
||||
char lut6_ml[NUM_LUTS][MAX_LUT_LEN];
|
||||
char lut5_ml[NUM_LUTS][MAX_LUT_LEN];
|
||||
char lut6_x[NUM_LUTS][MAX_LUT_LEN];
|
||||
char lut5_x[NUM_LUTS][MAX_LUT_LEN];
|
||||
struct fpga_device* dev_ml;
|
||||
|
||||
RC_CHECK(es->model);
|
||||
|
@ -1222,17 +1189,8 @@ 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].flags |= OUT_USED;
|
||||
|
||||
lut5_used = (cfg_ml.a2d[LUT_A].ff_mux == MUX_O5
|
||||
|| cfg_ml.a2d[LUT_A].out_mux == MUX_5Q
|
||||
|| cfg_ml.a2d[LUT_A].out_mux == MUX_O5
|
||||
|| cfg_ml.a2d[LUT_A].cy0 == CY0_O5);
|
||||
rc = lut2str(lut_ML[LUT_A],
|
||||
lut5_used,
|
||||
lut6_ml[LUT_A], &cfg_ml.a2d[LUT_A].lut6_str,
|
||||
lut5_ml[LUT_A], &cfg_ml.a2d[LUT_A].lut5_str);
|
||||
if (rc) FAIL(rc);
|
||||
cfg_ml.a2d[LUT_A].out_used = 1;
|
||||
cfg_ml.a2d[LUT_A].lut_val = lut_ML[LUT_A];
|
||||
}
|
||||
// ML-B
|
||||
if (lut_ML[LUT_B]
|
||||
|
@ -1246,17 +1204,8 @@ 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].flags |= OUT_USED;
|
||||
|
||||
lut5_used = (cfg_ml.a2d[LUT_B].ff_mux == MUX_O5
|
||||
|| cfg_ml.a2d[LUT_B].out_mux == MUX_5Q
|
||||
|| cfg_ml.a2d[LUT_B].out_mux == MUX_O5
|
||||
|| cfg_ml.a2d[LUT_B].cy0 == CY0_O5);
|
||||
rc = lut2str(lut_ML[LUT_B],
|
||||
lut5_used,
|
||||
lut6_ml[LUT_B], &cfg_ml.a2d[LUT_B].lut6_str,
|
||||
lut5_ml[LUT_B], &cfg_ml.a2d[LUT_B].lut5_str);
|
||||
if (rc) FAIL(rc);
|
||||
cfg_ml.a2d[LUT_B].out_used = 1;
|
||||
cfg_ml.a2d[LUT_B].lut_val = lut_ML[LUT_B];
|
||||
}
|
||||
// ML-C
|
||||
if (lut_ML[LUT_C]
|
||||
|
@ -1270,17 +1219,8 @@ 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].flags |= OUT_USED;
|
||||
|
||||
lut5_used = (cfg_ml.a2d[LUT_C].ff_mux == MUX_O5
|
||||
|| cfg_ml.a2d[LUT_C].out_mux == MUX_5Q
|
||||
|| cfg_ml.a2d[LUT_C].out_mux == MUX_O5
|
||||
|| cfg_ml.a2d[LUT_C].cy0 == CY0_O5);
|
||||
rc = lut2str(lut_ML[LUT_C],
|
||||
lut5_used,
|
||||
lut6_ml[LUT_C], &cfg_ml.a2d[LUT_C].lut6_str,
|
||||
lut5_ml[LUT_C], &cfg_ml.a2d[LUT_C].lut5_str);
|
||||
if (rc) FAIL(rc);
|
||||
cfg_ml.a2d[LUT_C].out_used = 1;
|
||||
cfg_ml.a2d[LUT_C].lut_val = lut_ML[LUT_C];
|
||||
}
|
||||
// ML-D
|
||||
if (lut_ML[LUT_D]
|
||||
|
@ -1294,73 +1234,40 @@ 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].flags |= OUT_USED;
|
||||
|
||||
lut5_used = (cfg_ml.a2d[LUT_D].ff_mux == MUX_O5
|
||||
|| cfg_ml.a2d[LUT_D].out_mux == MUX_5Q
|
||||
|| cfg_ml.a2d[LUT_D].out_mux == MUX_O5
|
||||
|| cfg_ml.a2d[LUT_D].cy0 == CY0_O5);
|
||||
rc = lut2str(lut_ML[LUT_D],
|
||||
lut5_used,
|
||||
lut6_ml[LUT_D], &cfg_ml.a2d[LUT_D].lut6_str,
|
||||
lut5_ml[LUT_D], &cfg_ml.a2d[LUT_D].lut5_str);
|
||||
if (rc) FAIL(rc);
|
||||
cfg_ml.a2d[LUT_D].out_used = 1;
|
||||
cfg_ml.a2d[LUT_D].lut_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].flags |= OUT_USED;
|
||||
lut5_used = cfg_x.a2d[LUT_A].out_mux != 0;
|
||||
rc = lut2str(lut_X[LUT_A],
|
||||
lut5_used,
|
||||
lut6_x[LUT_A], &cfg_x.a2d[LUT_A].lut6_str,
|
||||
lut5_x[LUT_A], &cfg_x.a2d[LUT_A].lut5_str);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
cfg_x.a2d[LUT_A].out_used = 1;
|
||||
cfg_x.a2d[LUT_A].lut_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].flags |= OUT_USED;
|
||||
lut5_used = cfg_x.a2d[LUT_B].out_mux != 0;
|
||||
rc = lut2str(lut_X[LUT_B],
|
||||
lut5_used,
|
||||
lut6_x[LUT_B], &cfg_x.a2d[LUT_B].lut6_str,
|
||||
lut5_x[LUT_B], &cfg_x.a2d[LUT_B].lut5_str);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
cfg_x.a2d[LUT_B].out_used = 1;
|
||||
cfg_x.a2d[LUT_B].lut_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].flags |= OUT_USED;
|
||||
lut5_used = cfg_x.a2d[LUT_C].out_mux != 0;
|
||||
rc = lut2str(lut_X[LUT_C],
|
||||
lut5_used,
|
||||
lut6_x[LUT_C], &cfg_x.a2d[LUT_C].lut6_str,
|
||||
lut5_x[LUT_C], &cfg_x.a2d[LUT_C].lut5_str);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
cfg_x.a2d[LUT_C].out_used = 1;
|
||||
cfg_x.a2d[LUT_C].lut_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].flags |= OUT_USED;
|
||||
lut5_used = cfg_x.a2d[LUT_D].out_mux != 0;
|
||||
rc = lut2str(lut_X[LUT_D],
|
||||
lut5_used,
|
||||
lut6_x[LUT_D], &cfg_x.a2d[LUT_D].lut6_str,
|
||||
lut5_x[LUT_D], &cfg_x.a2d[LUT_D].lut5_str);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
cfg_x.a2d[LUT_D].out_used = 1;
|
||||
cfg_x.a2d[LUT_D].lut_val = lut_X[LUT_D];
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2763,38 +2670,10 @@ static int is_latch(struct fpga_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int str2lut(uint64_t *lut, int lut_pos, const struct fpgadev_logic_a2d *a2d)
|
||||
{
|
||||
int lut6_used, lut5_used, rc;
|
||||
|
||||
lut6_used = a2d->lut6_str && a2d->lut6_str[0];
|
||||
lut5_used = a2d->lut5_str && a2d->lut5_str[0];
|
||||
if (!lut6_used && !lut5_used)
|
||||
return 0;
|
||||
|
||||
if (lut5_used) {
|
||||
if (!lut6_used) *lut = 0;
|
||||
else {
|
||||
rc = bool_str2bits(a2d->lut6_str, lut, 32);
|
||||
if (rc) FAIL(rc);
|
||||
(*lut) <<= 32;
|
||||
}
|
||||
rc = bool_str2bits(a2d->lut5_str, lut, 32);
|
||||
if (rc) FAIL(rc);
|
||||
} else {
|
||||
// lut6_used only
|
||||
rc = bool_str2bits(a2d->lut6_str, lut, 64);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int write_logic(struct fpga_bits* bits, struct fpga_model* model)
|
||||
{
|
||||
int dev_idx, row, row_pos, xm_col;
|
||||
int x, y, byte_off, rc;
|
||||
int x, y, byte_off;
|
||||
uint64_t lut_X[4], lut_ML[4]; // LUT_A-LUT_D
|
||||
uint64_t mi20, mi23_M, mi2526;
|
||||
uint8_t* u8_p;
|
||||
|
@ -3058,41 +2937,17 @@ static int write_logic(struct fpga_bits* bits, struct fpga_model* model)
|
|||
|
||||
// X device
|
||||
if (dev_x->instantiated) {
|
||||
rc = str2lut(&lut_X[LUT_A], xm_col
|
||||
? XC6_LMAP_XM_X_A : XC6_LMAP_XL_X_A,
|
||||
&dev_x->u.logic.a2d[LUT_A]);
|
||||
RC_ASSERT(model, !rc);
|
||||
rc = str2lut(&lut_X[LUT_B], xm_col
|
||||
? XC6_LMAP_XM_X_B : XC6_LMAP_XL_X_B,
|
||||
&dev_x->u.logic.a2d[LUT_B]);
|
||||
RC_ASSERT(model, !rc);
|
||||
rc = str2lut(&lut_X[LUT_C], xm_col
|
||||
? XC6_LMAP_XM_X_C : XC6_LMAP_XL_X_C,
|
||||
&dev_x->u.logic.a2d[LUT_C]);
|
||||
RC_ASSERT(model, !rc);
|
||||
rc = str2lut(&lut_X[LUT_D], xm_col
|
||||
? XC6_LMAP_XM_X_D : XC6_LMAP_XL_X_D,
|
||||
&dev_x->u.logic.a2d[LUT_D]);
|
||||
RC_ASSERT(model, !rc);
|
||||
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;
|
||||
}
|
||||
// M or L device
|
||||
if (dev_ml->instantiated) {
|
||||
rc = str2lut(&lut_ML[LUT_A], xm_col
|
||||
? XC6_LMAP_XM_M_A : XC6_LMAP_XL_L_A,
|
||||
&dev_ml->u.logic.a2d[LUT_A]);
|
||||
RC_ASSERT(model, !rc);
|
||||
rc = str2lut(&lut_ML[LUT_B], xm_col
|
||||
? XC6_LMAP_XM_M_B : XC6_LMAP_XL_L_B,
|
||||
&dev_ml->u.logic.a2d[LUT_B]);
|
||||
RC_ASSERT(model, !rc);
|
||||
rc = str2lut(&lut_ML[LUT_C], xm_col
|
||||
? XC6_LMAP_XM_M_C : XC6_LMAP_XL_L_C,
|
||||
&dev_ml->u.logic.a2d[LUT_C]);
|
||||
RC_ASSERT(model, !rc);
|
||||
rc = str2lut(&lut_ML[LUT_D], xm_col
|
||||
? XC6_LMAP_XM_M_D : XC6_LMAP_XL_L_D,
|
||||
&dev_ml->u.logic.a2d[LUT_D]);
|
||||
RC_ASSERT(model, !rc);
|
||||
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;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
245
libs/control.c
245
libs/control.c
|
@ -404,87 +404,36 @@ static void add_req_outpin(struct fpga_device* dev, pinw_idx_t pinw_i)
|
|||
// logic device
|
||||
//
|
||||
|
||||
int fdev_logic_setconf(struct fpga_model* model, int y, int x,
|
||||
int type_idx, const struct fpgadev_logic* logic_cfg)
|
||||
int fdev_logic_setconf(struct fpga_model *model, int y, int x,
|
||||
int type_idx, const struct fpgadev_logic *logic_cfg)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
int lut;
|
||||
struct fpga_device *dev;
|
||||
|
||||
RC_CHECK(model);
|
||||
// todo: if we delete the entire old config, why do we do the
|
||||
// config OR'ing below?
|
||||
fdev_delete(model, y, x, DEV_LOGIC, type_idx);
|
||||
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
|
||||
RC_ASSERT(model, dev);
|
||||
reset_required_pins(dev);
|
||||
|
||||
for (lut = LUT_A; lut <= LUT_D; lut++) {
|
||||
if (logic_cfg->a2d[lut].lut_mode)
|
||||
dev->u.logic.a2d[lut].lut_mode = logic_cfg->a2d[lut].lut_mode;
|
||||
if (logic_cfg->a2d[lut].flags & OUT_USED)
|
||||
dev->u.logic.a2d[lut].flags |= OUT_USED;
|
||||
if (logic_cfg->a2d[lut].lut6_str) {
|
||||
fdev_logic_a2d_lut(model, y, x, type_idx,
|
||||
lut, 6, logic_cfg->a2d[lut].lut6_str, ZTERM);
|
||||
}
|
||||
if (logic_cfg->a2d[lut].lut5_str) {
|
||||
fdev_logic_a2d_lut(model, y, x, type_idx,
|
||||
lut, 5, logic_cfg->a2d[lut].lut5_str, ZTERM);
|
||||
}
|
||||
if (logic_cfg->a2d[lut].ff) {
|
||||
RC_ASSERT(model, logic_cfg->a2d[lut].ff_mux
|
||||
&& logic_cfg->a2d[lut].ff_srinit);
|
||||
dev->u.logic.a2d[lut].ff = logic_cfg->a2d[lut].ff;
|
||||
dev->u.logic.a2d[lut].ff_mux = logic_cfg->a2d[lut].ff_mux;
|
||||
dev->u.logic.a2d[lut].ff_srinit = logic_cfg->a2d[lut].ff_srinit;
|
||||
}
|
||||
if (logic_cfg->a2d[lut].out_mux)
|
||||
dev->u.logic.a2d[lut].out_mux = logic_cfg->a2d[lut].out_mux;
|
||||
if (logic_cfg->a2d[lut].ff5_srinit)
|
||||
dev->u.logic.a2d[lut].ff5_srinit = logic_cfg->a2d[lut].ff5_srinit;
|
||||
if (logic_cfg->a2d[lut].cy0)
|
||||
dev->u.logic.a2d[lut].cy0 = logic_cfg->a2d[lut].cy0;
|
||||
|
||||
// distributed memory related:
|
||||
if (logic_cfg->a2d[lut].flags & LUT6VAL_SET) {
|
||||
dev->u.logic.a2d[lut].flags |= LUT6VAL_SET;
|
||||
dev->u.logic.a2d[lut].lut6_val = logic_cfg->a2d[lut].lut6_val;
|
||||
}
|
||||
if (logic_cfg->a2d[lut].flags & LUT5VAL_SET) {
|
||||
dev->u.logic.a2d[lut].flags |= LUT5VAL_SET;
|
||||
dev->u.logic.a2d[lut].lut5_val = logic_cfg->a2d[lut].lut5_val;
|
||||
}
|
||||
if (logic_cfg->a2d[lut].flags & LUTMODE_ROM2)
|
||||
dev->u.logic.a2d[lut].flags |= LUTMODE_ROM2;
|
||||
if (logic_cfg->a2d[lut].ram_mode)
|
||||
dev->u.logic.a2d[lut].ram_mode = logic_cfg->a2d[lut].ram_mode;
|
||||
if (logic_cfg->a2d[lut].di_mux)
|
||||
dev->u.logic.a2d[lut].di_mux = logic_cfg->a2d[lut].di_mux;
|
||||
}
|
||||
if (logic_cfg->clk_inv)
|
||||
dev->u.logic.clk_inv = logic_cfg->clk_inv;
|
||||
if (logic_cfg->sync_attr)
|
||||
dev->u.logic.sync_attr = logic_cfg->sync_attr;
|
||||
if (logic_cfg->ce_used)
|
||||
dev->u.logic.ce_used = logic_cfg->ce_used;
|
||||
if (logic_cfg->sr_used)
|
||||
dev->u.logic.sr_used = logic_cfg->sr_used;
|
||||
if (logic_cfg->we_mux)
|
||||
dev->u.logic.we_mux = logic_cfg->we_mux;
|
||||
if (logic_cfg->cout_used)
|
||||
dev->u.logic.cout_used = logic_cfg->cout_used;
|
||||
if (logic_cfg->precyinit)
|
||||
dev->u.logic.precyinit = logic_cfg->precyinit;
|
||||
if (logic_cfg->wa7_used)
|
||||
dev->u.logic.wa7_used = logic_cfg->wa7_used;
|
||||
if (logic_cfg->wa8_used)
|
||||
dev->u.logic.wa8_used = logic_cfg->wa8_used;
|
||||
|
||||
dev->u.logic = *logic_cfg;
|
||||
dev->instantiated = 1;
|
||||
|
||||
fdev_set_required_pins(model, y, x, DEV_LOGIC, type_idx);
|
||||
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)
|
||||
{
|
||||
|
@ -497,40 +446,7 @@ int fdev_logic_a2d_out_used(struct fpga_model* model, int y, int x,
|
|||
rc = reset_required_pins(dev);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int fdev_logic_a2d_lut(struct fpga_model* model, int y, int x, int type_idx,
|
||||
int lut_a2d, int lut_5or6, const char* lut_str, int lut_len)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
char** lut_ptr;
|
||||
int rc;
|
||||
|
||||
RC_CHECK(model);
|
||||
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
|
||||
if (!dev) FAIL(EINVAL);
|
||||
rc = reset_required_pins(dev);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
lut_ptr = (lut_5or6 == 5)
|
||||
? &dev->u.logic.a2d[lut_a2d].lut5_str
|
||||
: &dev->u.logic.a2d[lut_a2d].lut6_str;
|
||||
if (*lut_ptr == 0) {
|
||||
*lut_ptr = malloc(MAX_LUT_LEN);
|
||||
if (!(*lut_ptr)) FAIL(ENOMEM);
|
||||
}
|
||||
if (lut_len == ZTERM) lut_len = strlen(lut_str);
|
||||
memcpy(*lut_ptr, lut_str, lut_len);
|
||||
(*lut_ptr)[lut_len] = 0;
|
||||
|
||||
dev->u.logic.a2d[lut_a2d].out_used = used;
|
||||
dev->instantiated = 1;
|
||||
return 0;
|
||||
fail:
|
||||
|
@ -731,7 +647,7 @@ fail:
|
|||
int fdev_logic_precyinit(struct fpga_model* model, int y, int x,
|
||||
int type_idx, int precyinit)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
struct fpga_device *dev;
|
||||
int rc;
|
||||
|
||||
RC_CHECK(model);
|
||||
|
@ -747,6 +663,56 @@ fail:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int fdev_logic_o5_used(struct fpga_model *model, int y, int x, int type_idx,
|
||||
int lut_a2d)
|
||||
{
|
||||
struct fpga_device *dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
|
||||
if (!dev) { HERE(); return 0; }
|
||||
|
||||
return (type_idx == DEV_LOG_X
|
||||
&& dev->u.logic.a2d[lut_a2d].out_mux)
|
||||
|| (type_idx == DEV_LOG_M_OR_L
|
||||
&& (dev->u.logic.a2d[lut_a2d].ff_mux == MUX_O5
|
||||
|| dev->u.logic.a2d[lut_a2d].out_mux == MUX_5Q
|
||||
|| dev->u.logic.a2d[lut_a2d].out_mux == MUX_O5
|
||||
|| 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)
|
||||
{
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
RC_RETURN(model);
|
||||
}
|
||||
|
||||
//
|
||||
// iob device
|
||||
//
|
||||
|
@ -896,29 +862,12 @@ int fdev_bscan(struct fpga_model *model, int y, int x, int type_idx,
|
|||
RC_RETURN(model);
|
||||
}
|
||||
|
||||
static void scan_lut_digits(const char* s, int* digits)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
digits[i] = 0;
|
||||
if (!s) return;
|
||||
// Note special cases "0" and "1" for a lut that
|
||||
// always results in 0 or 1.
|
||||
for (i = 0; s[i]; i++) {
|
||||
if (s[i] != 'A' && s[i] != 'a')
|
||||
continue;
|
||||
if (s[i+1] >= '1' && s[i+1] <= '6')
|
||||
digits[s[++i]-'1']++;
|
||||
}
|
||||
}
|
||||
|
||||
int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
|
||||
int type_idx)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
int digits[6];
|
||||
int i, j, rc;
|
||||
int req_inpins[6];
|
||||
int i, j, k, rc;
|
||||
|
||||
RC_CHECK(model);
|
||||
dev = fdev_p(model, y, x, type, type_idx);
|
||||
|
@ -957,7 +906,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].flags & OUT_USED) {
|
||||
if (dev->u.logic.a2d[i].out_used) {
|
||||
// LO_A..LO_D are in sequence
|
||||
add_req_outpin(dev, LO_A+i);
|
||||
}
|
||||
|
@ -975,27 +924,40 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
|
|||
// LI_AX..LI_DX are in sequence
|
||||
add_req_inpin(dev, LI_AX+i);
|
||||
}
|
||||
if (dev->u.logic.a2d[i].lut6_str) {
|
||||
scan_lut_digits(dev->u.logic.a2d[i].lut6_str, digits);
|
||||
for (j = 0; j < 6; j++) {
|
||||
if (!digits[j]) continue;
|
||||
add_req_inpin(dev, LI_A1+i*6+j);
|
||||
|
||||
for (j = 0; j < 6; j++)
|
||||
req_inpins[j] = 0;
|
||||
if (fdev_logic_o5_used(model, y, x, type_idx, i)) {
|
||||
// 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))))
|
||||
continue;
|
||||
for (k = 0; k < 5; k++) {
|
||||
if (j & (1<<k))
|
||||
req_inpins[k] = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (!(dev->u.logic.a2d[i].lut_val & (1ULL << j)))
|
||||
continue;
|
||||
for (k = 0; k < 6; k++) {
|
||||
if (j & (1<<k))
|
||||
req_inpins[k] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dev->u.logic.a2d[i].lut5_str) {
|
||||
// A6 must be high/vcc if lut5 is used
|
||||
add_req_inpin(dev, LI_A6+i*6);
|
||||
scan_lut_digits(dev->u.logic.a2d[i].lut5_str, digits);
|
||||
for (j = 0; j < 6; j++) {
|
||||
if (!digits[j]) continue;
|
||||
for (j = 0; j < 6; j++) {
|
||||
if (req_inpins[j])
|
||||
add_req_inpin(dev, LI_A1+i*6+j);
|
||||
}
|
||||
}
|
||||
if ((dev->u.logic.a2d[i].ff_mux == MUX_XOR
|
||||
|| dev->u.logic.a2d[i].out_mux == MUX_XOR)
|
||||
&& !dev->u.logic.precyinit)
|
||||
add_req_inpin(dev, LI_CIN);
|
||||
if (dev->u.logic.a2d[i].flags & (LUT6VAL_SET|LUT5VAL_SET))
|
||||
if (dev->u.logic.a2d[i].ram_mode)
|
||||
add_req_inpin(dev, LI_CLK);
|
||||
}
|
||||
return 0;
|
||||
|
@ -1014,7 +976,6 @@ fail:
|
|||
void fdev_delete(struct fpga_model* model, int y, int x, int type, int type_idx)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
int i;
|
||||
|
||||
dev = fdev_p(model, y, x, type, type_idx);
|
||||
if (!dev) { HERE(); return; }
|
||||
|
@ -1023,14 +984,6 @@ void fdev_delete(struct fpga_model* model, int y, int x, int type, int type_idx)
|
|||
dev->pinw_req_for_cfg = 0;
|
||||
dev->pinw_req_total = 0;
|
||||
dev->pinw_req_in = 0;
|
||||
if (dev->type == DEV_LOGIC) {
|
||||
for (i = LUT_A; i <= LUT_D; i++) {
|
||||
free(dev->u.logic.a2d[i].lut6_str);
|
||||
dev->u.logic.a2d[i].lut6_str = 0;
|
||||
free(dev->u.logic.a2d[i].lut5_str);
|
||||
dev->u.logic.a2d[i].lut5_str = 0;
|
||||
}
|
||||
}
|
||||
dev->instantiated = 0;
|
||||
memset(&dev->u, 0, sizeof(dev->u));
|
||||
}
|
||||
|
|
|
@ -54,13 +54,12 @@ 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,
|
||||
int type_idx, int lut_a2d, int used);
|
||||
// lut_5or6 is int 5 or int 6
|
||||
int fdev_logic_a2d_lut(struct fpga_model* model, int y, int x, int type_idx,
|
||||
int lut_a2d, int lut_5or6, const char* lut_str, int lut_len);
|
||||
// srinit is FF_SRINIT0 or FF_SRINIT1
|
||||
int fdev_logic_a2d_ff(struct fpga_model* model, int y, int x, int type_idx,
|
||||
int lut_a2d, int ff_mux, int srinit);
|
||||
|
@ -69,7 +68,7 @@ int fdev_logic_a2d_ff5_srinit(struct fpga_model* model, int y, int x,
|
|||
int fdev_logic_a2d_out_mux(struct fpga_model* model, int y, int x,
|
||||
int type_idx, int lut_a2d, int out_mux);
|
||||
// cy0 is CY0_X or CY0_O5
|
||||
int fdev_logic_a2d_cy0(struct fpga_model* model, int y, int x,
|
||||
int fdev_logic_a2d_cy0(struct fpga_model *model, int y, int x,
|
||||
int type_idx, int lut_a2d, int cy0);
|
||||
|
||||
// clk is CLKINV_B or CLKINV_CLK
|
||||
|
@ -89,6 +88,12 @@ int fdev_logic_cout_used(struct fpga_model* model, int y, int x,
|
|||
int fdev_logic_precyinit(struct fpga_model* model, int y, int x,
|
||||
int type_idx, int precyinit);
|
||||
|
||||
// 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_iob_input(struct fpga_model* model, int y, int x,
|
||||
int type_idx, const char* io_std);
|
||||
int fdev_iob_output(struct fpga_model* model, int y, int x,
|
||||
|
|
|
@ -315,33 +315,21 @@ int printf_LOGIC(FILE* f, struct fpga_model* model,
|
|||
switch (cfg->a2d[j].lut_mode) {
|
||||
case LUTMODE_LUT:
|
||||
fprintf(f, "%s %c_mode LUT\n", pref, 'A'+j);
|
||||
// todo: A6_str, A5_str
|
||||
// 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);
|
||||
default: RC_FAIL(model, EINVAL);
|
||||
}
|
||||
|
||||
if (cfg->a2d[j].lut6_str && cfg->a2d[j].lut6_str[0])
|
||||
fprintf(f, "%s %c6_lut_str %s\n", pref, 'A'+j,
|
||||
cfg->a2d[j].lut6_str);
|
||||
if (cfg->a2d[j].lut5_str && cfg->a2d[j].lut5_str[0])
|
||||
fprintf(f, "%s %c5_lut_str %s\n", pref, 'A'+j,
|
||||
cfg->a2d[j].lut5_str);
|
||||
if (cfg->a2d[j].flags & LUT6VAL_SET)
|
||||
fprintf(f, "%s %c6_lut_val 0x%016lX\n", pref, 'A'+j, cfg->a2d[j].lut6_val);
|
||||
if (cfg->a2d[j].flags & LUT5VAL_SET)
|
||||
fprintf(f, "%s %c5_lut_val 0x%08X\n", pref, 'A'+j, cfg->a2d[j].lut5_val);
|
||||
if (cfg->a2d[j].flags & LUTMODE_ROM2)
|
||||
fprintf(f, "%s %c_rom\n", pref, 'A'+j);
|
||||
|
||||
if (cfg->a2d[j].flags & OUT_USED)
|
||||
if (cfg->a2d[j].out_used)
|
||||
fprintf(f, "%s %c_used\n", pref, 'A'+j);
|
||||
|
||||
switch (cfg->a2d[j].ff) {
|
||||
|
@ -537,7 +525,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, rc;
|
||||
int i, j;
|
||||
|
||||
dev = fdev_p(model, y, x, DEV_LOGIC, type_idx);
|
||||
if (!dev) { HERE(); return 0; }
|
||||
|
@ -546,12 +534,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].flags |= OUT_USED;
|
||||
goto inst_1;
|
||||
}
|
||||
snprintf(cmp_str, sizeof(cmp_str), "%c_rom", 'A'+i);
|
||||
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
|
||||
dev->u.logic.a2d[i].flags |= LUTMODE_ROM2;
|
||||
dev->u.logic.a2d[i].out_used = 1;
|
||||
goto inst_1;
|
||||
}
|
||||
}
|
||||
|
@ -582,6 +565,7 @@ 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);
|
||||
|
@ -594,6 +578,7 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
|
|||
if (rc) return 0;
|
||||
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))
|
||||
|
@ -709,10 +694,10 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
|
|||
__FILE__, __LINE__, errno, endptr);
|
||||
return 0;
|
||||
}
|
||||
dev->u.logic.a2d[i].lut6_val = val;
|
||||
dev->u.logic.a2d[i].flags |= LUT6VAL_SET;
|
||||
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
|
||||
|
@ -730,6 +715,7 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
|
|||
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))
|
||||
|
|
|
@ -343,6 +343,29 @@ 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;
|
||||
|
|
|
@ -69,6 +69,8 @@ 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);
|
||||
|
||||
void printf_type2(uint8_t* d, int len, int inpos, int num_entries);
|
||||
void printf_ramb16_data(uint8_t* bits, int inpos);
|
||||
|
||||
|
|
15
libs/model.h
15
libs/model.h
|
@ -416,10 +416,6 @@ enum {
|
|||
"COUT" }
|
||||
|
||||
enum { LUT_A = 0, LUT_B, LUT_C, LUT_D }; // offset into a2d[]
|
||||
#define OUT_USED 0x0001
|
||||
#define LUT6VAL_SET 0x0002
|
||||
#define LUT5VAL_SET 0x0004
|
||||
#define LUTMODE_ROM2 0x0008
|
||||
enum { LUTMODE_LUT = 1, LUTMODE_ROM, LUTMODE_RAM };
|
||||
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 };
|
||||
|
@ -437,16 +433,11 @@ enum { DIMUX_MC31 = 1, DIMUX_X, DIMUX_DX, DIMUX_BDI1 };
|
|||
|
||||
struct fpgadev_logic_a2d
|
||||
{
|
||||
int flags; // OUT_USED, LUT6VAL_SET, LUT5VAL_SET, LUTMODE_ROM2
|
||||
char* lut6_str;
|
||||
char* lut5_str;
|
||||
|
||||
// lut_mode should always be set for a used lut.
|
||||
// ROM and LUT are almost identical, RAM is a completely
|
||||
// different mode for the entire slice (M only).
|
||||
// In LUT or ROM mode, DI1/DI2, MC31 and WA1..WA8
|
||||
// should not be connected.
|
||||
|
||||
// lut_mode should always be set for a used lut.
|
||||
int lut_mode; // LUTMODE_LUT, LUTMODE_ROM, LUTMODE_RAM
|
||||
|
||||
uint64_t lut_val;
|
||||
|
@ -458,10 +449,6 @@ struct fpgadev_logic_a2d
|
|||
int ff; // OR2L, AND2L, LATCH, FF
|
||||
int cy0; // X, O5
|
||||
|
||||
// distributed memory related - if either LUT6VAL_SET or LUT5VAL_SET are on:
|
||||
uint64_t lut6_val;
|
||||
uint32_t lut5_val;
|
||||
|
||||
// Requirements for LUTMODE_RAM:
|
||||
// - input on CLK and WE pins
|
||||
// - SRL32 and SRL16 should have O6 or MC31 output
|
||||
|
|
Loading…
Reference in New Issue
Block a user