preparing for distributed memory support
This commit is contained in:
parent
7d90449ab4
commit
b1100a56b3
38
autotest.c
38
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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
131
libs/floorplan.c
131
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))
|
||||
|
|
24
libs/model.h
24
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
|
||||
|
|
Loading…
Reference in New Issue
Block a user