diff --git a/model.h b/model.h index 8764a31..e7b55a1 100644 --- a/model.h +++ b/model.h @@ -467,6 +467,9 @@ enum logicout_wire { /* 18 */ M_C, M_CMUX, M_CQ, M_D, M_DMUX, M_DQ }; +const char* logicin_str(enum logicin_wire w); +const char* logicout_str(enum logicout_wire w); + // The extra wires must not overlap with logicin_wire or logicout_wire // namespaces so that they can be combined with either of them. enum extra_wires { diff --git a/model_helper.c b/model_helper.c index ed730d9..91984d2 100644 --- a/model_helper.c +++ b/model_helper.c @@ -604,3 +604,107 @@ const char* logicin_s(int wire, int routing_io) return pf("INT_IOI_LOGICIN_B%i", wire & LWF_WIRE_MASK); return pf("LOGICIN_B%i", wire & LWF_WIRE_MASK); } + +const char* logicin_str(enum logicin_wire w) +{ + switch (w) { + case M_A1: + case X_A1: return "A1"; + case M_A2: + case X_A2: return "A2"; + case M_A3: + case X_A3: return "A3"; + case M_A4: + case X_A4: return "A4"; + case M_A5: + case X_A5: return "A5"; + case M_A6: + case X_A6: return "A6"; + case M_AX: + case X_AX: return "AX"; + case M_B1: + case X_B1: return "B1"; + case M_B2: + case X_B2: return "B2"; + case M_B3: + case X_B3: return "B3"; + case M_B4: + case X_B4: return "B4"; + case M_B5: + case X_B5: return "B5"; + case M_B6: + case X_B6: return "B6"; + case M_BX: + case X_BX: return "BX"; + case M_C1: + case X_C1: return "C1"; + case M_C2: + case X_C2: return "C2"; + case M_C3: + case X_C3: return "C3"; + case M_C4: + case X_C4: return "C4"; + case M_C5: + case X_C5: return "C5"; + case M_C6: + case X_C6: return "C6"; + case M_CE: + case X_CE: return "CE"; + case M_CX: + case X_CX: return "CX"; + case M_D1: + case X_D1: return "D1"; + case M_D2: + case X_D2: return "D2"; + case M_D3: + case X_D3: return "D3"; + case M_D4: + case X_D4: return "D4"; + case M_D5: + case X_D5: return "D5"; + case M_D6: + case X_D6: return "D6"; + case M_DX: + case X_DX: return "DX"; + + case M_AI: return "AI"; + case M_BI: return "BI"; + case M_CI: return "CI"; + case M_DI: return "DI"; + case M_WE: return "WE"; + } + ABORT(1); + return 0; +} + +const char* logicout_str(enum logicout_wire w) +{ + switch (w) { + case X_A: + case M_A: return "A"; + case X_AMUX: + case M_AMUX: return "AMUX"; + case X_AQ: + case M_AQ: return "AQ"; + case X_B: + case M_B: return "B"; + case X_BMUX: + case M_BMUX: return "BMUX"; + case X_BQ: + case M_BQ: return "BQ"; + case X_C: + case M_C: return "C"; + case X_CMUX: + case M_CMUX: return "CMUX"; + case X_CQ: + case M_CQ: return "CQ"; + case X_D: + case M_D: return "D"; + case X_DMUX: + case M_DMUX: return "DMUX"; + case X_DQ: + case M_DQ: return "DQ"; + } + ABORT(1); + return 0; +} diff --git a/model_main.c b/model_main.c index 92e39e5..9a1aa54 100644 --- a/model_main.c +++ b/model_main.c @@ -35,10 +35,8 @@ int fpga_build_model(struct fpga_model* model, int fpga_rows, const char* column rc = init_ports(model); if (rc) return rc; -#if 0 rc = init_conns(model); if (rc) return rc; -#endif rc = init_switches(model); if (rc) return rc; diff --git a/model_switches.c b/model_switches.c index aa22da1..a08833f 100644 --- a/model_switches.c +++ b/model_switches.c @@ -13,16 +13,19 @@ static int init_io_switches(struct fpga_model* model); static int init_routing_switches(struct fpga_model* model); static int init_north_south_dirwire_term(struct fpga_model* model); static int init_iologic_switches(struct fpga_model* model); +static int init_logic_switches(struct fpga_model* model); int init_switches(struct fpga_model* model) { int rc; -// todo: IO_OUTER_B, IO_INNER_B, LOGIC_XM - rc = init_iologic_switches(model); + rc = init_logic_switches(model); if (rc) goto xout; return 0; + rc = init_iologic_switches(model); + if (rc) goto xout; + rc = init_north_south_dirwire_term(model); if (rc) goto xout; @@ -39,6 +42,114 @@ xout: return rc; } +static int init_logic_tile(struct fpga_model* model, int y, int x) +{ + int rc, i, j, ml; + const char* xp; + + if (has_device(model, y, x, DEV_LOGIC_M)) { + ml = 'M'; + xp = "X"; + } else if (has_device(model, y, x, DEV_LOGIC_L)) { + ml = 'L'; + xp = "XX"; + } else + ABORT(1); + + if ((rc = add_switch(model, y, x, + pf("CLEX%c_CLK0", ml), pf("%s_CLK", xp), 0 /* bidir */))) goto xout; + if ((rc = add_switch(model, y, x, + pf("CLEX%c_CLK1", ml), pf("%c_CLK", ml), 0 /* bidir */))) goto xout; + if ((rc = add_switch(model, y, x, + pf("CLEX%c_SR0", ml), pf("%s_SR", xp), 0 /* bidir */))) goto xout; + if ((rc = add_switch(model, y, x, + pf("CLEX%c_SR1", ml), pf("%c_SR", ml), 0 /* bidir */))) goto xout; + for (i = X_A1; i <= X_DX; i++) { + if ((rc = add_switch(model,y, x, + pf("CLEX%c_LOGICIN_B%i", ml, i), + pf("%s_%s", xp, logicin_str(i)), + 0 /* bidir */))) goto xout; + } + for (i = M_A1; i <= M_WE; i++) { + if (ml == 'L' && + (i == M_AI || i == M_BI || i == M_CI + || i == M_DI || i == M_WE)) + continue; + if ((rc = add_switch(model,y, x, + pf("CLEX%c_LOGICIN_B%i", ml, i), + pf("%c_%s", ml, logicin_str(i)), + 0 /* bidir */))) goto xout; + } + for (i = X_A; i <= X_DQ; i++) { + if ((rc = add_switch(model, y, x, + pf("%s_%s", xp, logicout_str(i)), + pf("CLEX%c_LOGICOUT%i", ml, i), + 0 /* bidir */))) goto xout; + } + for (i = M_A; i <= M_DQ; i++) { + if ((rc = add_switch(model, y, x, + pf("%c_%s", ml, logicout_str(i)), + pf("CLEX%c_LOGICOUT%i", ml, i), + 0 /* bidir */))) goto xout; + } + for (i = 'A'; i <= 'D'; i++) { + for (j = 1; j <= 6; j++) { + if ((rc = add_switch(model, y, x, + pf("%c_%c%i", ml, i, j), + pf("%c_%c", ml, i), + 0 /* bidir */))) goto xout; + if ((rc = add_switch(model, y, x, + pf("%s_%c%i", xp, i, j), + pf("%s_%c", xp, i), + 0 /* bidir */))) goto xout; + } + if ((rc = add_switch(model, y, x, + pf("%c_%c", ml, i), + pf("%c_%cMUX", ml, i), + 0 /* bidir */))) goto xout; + } + if (ml == 'L') { + if (has_connpt(model, y, x, "XL_COUT_N")) { + if ((rc = add_switch(model, y, x, + "XL_COUT", "XL_COUT_N", + 0 /* bidir */))) goto xout; + } + if ((rc = add_switch(model, y, x, + "XL_COUT", "L_DMUX", 0 /* bidir */))) goto xout; + } else { + if (has_connpt(model, y, x, "M_COUT_N")) { + if ((rc = add_switch(model, y, x, + "M_COUT", "M_COUT_N", + 0 /* bidir */))) goto xout; + } + if ((rc = add_switch(model, y, x, + "M_COUT", "M_DMUX", 0 /* bidir */))) goto xout; + } + return 0; +xout: + return rc; +} + +static int init_logic_switches(struct fpga_model* model) +{ + int x, y, rc; + + for (x = LEFT_SIDE_WIDTH; x < model->x_width-RIGHT_SIDE_WIDTH; x++) { + if (!is_atx(X_LOGIC_COL, model, x)) + continue; + for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) { + if (has_device(model, y, x, DEV_LOGIC_M) + || has_device(model, y, x, DEV_LOGIC_L)) { + rc = init_logic_tile(model, y, x); + if (rc) goto xout; + } + } + } + return 0; +xout: + return rc; +} + static int init_iologic_tile(struct fpga_model* model, int y, int x) { int i, j, rc; diff --git a/new_fp.c b/new_fp.c index 9d46ea9..b711b89 100644 --- a/new_fp.c +++ b/new_fp.c @@ -25,12 +25,16 @@ int printf_switches(struct fpga_model* model); int main(int argc, char** argv) { struct fpga_model model; - int rc; + int no_conns, rc; if ((rc = fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS, XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING))) goto fail; + no_conns = 0; + if (argc > 1 && !strcmp(argv[1], "--no-conns")) + no_conns = 1; + printf("fpga_floorplan_format 1\n"); // @@ -59,8 +63,10 @@ int main(int argc, char** argv) rc = printf_ports(&model); if (rc) goto fail; - rc = printf_conns(&model); - if (rc) goto fail; + if (!no_conns) { + rc = printf_conns(&model); + if (rc) goto fail; + } rc = printf_switches(&model); if (rc) goto fail;