diff --git a/autotest.c b/autotest.c index c686274..363402f 100644 --- a/autotest.c +++ b/autotest.c @@ -1244,9 +1244,9 @@ static int test_lut_encoding(struct test_state* tstate) for (x_i = 0; x_i < sizeof(x_enum)/sizeof(*x_enum); x_i++) { for (type_i = 0; type_i < sizeof(idx_enum)/sizeof(*idx_enum); type_i++) { for (lut = LUT_A; lut <= LUT_D; lut++) { - memset(&logic_cfg, 0, sizeof(logic_cfg)); + CLEAR(logic_cfg); logic_cfg.a2d[lut].lut6_str = lut6_str; - logic_cfg.a2d[lut].out_used = 1; + logic_cfg.a2d[lut].flags |= OUT_USED; // lut6 only sprintf(lut6_str, "0"); @@ -1345,9 +1345,9 @@ static int test_logic_config(struct test_state* tstate) for (lut = LUT_A; lut <= LUT_D; lut++) { // lut6, direct-out - memset(&logic_cfg, 0, sizeof(logic_cfg)); + CLEAR(logic_cfg); logic_cfg.a2d[lut].lut6_str = "A1"; - logic_cfg.a2d[lut].out_used = 1; + logic_cfg.a2d[lut].flags |= OUT_USED; rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i], &logic_cfg); @@ -1357,7 +1357,7 @@ static int test_logic_config(struct test_state* tstate) // lut6, mux-out // O6 over mux-out seems not supported // on an X device. - memset(&logic_cfg, 0, sizeof(logic_cfg)); + CLEAR(logic_cfg); logic_cfg.a2d[lut].lut6_str = "A1"; logic_cfg.a2d[lut].out_mux = MUX_O6; @@ -1396,7 +1396,7 @@ static int test_logic_config(struct test_state* tstate) } // lut6, ff-out - memset(&logic_cfg, 0, sizeof(logic_cfg)); + CLEAR(logic_cfg); logic_cfg.a2d[lut].lut6_str = "A1"; logic_cfg.a2d[lut].ff = FF_FF; logic_cfg.a2d[lut].ff_mux = MUX_O6; @@ -1439,7 +1439,7 @@ static int test_logic_config(struct test_state* tstate) } // lut6, latch-out - memset(&logic_cfg, 0, sizeof(logic_cfg)); + CLEAR(logic_cfg); logic_cfg.a2d[lut].lut6_str = "A1"; logic_cfg.a2d[lut].ff = FF_LATCH; logic_cfg.a2d[lut].ff_mux = MUX_O6; @@ -1463,7 +1463,7 @@ static int test_logic_config(struct test_state* tstate) // // lut6, and-latch - memset(&logic_cfg, 0, sizeof(logic_cfg)); + CLEAR(logic_cfg); logic_cfg.a2d[lut].lut6_str = "A1"; logic_cfg.a2d[lut].ff = FF_AND2L; logic_cfg.a2d[lut].ff_mux = MUX_O6; @@ -1480,7 +1480,7 @@ static int test_logic_config(struct test_state* tstate) if (rc) FAIL(rc); // lut6, or-latch - memset(&logic_cfg, 0, sizeof(logic_cfg)); + CLEAR(logic_cfg); logic_cfg.a2d[lut].lut6_str = "A1"; logic_cfg.a2d[lut].ff = FF_OR2L; logic_cfg.a2d[lut].ff_mux = MUX_O6; @@ -1497,7 +1497,7 @@ static int test_logic_config(struct test_state* tstate) if (rc) FAIL(rc); // x, ff-out - memset(&logic_cfg, 0, sizeof(logic_cfg)); + CLEAR(logic_cfg); logic_cfg.a2d[lut].ff = FF_FF; logic_cfg.a2d[lut].ff_mux = MUX_X; logic_cfg.a2d[lut].ff_srinit = FF_SRINIT0; @@ -1510,11 +1510,11 @@ static int test_logic_config(struct test_state* tstate) // . o6-direct logic_cfg.a2d[lut].lut6_str = "A1"; - logic_cfg.a2d[lut].out_used = 1; + logic_cfg.a2d[lut].flags |= OUT_USED; 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 = 0; + logic_cfg.a2d[lut].flags |= OUT_USED; if (idx_enum[type_i] == DEV_LOG_M_OR_L) { // . o6-outmux @@ -1530,9 +1530,9 @@ static int test_logic_config(struct test_state* tstate) // // lut6 direct-out, lut5 mux-out - memset(&logic_cfg, 0, sizeof(logic_cfg)); + CLEAR(logic_cfg); logic_cfg.a2d[lut].lut6_str = "(A6+~A6)*A1"; - logic_cfg.a2d[lut].out_used = 1; + logic_cfg.a2d[lut].flags |= OUT_USED; logic_cfg.a2d[lut].lut5_str = "A1*A2"; logic_cfg.a2d[lut].out_mux = MUX_O5; rc = test_logic(tstate, y, x_enum[x_i], @@ -1606,7 +1606,7 @@ static int test_logic_config(struct test_state* tstate) } if (idx_enum[type_i] == DEV_LOG_X) { // minimum-config X device - memset(&logic_cfg, 0, sizeof(logic_cfg)); + 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].out_mux = MUX_5Q; @@ -1645,7 +1645,7 @@ static int test_logic_config(struct test_state* tstate) continue; } // cout - memset(&logic_cfg, 0, sizeof(logic_cfg)); + 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].cy0 = CY0_O5; @@ -1681,7 +1681,7 @@ static int test_logic_config(struct test_state* tstate) if (rc) FAIL(rc); // f8 out-mux - memset(&logic_cfg, 0, sizeof(logic_cfg)); + 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"; @@ -1703,7 +1703,7 @@ static int test_logic_config(struct test_state* tstate) if (rc) FAIL(rc); // f7amux - memset(&logic_cfg, 0, sizeof(logic_cfg)); + CLEAR(logic_cfg); logic_cfg.a2d[LUT_A].lut6_str = "~A5"; logic_cfg.a2d[LUT_B].lut6_str = "(A5)"; logic_cfg.a2d[LUT_A].out_mux = MUX_F7; @@ -1723,7 +1723,7 @@ static int test_logic_config(struct test_state* tstate) if (rc) FAIL(rc); // f7bmux - memset(&logic_cfg, 0, sizeof(logic_cfg)); + CLEAR(logic_cfg); logic_cfg.a2d[LUT_C].lut6_str = "~A5"; logic_cfg.a2d[LUT_D].lut6_str = "(A5)"; logic_cfg.a2d[LUT_C].out_mux = MUX_F7; diff --git a/libs/bit_frames.c b/libs/bit_frames.c index e1c5106..865e860 100644 --- a/libs/bit_frames.c +++ b/libs/bit_frames.c @@ -1211,7 +1211,7 @@ 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].flags |= OUT_USED; lut5_used = (cfg_ml.a2d[LUT_A].ff_mux == MUX_O5 || cfg_ml.a2d[LUT_A].out_mux == MUX_5Q @@ -1236,7 +1236,7 @@ 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].flags |= OUT_USED; lut5_used = (cfg_ml.a2d[LUT_B].ff_mux == MUX_O5 || cfg_ml.a2d[LUT_B].out_mux == MUX_5Q @@ -1261,7 +1261,7 @@ 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].flags |= OUT_USED; lut5_used = (cfg_ml.a2d[LUT_C].ff_mux == MUX_O5 || cfg_ml.a2d[LUT_C].out_mux == MUX_5Q @@ -1286,7 +1286,7 @@ 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].flags |= OUT_USED; lut5_used = (cfg_ml.a2d[LUT_D].ff_mux == MUX_O5 || cfg_ml.a2d[LUT_D].out_mux == MUX_5Q @@ -1304,7 +1304,7 @@ static int extract_logic(struct extract_state* es) || !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].flags |= OUT_USED; lut5_used = cfg_x.a2d[LUT_A].out_mux != 0; rc = lut2str(lut_X[LUT_A], l_col ? XC6_LMAP_XL_X_A : XC6_LMAP_XM_X_A, @@ -1319,7 +1319,7 @@ static int extract_logic(struct extract_state* es) || !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].flags |= OUT_USED; lut5_used = cfg_x.a2d[LUT_B].out_mux != 0; rc = lut2str(lut_X[LUT_B], l_col ? XC6_LMAP_XL_X_B : XC6_LMAP_XM_X_B, @@ -1334,7 +1334,7 @@ static int extract_logic(struct extract_state* es) || !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].flags |= OUT_USED; lut5_used = cfg_x.a2d[LUT_C].out_mux != 0; rc = lut2str(lut_X[LUT_C], l_col ? XC6_LMAP_XL_X_C : XC6_LMAP_XM_X_C, @@ -1349,7 +1349,7 @@ static int extract_logic(struct extract_state* es) || !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].flags |= OUT_USED; lut5_used = cfg_x.a2d[LUT_D].out_mux != 0; rc = lut2str(lut_X[LUT_D], l_col ? XC6_LMAP_XL_X_D : XC6_LMAP_XM_X_D, diff --git a/libs/control.c b/libs/control.c index 4bbb4be..dee57b2 100644 --- a/libs/control.c +++ b/libs/control.c @@ -415,10 +415,11 @@ int fdev_logic_setconf(struct fpga_model* model, int y, int x, if (!dev) FAIL(EINVAL); rc = reset_required_pins(dev); if (rc) FAIL(rc); + // todo: should we delete the current device configuration? for (lut = LUT_A; lut <= LUT_D; lut++) { - if (logic_cfg->a2d[lut].out_used) - dev->u.logic.a2d[lut].out_used = 1; + if (logic_cfg->a2d[lut].flags & OUT_USED) + dev->u.logic.a2d[lut].flags |= OUT_USED; if (logic_cfg->a2d[lut].lut6_str) { rc = fdev_logic_a2d_lut(model, y, x, type_idx, lut, 6, logic_cfg->a2d[lut].lut6_str, ZTERM); @@ -443,6 +444,22 @@ int fdev_logic_setconf(struct fpga_model* model, int y, int x, 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_ROM) + dev->u.logic.a2d[lut].flags |= LUTMODE_ROM; + 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; @@ -479,7 +496,10 @@ int fdev_logic_a2d_out_used(struct fpga_model* model, int y, int x, rc = reset_required_pins(dev); if (rc) FAIL(rc); - dev->u.logic.a2d[lut_a2d].out_used = (used != 0); + 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: @@ -928,7 +948,7 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type, add_req_inpin(dev, LI_CX); } 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); } diff --git a/libs/floorplan.c b/libs/floorplan.c index 29b875b..0b7dc0d 100644 --- a/libs/floorplan.c +++ b/libs/floorplan.c @@ -328,13 +328,14 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model, cfg = &tile->devs[i].u.logic; for (j = LUT_D; j >= LUT_A; j--) { if (cfg->a2d[j].lut6_str && cfg->a2d[j].lut6_str[0]) - fprintf(f, "%s %c6_lut %s\n", pref, 'A'+j, + 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 %s\n", pref, 'A'+j, + fprintf(f, "%s %c5_lut_str %s\n", pref, 'A'+j, cfg->a2d[j].lut5_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); @@ -431,6 +432,49 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model, break; case 0: break; default: FAIL(EINVAL); } + // distributed memory related: + switch (cfg->a2d[j].ram_mode) { + case DPRAM64: + fprintf(f, "%s %c_ram_mode DPRAM64\n", pref, 'A'+j); + break; + case DPRAM32: + fprintf(f, "%s %c_ram_mode DPRAM32\n", pref, 'A'+j); + break; + case SPRAM64: + fprintf(f, "%s %c_ram_mode SPRAM64\n", pref, 'A'+j); + break; + case SPRAM32: + fprintf(f, "%s %c_ram_mode SPRAM32\n", pref, 'A'+j); + break; + case SRL32: + fprintf(f, "%s %c_ram_mode SRL32\n", pref, 'A'+j); + break; + case SRL16: + fprintf(f, "%s %c_ram_mode SRL16\n", pref, 'A'+j); + break; + case 0: break; default: FAIL(EINVAL); + } + 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_ROM) + fprintf(f, "%s %c_rom\n", pref, 'A'+j); + switch (cfg->a2d[j].di_mux) { + case DIMUX_MC31: + fprintf(f, "%s %c_di_mux MC31\n", pref, 'A'+j); + break; + case DIMUX_X: + fprintf(f, "%s %c_di_mux X\n", pref, 'A'+j); + break; + case DIMUX_DX: + fprintf(f, "%s %c_di_mux DX\n", pref, 'A'+j); + break; + case DIMUX_BDI1: + fprintf(f, "%s %c_di_mux BDI1\n", pref, 'A'+j); + break; + case 0: break; default: FAIL(EINVAL); + } } switch (cfg->clk_inv) { case CLKINV_B: @@ -487,8 +531,10 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx, const char* w1, int w1_len, const char* w2, int w2_len) { struct fpga_device* dev; - char cmp_str[128]; - int i, rc; + char cmp_str[128], buf[32]; + char *endptr; + long int val; + int i, j, rc; dev = fdev_p(model, y, x, DEV_LOGIC, type_idx); if (!dev) { HERE(); return 0; } @@ -497,7 +543,12 @@ 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; + } + 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_ROM; goto inst_1; } } @@ -520,13 +571,13 @@ 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++) { - snprintf(cmp_str, sizeof(cmp_str), "%c6_lut", 'A'+i); + 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; goto inst_2; } - snprintf(cmp_str, sizeof(cmp_str), "%c5_lut", 'A'+i); + 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; @@ -614,6 +665,70 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx, else return 0; goto inst_2; } + snprintf(cmp_str, sizeof(cmp_str), "%c_ram_mode", 'A'+i); + if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) { + if (!str_cmp(w2, w2_len, "DPRAM64", ZTERM)) + dev->u.logic.a2d[i].ram_mode = DPRAM64; + else if (!str_cmp(w2, w2_len, "DPRAM32", ZTERM)) + dev->u.logic.a2d[i].ram_mode = DPRAM32; + else if (!str_cmp(w2, w2_len, "SPRAM64", ZTERM)) + dev->u.logic.a2d[i].ram_mode = SPRAM64; + else if (!str_cmp(w2, w2_len, "SPRAM32", ZTERM)) + dev->u.logic.a2d[i].ram_mode = SPRAM32; + else if (!str_cmp(w2, w2_len, "SRL32", ZTERM)) + dev->u.logic.a2d[i].ram_mode = SRL32; + else if (!str_cmp(w2, w2_len, "SRL16", ZTERM)) + dev->u.logic.a2d[i].ram_mode = SRL16; + else return 0; + 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) return 0; + errno = 0; + for (j = 2; j < w2_len; j++) + buf[j-2] = w2[j]; + buf[j-2] = 0; + val = strtol(buf, &endptr, /*base*/ 16); + if (errno || *endptr) 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_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 = strtol(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; + } + 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)) + dev->u.logic.a2d[i].di_mux = DIMUX_MC31; + else if (!str_cmp(w2, w2_len, "X", ZTERM)) + dev->u.logic.a2d[i].di_mux = DIMUX_X; + else if (!str_cmp(w2, w2_len, "DX", ZTERM)) + dev->u.logic.a2d[i].di_mux = DIMUX_DX; + else if (!str_cmp(w2, w2_len, "BDI1", ZTERM)) + dev->u.logic.a2d[i].di_mux = DIMUX_BDI1; + else return 0; + goto inst_2; + } } if (!str_cmp(w1, w1_len, "clk", ZTERM)) { if (!str_cmp(w2, w2_len, "CLK_B", ZTERM)) diff --git a/libs/model.h b/libs/model.h index 8b98c5a..36d991d 100644 --- a/libs/model.h +++ b/libs/model.h @@ -416,6 +416,10 @@ 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_ROM 0x0008 enum { FF_SRINIT0 = 1, FF_SRINIT1 }; enum { MUX_O6 = 1, MUX_O5, MUX_5Q, MUX_X, MUX_CY, MUX_XOR, MUX_F7, MUX_F8, MUX_MC31 }; enum { FF_OR2L = 1, FF_AND2L, FF_LATCH, FF_FF }; @@ -424,13 +428,23 @@ enum { CLKINV_B = 1, CLKINV_CLK }; enum { SYNCATTR_SYNC = 1, SYNCATTR_ASYNC }; enum { WEMUX_WE = 1, WEMUX_CE }; enum { PRECYINIT_0 = 1, PRECYINIT_1, PRECYINIT_AX }; +enum { DPRAM64 = 1, DPRAM32, SPRAM64, SPRAM32, SRL32, SRL16 }; +enum { DIMUX_MC31 = 1, DIMUX_X, DIMUX_DX, DIMUX_BDI1 }; #define MAX_LUT_LEN 2048 #define NUM_LUTS 4 struct fpgadev_logic_a2d { - int out_used; + // LUT/RAM/ROM mode: + // - Both the lut6 and lut5 must have the same mode of either + // LUT, RAM or ROM. + // - If neither LUT6VAL_SET nor LUT5VAL_SET are on, the mode is LUT. + // - If either LUT6VAL_SET or LUT5VAL_SET are on, lut6_str and + // lut5_str are ignored, and the mode is RAM, or ROM if + // LUTMODE_ROM is on. + + int flags; // OUT_USED, LUT6VAL_SET, LUT5VAL_SET, LUTMODE_ROM char* lut6_str; char* lut5_str; int ff_mux; // O6, O5, X, F7(a/c), F8(b), MC31(d), CY, XOR @@ -439,6 +453,14 @@ struct fpgadev_logic_a2d int out_mux; // O6, O5, 5Q, F7(a/c), F8(b), MC31(d), CY, XOR 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; + int ram_mode; // only if LUTMODE_ROM is not set + // DPRAM64, DPRAM32, SPRAM64, SPRAM32, SRL32, SRL16 + int di_mux; // only for A-C + // DIMUX_MC31, DIMUX_X, DIMUX_DX (b/c), DIMUX_BDI1 (a) }; struct fpgadev_logic