diff --git a/autotest.c b/autotest.c index d965039..c4a34c0 100644 --- a/autotest.c +++ b/autotest.c @@ -81,7 +81,7 @@ static int diff_printf(struct test_state* tstate) rc = printf_devices(dest_f, tstate->model, /*config_only*/ 1); if (rc) FAIL(rc); - rc = printf_switches(dest_f, tstate->model, /*enabled_only*/ 1); + rc = printf_nets(dest_f, tstate->model); if (rc) FAIL(rc); fclose(dest_f); @@ -108,7 +108,7 @@ int main(int argc, char** argv) struct fpga_model model; struct fpga_device* P46_dev, *P48_dev, *logic_dev; int P46_y, P46_x, P46_dev_idx, P46_type_idx; - int P48_y, P48_x, P48_dev_idx, P48_type_idx, dev_idx, rc; + int P48_y, P48_x, P48_dev_idx, P48_type_idx, logic_dev_idx, rc; struct test_state tstate; struct switch_to_yx switch_to; net_idx_t P46_net; @@ -161,9 +161,9 @@ int main(int argc, char** argv) P48_dev->iob.suspend = SUSP_3STATE; // configure logic - dev_idx = fpga_dev_idx(&model, /*y*/ 68, /*x*/ 13, DEV_LOGIC, DEV_LOGX); - if (dev_idx == NO_DEV) FAIL(EINVAL); - logic_dev = FPGA_DEV(&model, /*y*/ 68, /*x*/ 13, dev_idx); + logic_dev_idx = fpga_dev_idx(&model, /*y*/ 68, /*x*/ 13, DEV_LOGIC, DEV_LOGX); + if (logic_dev_idx == NO_DEV) FAIL(EINVAL); + logic_dev = FPGA_DEV(&model, /*y*/ 68, /*x*/ 13, logic_dev_idx); logic_dev->instantiated = 1; logic_dev->logic.D_used = 1; rc = fpga_set_lut(&model, logic_dev, D6_LUT, "A3", ZTERM); @@ -178,6 +178,9 @@ int main(int argc, char** argv) rc = fpga_net_add_port(&model, P46_net, P46_y, P46_x, P46_dev_idx, IOB_OUT_I); if (rc) FAIL(rc); + rc = fpga_net_add_port(&model, P46_net, /*y*/ 68, /*x*/ 13, + logic_dev_idx, LOGIC_IN_D3); + if (rc) FAIL(rc); printf("P46 I pinw %s\n", strarray_lookup(&model.str, P46_dev->pinw[IOB_OUT_I])); diff --git a/control.c b/control.c index 92e0fb1..4f73023 100644 --- a/control.c +++ b/control.c @@ -418,6 +418,24 @@ str16_t fpga_switch_str_i(struct fpga_model* model, int y, int x, return tile->conn_point_names[connpt_o*2+1]; } +const char* fpga_switch_print(struct fpga_model* model, int y, int x, + swidx_t swidx) +{ + enum { NUM_BUFS = 16, BUF_SIZE = 128 }; + static char buf[NUM_BUFS][BUF_SIZE]; + static int last_buf = 0; + uint32_t sw; + + sw = YX_TILE(model, y, x)->switches[swidx]; + last_buf = (last_buf+1)%NUM_BUFS; + + snprintf(buf[last_buf], sizeof(*buf), "%s %s %s", + connpt_str(model, y, x, SW_FROM_I(sw)), + sw & SWITCH_BIDIRECTIONAL ? "<->" : "->", + connpt_str(model, y, x, SW_TO_I(sw))); + return buf[last_buf]; +} + int fpga_switch_is_bidir(struct fpga_model* model, int y, int x, swidx_t swidx) { @@ -454,7 +472,8 @@ void fpga_switch_disable(struct fpga_model* model, int y, int x, #define SW_BUF_SIZE 256 #define NUM_SW_BUFS 64 -const char* fmt_sw(struct fpga_model* model, int y, int x, swidx_t sw, int from_to) +static const char* fmt_swset_el(struct fpga_model* model, int y, int x, + swidx_t sw, int from_to) { static char sw_buf[NUM_SW_BUFS][SW_BUF_SIZE]; static int last_buf = 0; @@ -472,7 +491,7 @@ const char* fmt_sw(struct fpga_model* model, int y, int x, swidx_t sw, int from_ // to the left side to match the physical direction. strcat(midstr, (from_to == SW_TO) ? "<-" : "->"); } - // fmt_sw() prints only the destination side of the switch (!from_to), + // fmt_swset_el() prints only the destination side of the switch (!from_to), // because it is the significant one in a chain of switches, and if the // caller wants the source side they can add it outside. snprintf(sw_buf[last_buf], sizeof(sw_buf[0]), "%s%s%s", @@ -501,13 +520,15 @@ const char* fmt_swset(struct fpga_model* model, int y, int x, o += strlen(&buf[last_buf][o]); for (i = 0; i < set->len; i++) { buf[last_buf][o++] = ' '; - strcpy(&buf[last_buf][o], fmt_sw(model, y, x, set->sw[i], SW_FROM)); + strcpy(&buf[last_buf][o], + fmt_swset_el(model, y, x, set->sw[i], SW_FROM)); o += strlen(&buf[last_buf][o]); } } else { // SW_TO for (i = set->len-1; i >= 0; i--) { if (i < set->len-1) buf[last_buf][o++] = ' '; - strcpy(&buf[last_buf][o], fmt_sw(model, y, x, set->sw[i], SW_TO)); + strcpy(&buf[last_buf][o], + fmt_swset_el(model, y, x, set->sw[i], SW_TO)); o += strlen(&buf[last_buf][o]); } buf[last_buf][o++] = ' '; @@ -794,7 +815,8 @@ struct fpga_net* fpga_net_get(struct fpga_model* model, net_idx_t net_i) { if (net_i <= NO_NET || net_i > model->num_nets) { - HERE(); + fprintf(stderr, "%s:%i net_i %i num_nets %i\n", __FILE__, + __LINE__, net_i, model->num_nets); return 0; } return &model->nets[net_i-1]; diff --git a/control.h b/control.h index 9e8fdf8..1d163ed 100644 --- a/control.h +++ b/control.h @@ -68,6 +68,8 @@ const char* fpga_switch_str(struct fpga_model* model, int y, int x, swidx_t swidx, int from_to); str16_t fpga_switch_str_i(struct fpga_model* model, int y, int x, swidx_t swidx, int from_to); +const char* fpga_switch_print(struct fpga_model* model, int y, int x, + swidx_t swidx); int fpga_switch_is_bidir(struct fpga_model* model, int y, int x, swidx_t swidx); int fpga_switch_is_used(struct fpga_model* model, int y, int x, @@ -79,8 +81,6 @@ 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); -const char* fmt_sw(struct fpga_model* model, int y, int x, - swidx_t sw, int from_to); const char* fmt_swset(struct fpga_model* model, int y, int x, struct sw_set* set, int from_to); diff --git a/floorplan.c b/floorplan.c index b8df162..2bcb5e9 100644 --- a/floorplan.c +++ b/floorplan.c @@ -61,32 +61,12 @@ int printf_tiles(FILE* f, struct fpga_model* model) return 0; } -static void printf_wrap(FILE* f, char* line, int prefix_len, - const char* fmt, ...) -{ - va_list list; - int i; - - va_start(list, fmt); - i = strlen(line); - if (i >= 80) { - line[i] = '\n'; - line[i+1] = 0; - fprintf(f, line); - line[prefix_len] = 0; - i = prefix_len; - } - line[i] = ' '; - vsnprintf(&line[i+1], 256, fmt, list); - va_end(list); -} - static int printf_IOB(FILE* f, struct fpga_model* model, int y, int x, int config_only) { struct fpga_tile* tile; - char line[1024]; - int type_count, plen, i; + char pref[256]; + int type_count, i; tile = YX_TILE(model, y, x); type_count = 0; @@ -97,111 +77,109 @@ static int printf_IOB(FILE* f, struct fpga_model* model, type_count++; continue; } - snprintf(line, sizeof(line), "dev y%02i x%02i IOB %i", + snprintf(pref, sizeof(pref), "dev y%02i x%02i IOB %i", y, x, type_count); type_count++; - plen = strlen(line); - printf_wrap(f, line, plen, "type %s", - tile->devs[i].iob.subtype == IOBM - ? "M" : "S"); + if (!config_only) { + fprintf(f, "%s type %s\n", pref, + tile->devs[i].iob.subtype == IOBM ? "M" : "S"); + } if (tile->devs[i].iob.istandard[0]) - printf_wrap(f, line, plen, "istd %s", + fprintf(f, "%s istd %s\n", pref, tile->devs[i].iob.istandard); if (tile->devs[i].iob.ostandard[0]) - printf_wrap(f, line, plen, "ostd %s", + fprintf(f, "%s ostd %s\n", pref, tile->devs[i].iob.ostandard); switch (tile->devs[i].iob.bypass_mux) { case BYPASS_MUX_I: - printf_wrap(f, line, plen, "bypass_mux I"); + fprintf(f, "%s bypass_mux I\n", pref); break; case BYPASS_MUX_O: - printf_wrap(f, line, plen, "bypass_mux O"); + fprintf(f, "%s bypass_mux O\n", pref); break; case BYPASS_MUX_T: - printf_wrap(f, line, plen, "bypass_mux T"); + fprintf(f, "%s bypass_mux T\n", pref); break; case 0: break; default: EXIT(1); } switch (tile->devs[i].iob.I_mux) { case IMUX_I_B: - printf_wrap(f, line, plen, "imux I_B"); + fprintf(f, "%s imux I_B\n", pref); break; case IMUX_I: - printf_wrap(f, line, plen, "imux I"); + fprintf(f, "%s imux I\n", pref); break; case 0: break; default: EXIT(1); } if (tile->devs[i].iob.drive_strength) - printf_wrap(f, line, plen, "strength %i", + fprintf(f, "%s strength %i\n", pref, tile->devs[i].iob.drive_strength); switch (tile->devs[i].iob.slew) { case SLEW_SLOW: - printf_wrap(f, line, plen, "slew SLOW"); + fprintf(f, "%s slew SLOW\n", pref); break; case SLEW_FAST: - printf_wrap(f, line, plen, "slew FAST"); + fprintf(f, "%s slew FAST\n", pref); break; case SLEW_QUIETIO: - printf_wrap(f, line, plen, "slew QUIETIO"); + fprintf(f, "%s slew QUIETIO\n", pref); break; case 0: break; default: EXIT(1); } if (tile->devs[i].iob.O_used) - printf_wrap(f, line, plen, "O_used"); + fprintf(f, "%s O_used\n", pref); switch (tile->devs[i].iob.suspend) { case SUSP_LAST_VAL: - printf_wrap(f, line, plen, "suspend DRIVE_LAST_VALUE"); + fprintf(f, "%s suspend DRIVE_LAST_VALUE\n", pref); break; case SUSP_3STATE: - printf_wrap(f, line, plen, "suspend 3STATE"); + fprintf(f, "%s suspend 3STATE\n", pref); break; case SUSP_3STATE_PULLUP: - printf_wrap(f, line, plen, "suspend 3STATE_PULLUP"); + fprintf(f, "%s suspend 3STATE_PULLUP\n", pref); break; case SUSP_3STATE_PULLDOWN: - printf_wrap(f, line, plen, "suspend 3STATE_PULLDOWN"); + fprintf(f, "%s suspend 3STATE_PULLDOWN\n", pref); break; case SUSP_3STATE_KEEPER: - printf_wrap(f, line, plen, "suspend 3STATE_KEEPER"); + fprintf(f, "%s suspend 3STATE_KEEPER\n", pref); break; case SUSP_3STATE_OCT_ON: - printf_wrap(f, line, plen, "suspend 3STATE_OCT_ON"); + fprintf(f, "%s suspend 3STATE_OCT_ON\n", pref); break; case 0: break; default: EXIT(1); } switch (tile->devs[i].iob.in_term) { case ITERM_NONE: - printf_wrap(f, line, plen, "in_term NONE"); + fprintf(f, "%s in_term NONE\n", pref); break; case ITERM_UNTUNED_25: - printf_wrap(f, line, plen, "in_term UNTUNED_SPLIT_25"); + fprintf(f, "%s in_term UNTUNED_SPLIT_25\n", pref); break; case ITERM_UNTUNED_50: - printf_wrap(f, line, plen, "in_term UNTUNED_SPLIT_50"); + fprintf(f, "%s in_term UNTUNED_SPLIT_50\n", pref); break; case ITERM_UNTUNED_75: - printf_wrap(f, line, plen, "in_term UNTUNED_SPLIT_75"); + fprintf(f, "%s in_term UNTUNED_SPLIT_75\n", pref); break; case 0: break; default: EXIT(1); } switch (tile->devs[i].iob.out_term) { case OTERM_NONE: - printf_wrap(f, line, plen, "out_term NONE"); + fprintf(f, "%s out_term NONE\n", pref); break; case OTERM_UNTUNED_25: - printf_wrap(f, line, plen, "out_term UNTUNED_25"); + fprintf(f, "%s out_term UNTUNED_25\n", pref); break; case OTERM_UNTUNED_50: - printf_wrap(f, line, plen, "out_term UNTUNED_50"); + fprintf(f, "%s out_term UNTUNED_50\n", pref); break; case OTERM_UNTUNED_75: - printf_wrap(f, line, plen, "out_term UNTUNED_75"); + fprintf(f, "%s out_term UNTUNED_75\n", pref); break; case 0: break; default: EXIT(1); } - strcat(line, "\n"); - fprintf(f, line); } return 0; } @@ -313,8 +291,8 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model, int y, int x, int config_only) { struct fpga_tile* tile; - char line[1024]; - int type_count, plen, i; + char pref[256]; + int type_count, i; tile = YX_TILE(model, y, x); type_count = 0; @@ -325,45 +303,44 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model, type_count++; continue; } - snprintf(line, sizeof(line), "dev y%02i x%02i LOGIC %i", + snprintf(pref, sizeof(pref), "dev y%02i x%02i LOGIC %i", y, x, type_count); type_count++; - plen = strlen(line); - switch (tile->devs[i].logic.subtype) { - case LOGIC_X: - printf_wrap(f, line, plen, "type X"); - break; - case LOGIC_L: - printf_wrap(f, line, plen, "type L"); - break; - case LOGIC_M: - printf_wrap(f, line, plen, "type M"); - break; - default: EXIT(1); + if (!config_only) { + switch (tile->devs[i].logic.subtype) { + case LOGIC_X: + fprintf(f, "%s type X\n", pref); + break; + case LOGIC_L: + fprintf(f, "%s type L\n", pref); + break; + case LOGIC_M: + fprintf(f, "%s type M\n", pref); + break; + default: EXIT(1); + } } if (tile->devs[i].logic.A_used) - printf_wrap(f, line, plen, "A_used"); + fprintf(f, "%s A_used\n", pref); if (tile->devs[i].logic.B_used) - printf_wrap(f, line, plen, "B_used"); + fprintf(f, "%s B_used\n", pref); if (tile->devs[i].logic.C_used) - printf_wrap(f, line, plen, "C_used"); + fprintf(f, "%s C_used\n", pref); if (tile->devs[i].logic.D_used) - printf_wrap(f, line, plen, "D_used"); + fprintf(f, "%s D_used\n", pref); if (tile->devs[i].logic.A6_lut && tile->devs[i].logic.A6_lut[0]) - printf_wrap(f, line, plen, "A6_lut %s", + fprintf(f, "%s A6_lut %s\n", pref, tile->devs[i].logic.A6_lut); if (tile->devs[i].logic.B6_lut && tile->devs[i].logic.B6_lut[0]) - printf_wrap(f, line, plen, "B6_lut %s", + fprintf(f, "%s B6_lut %s\n", pref, tile->devs[i].logic.B6_lut); if (tile->devs[i].logic.C6_lut && tile->devs[i].logic.C6_lut[0]) - printf_wrap(f, line, plen, "C6_lut %s", + fprintf(f, "%s C6_lut %s\n", pref, tile->devs[i].logic.C6_lut); if (tile->devs[i].logic.D6_lut && tile->devs[i].logic.D6_lut[0]) - printf_wrap(f, line, plen, "D6_lut %s", + fprintf(f, "%s D6_lut %s\n", pref, tile->devs[i].logic.D6_lut); - strcat(line, "\n"); - fprintf(f, line); } return 0; } @@ -438,82 +415,11 @@ int printf_devices(FILE* f, struct fpga_model* model, int config_only) for (i = 0; i < tile->num_devs; i++) { if (config_only && !(tile->devs[i].instantiated)) continue; - switch (tile->devs[i].type) { - case DEV_MACC: - fprintf(f, "dev y%02i x%02i DSP48A1\n", y, x); - break; - case DEV_TIEOFF: - fprintf(f, "dev y%02i x%02i TIEOFF\n", y, x); - break; - case DEV_ILOGIC: - fprintf(f, "dev y%02i x%02i ILOGIC\n", y, x); - break; - case DEV_OLOGIC: - fprintf(f, "dev y%02i x%02i OLOGIC\n", y, x); - break; - case DEV_IODELAY: - fprintf(f, "dev y%02i x%02i IODELAY\n", y, x); - break; - case DEV_BRAM16: - fprintf(f, "dev y%02i x%02i RAMB16\n", y, x); - break; - case DEV_BRAM8: - fprintf(f, "dev y%02i x%02i RAMB8\n", y, x); - break; - case DEV_BUFH: - fprintf(f, "dev y%02i x%02i BUFH\n", y, x); - break; - case DEV_BUFIO: - fprintf(f, "dev y%02i x%02i BUFIO2\n", y, x); - break; - case DEV_BUFIO_FB: - fprintf(f, "dev y%02i x%02i BUFIO2FB\n", y, x); - break; - case DEV_BUFPLL: - fprintf(f, "dev y%02i x%02i BUFPLL\n", y, x); - break; - case DEV_BUFPLL_MCB: - fprintf(f, "dev y%02i x%02i BUFPLL_MCB\n", y, x); - break; - case DEV_BUFGMUX: - fprintf(f, "dev y%02i x%02i BUFGMUX\n", y, x); - break; - case DEV_BSCAN: - fprintf(f, "dev y%02i x%02i BSCAN\n", y, x); - break; - case DEV_DCM: - fprintf(f, "dev y%02i x%02i DCM\n", y, x); - break; - case DEV_PLL: - fprintf(f, "dev y%02i x%02i PLL\n", y, x); - break; - case DEV_ICAP: - fprintf(f, "dev y%02i x%02i ICAP\n", y, x); - break; - case DEV_POST_CRC_INTERNAL: - fprintf(f, "dev y%02i x%02i POST_CRC_INTERNAL\n", y, x); - break; - case DEV_STARTUP: - fprintf(f, "dev y%02i x%02i STARTUP\n", y, x); - break; - case DEV_SLAVE_SPI: - fprintf(f, "dev y%02i x%02i SLAVE_SPI\n", y, x); - break; - case DEV_SUSPEND_SYNC: - fprintf(f, "dev y%02i x%02i SUSPEND_SYNC\n", y, x); - break; - case DEV_OCT_CALIBRATE: - fprintf(f, "dev y%02i x%02i OCT_CALIBRATE\n", y, x); - break; - case DEV_SPI_ACCESS: - fprintf(f, "dev y%02i x%02i SPI_ACCESS\n", y, x); - break; - case DEV_IOB: - case DEV_LOGIC: - case DEV_NONE: - // to suppress compiler warning - break; - } + if (tile->devs[i].type == DEV_LOGIC + || tile->devs[i].type == DEV_IOB) + continue; // handled above + fprintf(f, "dev y%02i x%02i %s\n", y, x, + fpgadev_str(tile->devs[i].type)); } } } @@ -620,52 +526,89 @@ int printf_conns(FILE* f, struct fpga_model* model) return 0; } -int printf_switches(FILE* f, struct fpga_model* model, int enabled_only) +int printf_switches(FILE* f, struct fpga_model* model) { struct fpga_tile* tile; - int x, y, i, from_connpt_o, to_connpt_o, from_str_i, to_str_i; - int first_switch_printed, is_bidirectional, is_on; - const char* from_str, *to_str; + int x, y, i, first_switch_printed; for (x = 0; x < model->x_width; x++) { for (y = 0; y < model->y_height; y++) { tile = YX_TILE(model, y, x); - - // no newlines between tiles in enabled_only mode - first_switch_printed = enabled_only; - + first_switch_printed = 0; for (i = 0; i < tile->num_switches; i++) { - 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_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]; - - from_str = strarray_lookup(&model->str, from_str_i); - to_str = strarray_lookup(&model->str, to_str_i); - if (!from_str || !to_str) { - fprintf(stderr, "Internal error in %s:%i, cannot lookup from_i %i or to_i %i\n", - __FILE__, __LINE__, from_str_i, to_str_i); - continue; - } - if (enabled_only && !is_on) - continue; if (!first_switch_printed) { first_switch_printed = 1; fprintf(f, "\n"); } - fprintf(f, "sw y%02i x%02i %s %s %s%s\n", - y, x, from_str, is_bidirectional - ? "<->" : "->", to_str, - is_on ? " on" : ""); + fprintf(f, "sw y%02i x%02i %s\n", + y, x, fpga_switch_print(model, y, x, i)); } } } return 0; } +static void printf_inout_pin(FILE* f, struct fpga_model* model, + net_idx_t net_i, struct net_el* el) +{ + struct fpga_tile* tile; + pinw_idx_t pinw_i; + dev_idx_t dev_idx; + int in_pin; + const char* pin_str; + char buf[1024]; + + if (!(el->idx & NET_IDX_IS_PINW)) + { HERE(); return; } + + tile = YX_TILE(model, el->y, el->x); + dev_idx = el->dev_idx; + if (dev_idx < 0 || dev_idx >= tile->num_devs) + { HERE(); return; } + pinw_i = el->idx & NET_IDX_MASK; + if (pinw_i < 0 || pinw_i >= tile->devs[dev_idx].num_pinw_total) + { HERE(); return; } + in_pin = pinw_i < tile->devs[dev_idx].num_pinw_in; + + pin_str = fpgadev_pinw_idx2str(tile->devs[dev_idx].type, pinw_i); + if (!pin_str) { HERE(); return; } + + snprintf(buf, sizeof(buf), "net %i %s y%02i x%02i %s %i pin %s\n", + net_i, in_pin ? "in" : "out", el->y, el->x, + fpgadev_str(tile->devs[dev_idx].type), + fpga_dev_typeidx(model, el->y, el->x, dev_idx), + pin_str); + fprintf(f, buf); +} + +int printf_nets(FILE* f, struct fpga_model* model) +{ + net_idx_t net_i; + struct fpga_net* net; + int i, rc; + + net_i = NO_NET; + while (!(rc = fpga_net_enum(model, net_i, &net_i)) && net_i != NO_NET) { + net = fpga_net_get(model, net_i); + if (!net) FAIL(rc); + for (i = 0; i < net->len; i++) { + if (net->el[i].idx & NET_IDX_IS_PINW) { + printf_inout_pin(f, model, net_i, &net->el[i]); + continue; + } + // switch + fprintf(f, "net %i sw y%02i x%02i %s\n", + net_i, net->el[i].y, net->el[i].x, + fpga_switch_print(model, net->el[i].y, + net->el[i].x, net->el[i].idx)); + } + } + if (rc) FAIL(rc); + return 0; +fail: + return rc; +} + static enum fpgadev_type to_type(const char* s, int len) { if (!str_cmp(s, len, "IOB", 3)) return DEV_IOB; @@ -857,11 +800,9 @@ int write_floorplan(FILE* f, struct fpga_model* model, int flags) rc = printf_devices(f, model, /*config_only*/ 1); if (rc) FAIL(rc); - rc = printf_switches(f, model, /*enabled_only*/ 1); + rc = printf_nets(f, model); 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/floorplan.h b/floorplan.h index 581f63a..d252d65 100644 --- a/floorplan.h +++ b/floorplan.h @@ -34,4 +34,5 @@ int printf_tiles(FILE* f, struct fpga_model* model); int printf_devices(FILE* f, struct fpga_model* model, int config_only); int printf_ports(FILE* f, struct fpga_model* model); int printf_conns(FILE* f, struct fpga_model* model); -int printf_switches(FILE* f, struct fpga_model* model, int enabled_only); +int printf_switches(FILE* f, struct fpga_model* model); +int printf_nets(FILE* f, struct fpga_model* model); diff --git a/helper.c b/helper.c index d11304c..d2c5b3a 100644 --- a/helper.c +++ b/helper.c @@ -5,6 +5,7 @@ // For details see the UNLICENSE file at the root of the source tree. // +#include #include "helper.h" #include "parts.h" @@ -748,6 +749,26 @@ int to_i(const char* s, int len) return num; } +void printf_wrap(FILE* f, char* line, int prefix_len, + const char* fmt, ...) +{ + va_list list; + int i; + + va_start(list, fmt); + i = strlen(line); + if (i >= 80) { + line[i] = '\n'; + line[i+1] = 0; + fprintf(f, line); + line[prefix_len] = 0; + i = prefix_len; + } + line[i] = ' '; + vsnprintf(&line[i+1], 256, fmt, list); + va_end(list); +} + // Dan Bernstein's hash function uint32_t hash_djb2(const unsigned char* str) { diff --git a/helper.h b/helper.h index 6b2e692..37a6f03 100644 --- a/helper.h +++ b/helper.h @@ -99,6 +99,9 @@ int str_cmp(const char* a, int a_len, const char* b, int b_len); int all_digits(const char* a, int len); int to_i(const char* s, int len); +void printf_wrap(FILE* f, char* line, int prefix_len, + const char* fmt, ...); + uint32_t hash_djb2(const unsigned char* str); // Strings are distributed among bins. Each bin is diff --git a/model.h b/model.h index f8784ba..03192ae 100644 --- a/model.h +++ b/model.h @@ -304,35 +304,21 @@ int pos_in_row(int y, struct fpga_model* model); const char* logicin_s(int wire, int routing_io); enum fpgadev_type -{ - DEV_NONE = 0, - - DEV_LOGIC, - DEV_TIEOFF, - DEV_MACC, - DEV_IOB, - DEV_ILOGIC, - DEV_OLOGIC, - DEV_IODELAY, - DEV_BRAM16, - DEV_BRAM8, - DEV_BUFH, - DEV_BUFIO, - DEV_BUFIO_FB, - DEV_BUFPLL, - DEV_BUFPLL_MCB, - DEV_BUFGMUX, - DEV_BSCAN, - DEV_DCM, - DEV_PLL, - DEV_ICAP, - DEV_POST_CRC_INTERNAL, - DEV_STARTUP, - DEV_SLAVE_SPI, - DEV_SUSPEND_SYNC, - DEV_OCT_CALIBRATE, - DEV_SPI_ACCESS -}; + { DEV_NONE = 0, + DEV_LOGIC, DEV_TIEOFF, DEV_MACC, DEV_IOB, + DEV_ILOGIC, DEV_OLOGIC, DEV_IODELAY, DEV_BRAM16, DEV_BRAM8, + DEV_BUFH, DEV_BUFIO, DEV_BUFIO_FB, DEV_BUFPLL, DEV_BUFPLL_MCB, + DEV_BUFGMUX, DEV_BSCAN, DEV_DCM, DEV_PLL, DEV_ICAP, + DEV_POST_CRC_INTERNAL, DEV_STARTUP, DEV_SLAVE_SPI, + DEV_SUSPEND_SYNC, DEV_OCT_CALIBRATE, DEV_SPI_ACCESS }; +#define FPGA_DEV_STR \ + { 0, \ + "LOGIC", "TIEOFF", "MACC", "IOB", \ + "ILOGIC", "OLOGIC", "IODELAY", "BRAM16", "BRAM8", \ + "BUFH", "BUFIO", "BUFIO_FB", "BUFPLL", "BUFPLL_MCB", \ + "BUFGMUX", "BSCAN", "DCM", "PLL", "ICAP", \ + "POST_CRC_INTERNAL", "STARTUP", "SLAVE_SPI", \ + "SUSPEND_SYNC", "OCT_CALIBRATE", "SPI_ACCESS" } // We use two types of device indices, one is a flat index // into the tile->devs array (dev_idx_t), the other @@ -523,6 +509,7 @@ int init_tiles(struct fpga_model* model); int init_devices(struct fpga_model* model); void free_devices(struct fpga_model* model); +const char* fpgadev_str(enum fpgadev_type type); #define PINW_NO_IDX -1 pinw_idx_t fpgadev_pinw_str2idx(int devtype, const char* str); // returns 0 when idx not found for the given devtype diff --git a/model_devices.c b/model_devices.c index a202fe1..fedd89d 100644 --- a/model_devices.c +++ b/model_devices.c @@ -332,13 +332,23 @@ void free_devices(struct fpga_model* model) model->tiles[i].num_devs = 0; } } - + +const char* fpgadev_str(enum fpgadev_type type) +{ + static const char* dev_str[] = FPGA_DEV_STR; + + if (type < 0 || type >= sizeof(dev_str)/sizeof(*dev_str)) + { HERE(); return 0; } + return dev_str[type]; +} + static const char* iob_pinw_str[] = IOB_PINW_STR; static const char* logic_pinw_str[] = LOGIC_PINW_STR; pinw_idx_t fpgadev_pinw_str2idx(int devtype, const char* str) { int i; + if (devtype == DEV_IOB) { for (i = 0; i < sizeof(iob_pinw_str)/sizeof(*iob_pinw_str); i++) { if (!strcmp(iob_pinw_str[i], str)) diff --git a/new_fp.c b/new_fp.c index 2d29899..a7e2343 100644 --- a/new_fp.c +++ b/new_fp.c @@ -37,7 +37,7 @@ int main(int argc, char** argv) if (rc) goto fail; } - rc = printf_switches(stdout, &model, /*enabled_only*/ 0); + rc = printf_switches(stdout, &model); if (rc) goto fail; return EXIT_SUCCESS;