diff --git a/Makefile b/Makefile index 5a1b770..2fd0b35 100644 --- a/Makefile +++ b/Makefile @@ -112,9 +112,9 @@ compare.%: xc6slx9_empty.% %.devs: %.fp @cat $<|awk '{if ($$1=="dev") {if ($$6=="type") printf "%s %s %s %s\n",$$2,$$3,$$4,$$7; else printf "%s %s %s\n",$$2,$$3,$$4; }}'|sort >$@ -%.nets: %.fp pair2net +%.cnets: %.fp pair2net cat $<|awk '{if ($$1=="conn") printf "%s-%s-%s %s-%s-%s\n",$$2,$$3,$$4,$$5,$$6,$$7}' |./pair2net -|sort >$@ - @echo Number of nets: + @echo Number of conn nets: @cat $@|wc -l @echo Number of connection points: @cat $@|wc -w @@ -143,15 +143,15 @@ clean: pair2net pair2net.o \ xc6slx9_empty.fp xc6slx9.svg \ xc6slx9_empty.tiles xc6slx9_empty.devs xc6slx9_empty.conns \ - xc6slx9_empty.ports xc6slx9_empty.sw xc6slx9_empty.nets \ + xc6slx9_empty.ports xc6slx9_empty.sw xc6slx9_empty.cnets \ compare_other.tiles compare_other.devs compare_other.conns compare_other.ports \ - compare_other.sw compare_other.nets \ + compare_other.sw compare_other.cnets \ compare_tiles_matching.txt compare_tiles_diff.txt compare_tiles_extra.txt \ compare_devs_matching.txt compare_devs_diff.txt compare_devs_extra.txt \ compare_conns_matching.txt compare_conns_diff.txt compare_conns_extra.txt \ compare_ports_matching.txt compare_ports_diff.txt compare_ports_extra.txt \ compare_sw_matching.txt compare_sw_diff.txt compare_sw_extra.txt \ - compare_nets_matching.txt compare_nets_diff.txt compare_nets_extra.txt + compare_cnets_matching.txt compare_cnets_diff.txt compare_cnets_extra.txt install: all mkdir -p $(DESTDIR)/$(PREFIX)/bin/ diff --git a/autotest.c b/autotest.c index 6d2d429..009e3db 100644 --- a/autotest.c +++ b/autotest.c @@ -167,14 +167,14 @@ int main(int argc, char** argv) rc = diff_printf(&tstate); if (rc) FAIL(rc); -printf("P46 I pinw %s\n", strarray_lookup(&model.str, P46_dev->iob.pinw_out_I)); +printf("P46 I pinw %s\n", strarray_lookup(&model.str, P46_dev->pinw_out[IOB_OUT_I])); switch_to.yx_req = YX_DEV_ILOGIC; switch_to.flags = SWTO_YX_DEF; switch_to.model = &model; switch_to.y = P46_y; switch_to.x = P46_x; - switch_to.start_switch = P46_dev->iob.pinw_out_I; + switch_to.start_switch = P46_dev->pinw_out[IOB_OUT_I]; rc = fpga_switch_to_yx(&switch_to); if (rc) FAIL(rc); rc = fpga_switch_set_enable(&model, switch_to.y, switch_to.x, &switch_to.set); @@ -216,7 +216,7 @@ printf(" %s\n", fmt_swset(&model, switch_to.y, switch_to.x, &switch_to.set, SW_F struct sw_chain c = { .model = &model, .y = switch_to.dest_y, .x = switch_to.dest_x+1, - .start_switch = logic_dev->logic.pinw_in[LUT_D][LUT_3], + .start_switch = logic_dev->pinw_in[LOGIC_IN_D3], .from_to = SW_TO, .max_chain_size = MAX_SW_DEPTH }; if (fpga_switch_chain(&c) == NO_CONN) FAIL(EINVAL); if (c.set.len == 0) { HERE(); FAIL(EINVAL); } @@ -248,7 +248,7 @@ printf(" %s\n", fmt_swset(&model, c.y, c.x, &c.set, SW_FROM)); if (rc) FAIL(rc); printf("\n"); - printf("P48 O pinw %s\n", strarray_lookup(&model.str, P48_dev->iob.pinw_in_O)); + printf("P48 O pinw %s\n", strarray_lookup(&model.str, P48_dev->pinw_in[IOB_IN_O])); printf("\n"); printf("O Test suite completed.\n"); diff --git a/bit_frames.c b/bit_frames.c index 4bed89a..279b38d 100644 --- a/bit_frames.c +++ b/bit_frames.c @@ -106,7 +106,8 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits) if (!dev) FAIL(rc); // we only support 2 hardcoded types of IOB right now - if (u32_p[0] == 0x00000100 + // todo: bit 7 goes on when out-net connected? + if ((u32_p[0] & 0xFFFFFF7F) == 0x00000100 && u32_p[1] == 0x06001100) { dev->instantiated = 1; strcpy(dev->iob.ostandard, IO_LVCMOS33); diff --git a/control.c b/control.c index cba4cd6..b035100 100644 --- a/control.c +++ b/control.c @@ -426,13 +426,13 @@ int fpga_switch_is_bidir(struct fpga_model* model, int y, int x, int fpga_switch_is_enabled(struct fpga_model* model, int y, int x, swidx_t swidx) { - return (YX_TILE(model, y, x)->switches[swidx] & SWITCH_ON) != 0; + return (YX_TILE(model, y, x)->switches[swidx] & SWITCH_USED) != 0; } void fpga_switch_enable(struct fpga_model* model, int y, int x, swidx_t swidx) { - YX_TILE(model, y, x)->switches[swidx] |= SWITCH_ON; + YX_TILE(model, y, x)->switches[swidx] |= SWITCH_USED; } int fpga_switch_set_enable(struct fpga_model* model, int y, int x, @@ -447,7 +447,7 @@ int fpga_switch_set_enable(struct fpga_model* model, int y, int x, void fpga_switch_disable(struct fpga_model* model, int y, int x, swidx_t swidx) { - YX_TILE(model, y, x)->switches[swidx] &= ~SWITCH_ON; + YX_TILE(model, y, x)->switches[swidx] &= ~SWITCH_USED; } #define SW_BUF_SIZE 256 diff --git a/floorplan.c b/floorplan.c index 8530956..73e1674 100644 --- a/floorplan.c +++ b/floorplan.c @@ -638,7 +638,7 @@ int printf_switches(FILE* f, struct fpga_model* model, int enabled_only) from_connpt_o = (tile->switches[i] & 0x3FFF8000) >> 15; to_connpt_o = tile->switches[i] & 0x00007FFF; is_bidirectional = (tile->switches[i] & SWITCH_BIDIRECTIONAL) != 0; - is_on = (tile->switches[i] & SWITCH_ON) != 0; + is_on = (tile->switches[i] & SWITCH_USED) != 0; from_str_i = tile->conn_point_names[from_connpt_o*2+1]; to_str_i = tile->conn_point_names[to_connpt_o*2+1]; @@ -859,6 +859,8 @@ int write_floorplan(FILE* f, struct fpga_model* model, int flags) rc = printf_switches(f, model, /*enabled_only*/ 1); if (rc) FAIL(rc); +// net 0 input y00 x00 name output y00 x00 name sw y00 x00 from -> to + return 0; fail: return rc; diff --git a/model.h b/model.h index 3e6d4c1..86a285a 100644 --- a/model.h +++ b/model.h @@ -342,24 +342,31 @@ enum fpgadev_type // data can safely be initialized to 0 meaning unconfigured. enum { LOGIC_M = 1, LOGIC_L, LOGIC_X }; -// LUT_ macros to make the pinw arrays more readable -enum { LUT_A = 0, LUT_B, LUT_C, LUT_D }; -enum { LUT_1 = 0, LUT_2, LUT_3, LUT_4, LUT_5, LUT_6 }; +// All LOGICIN_IN A..D sequences must be exactly sequential as +// here to match initialization in model_device:init_logic(). +enum { LOGIC_IN_A1 = 0, LOGIC_IN_A2, LOGIC_IN_A3, LOGIC_IN_A4, LOGIC_IN_A5, + LOGIC_IN_A6, + LOGIC_IN_B1, LOGIC_IN_B2, LOGIC_IN_B3, LOGIC_IN_B4, LOGIC_IN_B5, + LOGIC_IN_B6, + LOGIC_IN_C1, LOGIC_IN_C2, LOGIC_IN_C3, LOGIC_IN_C4, LOGIC_IN_C5, + LOGIC_IN_C6, + LOGIC_IN_D1, LOGIC_IN_D2, LOGIC_IN_D3, LOGIC_IN_D4, LOGIC_IN_D5, + LOGIC_IN_D6, + LOGIC_IN_AX, LOGIC_IN_BX, LOGIC_IN_CX, LOGIC_IN_DX, + LOGIC_IN_CLK, LOGIC_IN_CE, LOGIC_IN_SR, + // only for L and M: + LOGIC_IN_CIN, // only some L and M devs have this + // only for M: + LOGIC_IN_WE, LOGIC_IN_AI, LOGIC_IN_BI, LOGIC_IN_CI, LOGIC_IN_DI, + LOGIC_NUM_PINW_IN }; +enum { LOGIC_OUT_A = 0, LOGIC_OUT_B, LOGIC_OUT_C, LOGIC_OUT_D, + LOGIC_OUT_AMUX, LOGIC_OUT_BMUX, LOGIC_OUT_CMUX, LOGIC_OUT_DMUX, + LOGIC_OUT_AQ, LOGIC_OUT_BQ, LOGIC_OUT_CQ, LOGIC_OUT_DQ, + LOGIC_OUT_COUT, // only some L and M devs have this + LOGIC_NUM_PINW_OUT }; struct fpgadev_logic { - // pinwires that don't exist for a specific device - // will be set to STRIDX_NO_ENTRY - - // for X, L and M: - str16_t pinw_in[4][6], pinw_in_X[4]; - str16_t pinw_in_CLK, pinw_in_CE, pinw_in_SR; - str16_t pinw_out[4], pinw_out_MUX[4], pinw_out_Q[4]; - // only for L and M: - str16_t pinw_in_CIN, pinw_out_COUT; // not all devs have this - // only for M: - str16_t pinw_in_WE, pinw_in_I[4]; - int subtype; // LOGIC_M, LOGIC_L or LOGIC_X int A_used, B_used, C_used, D_used; char* A6_lut, *B6_lut, *C6_lut, *D6_lut; @@ -378,17 +385,13 @@ enum { ITERM_NONE = 1, ITERM_UNTUNED_25, ITERM_UNTUNED_50, enum { OTERM_NONE = 1, OTERM_UNTUNED_25, OTERM_UNTUNED_50, OTERM_UNTUNED_75 }; +enum { IOB_IN_O = 0, IOB_IN_T, IOB_IN_DIFFI_IN, IOB_IN_DIFFO_IN, + IOB_NUM_PINW_IN }; +enum { IOB_OUT_I = 0, IOB_OUT_PADOUT, IOB_OUT_PCI_RDY, IOB_OUT_DIFFO_OUT, + IOB_NUM_PINW_OUT }; + struct fpgadev_iob { - str16_t pinw_in_O; - str16_t pinw_in_T; - str16_t pinw_out_I; - str16_t pinw_out_PADOUT; - str16_t pinw_out_PCI_RDY; - str16_t pinw_in_DIFFI_IN; - str16_t pinw_in_DIFFO_IN; - str16_t pinw_out_DIFFO_OUT; - int subtype; // IOBM or IOBS IOSTANDARD istandard; IOSTANDARD ostandard; @@ -402,17 +405,26 @@ struct fpgadev_iob int out_term; }; +#define MAX_PINW_IN 64 +#define MAX_PINW_OUT 32 + struct fpga_device { enum fpgadev_type type; int instantiated; + int num_in_wires, num_out_wires; + // pinwires that are within the type-range of a device, but + // don't exist for that particular instance, will be set to + // STRIDX_NO_ENTRY + str16_t pinw_in[MAX_PINW_IN]; + str16_t pinw_out[MAX_PINW_OUT]; union { struct fpgadev_logic logic; struct fpgadev_iob iob; }; }; -#define SWITCH_ON 0x80000000 +#define SWITCH_USED 0x80000000 #define SWITCH_BIDIRECTIONAL 0x40000000 #define SWITCH_MAX_CONNPT_O 0x7FFF // 15 bits #define SW_FROM_I(u32) (((u32) >> 15) & SWITCH_MAX_CONNPT_O) diff --git a/model_devices.c b/model_devices.c index d49cc23..85a857c 100644 --- a/model_devices.c +++ b/model_devices.c @@ -327,7 +327,7 @@ void free_devices(struct fpga_model* model) } } -#define DEV_INCREMENT 8 +#define DEV_INCREMENT 4 static int add_dev(struct fpga_model* model, int y, int x, int type, int subtype) @@ -386,32 +386,33 @@ static int init_iob(struct fpga_model* model, int y, int x, snprintf(tmp_str, sizeof(tmp_str), "%s_O%i_PINW", prefix, type_idx); rc = add_connpt_name(model, y, x, tmp_str, /*dup_warn*/ 1, - &tile->devs[idx].iob.pinw_in_O, 0); + &tile->devs[idx].pinw_in[IOB_IN_O], 0); if (rc) FAIL(rc); - snprintf(tmp_str, sizeof(tmp_str), "%s_T%i_PINW", prefix, type_idx); rc = add_connpt_name(model, y, x, tmp_str, /*dup_warn*/ 1, - &tile->devs[idx].iob.pinw_in_T, 0); - if (rc) FAIL(rc); - snprintf(tmp_str, sizeof(tmp_str), "%s_IBUF%i_PINW", prefix, type_idx); - rc = add_connpt_name(model, y, x, tmp_str, /*dup_warn*/ 1, - &tile->devs[idx].iob.pinw_out_I, 0); - if (rc) FAIL(rc); - snprintf(tmp_str, sizeof(tmp_str), "%s_PADOUT%i", prefix, type_idx); - rc = add_connpt_name(model, y, x, tmp_str, /*dup_warn*/ 1, - &tile->devs[idx].iob.pinw_out_PADOUT, 0); + &tile->devs[idx].pinw_in[IOB_IN_T], 0); if (rc) FAIL(rc); snprintf(tmp_str, sizeof(tmp_str), "%s_DIFFI_IN%i", prefix, type_idx); rc = add_connpt_name(model, y, x, tmp_str, /*dup_warn*/ 1, - &tile->devs[idx].iob.pinw_in_DIFFI_IN, 0); + &tile->devs[idx].pinw_in[IOB_IN_DIFFI_IN], 0); if (rc) FAIL(rc); snprintf(tmp_str, sizeof(tmp_str), "%s_DIFFO_IN%i", prefix, type_idx); rc = add_connpt_name(model, y, x, tmp_str, /*dup_warn*/ 1, - &tile->devs[idx].iob.pinw_in_DIFFO_IN, 0); + &tile->devs[idx].pinw_in[IOB_IN_DIFFO_IN], 0); + if (rc) FAIL(rc); + tile->devs[idx].num_in_wires = IOB_NUM_PINW_IN; + + snprintf(tmp_str, sizeof(tmp_str), "%s_IBUF%i_PINW", prefix, type_idx); + rc = add_connpt_name(model, y, x, tmp_str, /*dup_warn*/ 1, + &tile->devs[idx].pinw_out[IOB_OUT_I], 0); + if (rc) FAIL(rc); + snprintf(tmp_str, sizeof(tmp_str), "%s_PADOUT%i", prefix, type_idx); + rc = add_connpt_name(model, y, x, tmp_str, /*dup_warn*/ 1, + &tile->devs[idx].pinw_out[IOB_OUT_PADOUT], 0); if (rc) FAIL(rc); snprintf(tmp_str, sizeof(tmp_str), "%s_DIFFO_OUT%i", prefix, type_idx); rc = add_connpt_name(model, y, x, tmp_str, /*dup_warn*/ 1, - &tile->devs[idx].iob.pinw_out_DIFFO_OUT, 0); + &tile->devs[idx].pinw_out[IOB_OUT_DIFFO_OUT], 0); if (rc) FAIL(rc); if (!x && y == model->center_y - CENTER_TOP_IOB_O && type_idx == 1) @@ -427,8 +428,9 @@ static int init_iob(struct fpga_model* model, int y, int x, "%s_PCI_RDY%i", prefix, type_idx); } rc = add_connpt_name(model, y, x, tmp_str, /*dup_warn*/ 1, - &tile->devs[idx].iob.pinw_out_PCI_RDY, 0); + &tile->devs[idx].pinw_out[IOB_OUT_PCI_RDY], 0); if (rc) FAIL(rc); + tile->devs[idx].num_out_wires = IOB_NUM_PINW_OUT; return 0; fail: return rc; @@ -452,56 +454,56 @@ static int init_logic(struct fpga_model* model, int y, int x, ? "XX_" : "X_"; } else FAIL(EINVAL); - for (i = LUT_A; i <= LUT_D; i++) { - for (j = LUT_1; j <= LUT_6; j++) { + for (i = 0; i < 4; i++) { // 'A' to 'D' + for (j = 0; j < 6; j++) { rc = add_connpt_name(model, y, x, pf("%s%c%i", pre, 'A'+i, j+1), /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_in[i][j], 0); + &tile->devs[idx].pinw_in[LOGIC_IN_A1+i*6+j], 0); if (rc) FAIL(rc); } rc = add_connpt_name(model, y, x, pf("%s%cX", pre, 'A'+i), /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_in_X[i], 0); + &tile->devs[idx].pinw_in[LOGIC_IN_AX+i], 0); if (rc) FAIL(rc); if (subtype == LOGIC_M) { rc = add_connpt_name(model, y, x, pf("%s%cI", pre, 'A'+i), /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_in_I[i], 0); + &tile->devs[idx].pinw_in[LOGIC_IN_AI+i], 0); if (rc) FAIL(rc); } else - tile->devs[idx].logic.pinw_in_I[i] = STRIDX_NO_ENTRY; + tile->devs[idx].pinw_in[LOGIC_IN_AI+i] = STRIDX_NO_ENTRY; rc = add_connpt_name(model, y, x, pf("%s%c", pre, 'A'+i), /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_out[i], 0); + &tile->devs[idx].pinw_out[LOGIC_OUT_A+i], 0); if (rc) FAIL(rc); rc = add_connpt_name(model, y, x, pf("%s%cMUX", pre, 'A'+i), /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_out_MUX[i], 0); + &tile->devs[idx].pinw_out[LOGIC_OUT_AMUX+i], 0); if (rc) FAIL(rc); rc = add_connpt_name(model, y, x, pf("%s%cQ", pre, 'A'+i), /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_out_Q[i], 0); + &tile->devs[idx].pinw_out[LOGIC_OUT_AQ+i], 0); if (rc) FAIL(rc); } rc = add_connpt_name(model, y, x, pf("%sCLK", pre), /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_in_CLK, 0); + &tile->devs[idx].pinw_in[LOGIC_IN_CLK], 0); if (rc) FAIL(rc); rc = add_connpt_name(model, y, x, pf("%sCE", pre), /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_in_CE, 0); + &tile->devs[idx].pinw_in[LOGIC_IN_CE], 0); if (rc) FAIL(rc); rc = add_connpt_name(model, y, x, pf("%sSR", pre), /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_in_SR, 0); + &tile->devs[idx].pinw_in[LOGIC_IN_SR], 0); if (rc) FAIL(rc); if (subtype == LOGIC_M) { rc = add_connpt_name(model, y, x, pf("%sWE", pre), /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_in_WE, 0); + &tile->devs[idx].pinw_in[LOGIC_IN_WE], 0); if (rc) FAIL(rc); } else - tile->devs[idx].logic.pinw_in_WE = STRIDX_NO_ENTRY; + tile->devs[idx].pinw_in[LOGIC_IN_WE] = STRIDX_NO_ENTRY; if (subtype != LOGIC_X && ((is_atx(X_ROUTING_NO_IO, model, x-1) && is_aty(Y_INNER_BOTTOM, model, y+1)) @@ -509,22 +511,25 @@ static int init_logic(struct fpga_model* model, int y, int x, && is_aty(Y_BOT_INNER_IO, model, y+1)))) { rc = add_connpt_name(model, y, x, pf("%sCIN", pre), /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_in_CIN, 0); + &tile->devs[idx].pinw_in[LOGIC_IN_CIN], 0); if (rc) FAIL(rc); } else - tile->devs[idx].logic.pinw_in_CIN = STRIDX_NO_ENTRY; + tile->devs[idx].pinw_in[LOGIC_IN_CIN] = STRIDX_NO_ENTRY; if (subtype == LOGIC_M) { rc = add_connpt_name(model, y, x, "M_COUT", /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_out_COUT, 0); + &tile->devs[idx].pinw_out[LOGIC_OUT_COUT], 0); if (rc) FAIL(rc); } else if (subtype == LOGIC_L) { rc = add_connpt_name(model, y, x, "XL_COUT", /*dup_warn*/ 1, - &tile->devs[idx].logic.pinw_out_COUT, 0); + &tile->devs[idx].pinw_out[LOGIC_OUT_COUT], 0); if (rc) FAIL(rc); } else - tile->devs[idx].logic.pinw_out_COUT = STRIDX_NO_ENTRY; + tile->devs[idx].pinw_out[LOGIC_OUT_COUT] = STRIDX_NO_ENTRY; + + tile->devs[idx].num_in_wires = LOGIC_NUM_PINW_IN; + tile->devs[idx].num_out_wires = LOGIC_NUM_PINW_OUT; return 0; fail: return rc;