diff --git a/autotest.c b/autotest.c index 79025b9..34c5fa0 100644 --- a/autotest.c +++ b/autotest.c @@ -136,7 +136,7 @@ static int test_net(struct test_state* tstate, net_idx_t net_i) net->el[2].y, net->el[2].x, fpga_switch_str_i(tstate->model, net->el[2].y, net->el[2].x, - net->el[2].idx, SW_TO), 1, SW_TO); + net->el[2].idx, SW_TO), SW_TO, 1); same_len = sizeof(same_sw)/sizeof(*same_sw); rc = fpga_switch_same_fromto(tstate->model, net->el[2].y, net->el[2].x, @@ -174,7 +174,7 @@ static int test_net2(struct test_state* tstate, net_idx_t net_i) net->el[i-1].y, net->el[i-1].x, fpga_switch_str_i(tstate->model, net->el[i-1].y, net->el[i-1].x, - net->el[i-1].idx, SW_FROM), 1, SW_FROM); + net->el[i-1].idx, SW_FROM), SW_FROM, 1); same_len = sizeof(same_sw)/sizeof(*same_sw); rc = fpga_switch_same_fromto(tstate->model, net->el[i-1].y, net->el[i-1].x, @@ -195,37 +195,13 @@ fail: return rc; } -static void fdev_print_required_pins(struct fpga_model* model, int y, int x, - int type, int type_idx) -{ - struct fpga_device* dev; - int i; - - dev = fdev_p(model, y, x, type, type_idx); - if (!dev) { HERE(); return; } - - printf("y%02i x%02i %s %i inpin", y, x, fdev_type2str(type), type_idx); - if (!dev->pinw_req_in) - printf(" -\n"); - else { - for (i = 0; i < dev->pinw_req_in; i++) - printf(" %s", fdev_pinw_idx2str(type, dev->pinw_req_for_cfg[i])); - printf("\n"); - } - - printf("y%02i x%02i %s %i outpin", y, x, fdev_type2str(type), type_idx); - if (dev->pinw_req_total <= dev->pinw_req_in) - printf(" -\n"); - else { - for (i = dev->pinw_req_in; i < dev->pinw_req_total; i++) - printf(" %s", fdev_pinw_idx2str(type, dev->pinw_req_for_cfg[i])); - printf("\n"); - } -} - static int test_all_logic_configs(struct test_state* tstate) { - int y, x, rc; + struct fpga_device* dev; + struct switch_to_yx switch_to; + struct sw_chain chain; + net_idx_t net_idx; + int y, x, i, from_to, rc; // todo: goal: configure valid logic with as many possible in and out // pins, for M and X device @@ -238,10 +214,54 @@ static int test_all_logic_configs(struct test_state* tstate) rc = fdev_set_required_pins(tstate->model, y, x, DEV_LOGIC, DEV_LOGX); if (rc) FAIL(rc); +// fdev_print_required_pins(tstate->model, y, x, DEV_LOGIC, DEV_LOGX); - fdev_print_required_pins(tstate->model, y, x, DEV_LOGIC, DEV_LOGX); - rc = diff_printf(tstate); - if (rc) FAIL(rc); + dev = fdev_p(tstate->model, y, x, DEV_LOGIC, DEV_LOGX); + if (!dev) FAIL(EINVAL); + for (i = 0; i < dev->pinw_req_total; i++) { + from_to = (i < dev->pinw_req_in) ? SW_TO : SW_FROM; + switch_to.yx_req = YX_ROUTING_TILE; + switch_to.flags = SWTO_YX_DEF; + switch_to.model = tstate->model; + switch_to.y = y; + switch_to.x = x; + switch_to.start_switch = dev->pinw[dev->pinw_req_for_cfg[i]]; + switch_to.from_to = from_to; + rc = fpga_switch_to_yx(&switch_to); + if (rc) FAIL(rc); +// printf_switch_to_result(&switch_to); + + chain.model = tstate->model; + chain.y = switch_to.dest_y; + chain.x = switch_to.dest_x; + chain.start_switch = switch_to.dest_connpt; + chain.from_to = from_to; + chain.max_chain_size = 1; + while (fpga_switch_chain(&chain) != NO_SWITCH) { + rc = fpga_net_new(tstate->model, &net_idx); + if (rc) FAIL(rc); + + // add port + rc = fpga_net_add_port(tstate->model, net_idx, + y, x, fpga_dev_idx(tstate->model, y, x, + DEV_LOGIC, DEV_LOGX), dev->pinw_req_for_cfg[i]); + if (rc) FAIL(rc); + // add (one) switch in logic tile + rc = fpga_net_add_switches(tstate->model, net_idx, + y, x, &switch_to.set); + if (rc) FAIL(rc); + // add switches in routing tile + rc = fpga_net_add_switches(tstate->model, net_idx, + switch_to.dest_y, switch_to.dest_x, &chain.set); + if (rc) FAIL(rc); + +// fprintf_net(stdout, tstate->model, net_idx); + + rc = diff_printf(tstate); + if (rc) FAIL(rc); + fpga_net_delete(tstate->model, net_idx); + } + } return 0; fail: return rc; @@ -349,6 +369,7 @@ int main(int argc, char** argv) switch_to.y = P46_y; switch_to.x = P46_x; switch_to.start_switch = P46_dev->pinw[IOB_OUT_I]; + switch_to.from_to = SW_FROM; rc = fpga_switch_to_yx(&switch_to); if (rc) FAIL(rc); rc = fpga_net_add_switches(&model, P46_net, switch_to.y, @@ -357,9 +378,11 @@ int main(int argc, char** argv) switch_to.yx_req = YX_ROUTING_TILE; switch_to.flags = SWTO_YX_DEF; + switch_to.model = &model; switch_to.y = switch_to.dest_y; switch_to.x = switch_to.dest_x; switch_to.start_switch = switch_to.dest_connpt; + switch_to.from_to = SW_FROM; rc = fpga_switch_to_yx(&switch_to); if (rc) FAIL(rc); rc = fpga_net_add_switches(&model, P46_net, switch_to.y, @@ -368,9 +391,11 @@ int main(int argc, char** argv) switch_to.yx_req = YX_ROUTING_TO_FABLOGIC; switch_to.flags = SWTO_YX_CLOSEST; + switch_to.model = &model; switch_to.y = switch_to.dest_y; switch_to.x = switch_to.dest_x; switch_to.start_switch = switch_to.dest_connpt; + switch_to.from_to = SW_FROM; rc = fpga_switch_to_yx(&switch_to); if (rc) FAIL(rc); rc = fpga_net_add_switches(&model, P46_net, switch_to.y, @@ -379,9 +404,11 @@ int main(int argc, char** argv) switch_to.yx_req = YX_DEV_LOGIC; switch_to.flags = SWTO_YX_TARGET_CONNPT|SWTO_YX_MAX_SWITCH_DEPTH; + switch_to.model = &model; switch_to.y = switch_to.dest_y; switch_to.x = switch_to.dest_x; switch_to.start_switch = switch_to.dest_connpt; + switch_to.from_to = SW_FROM; switch_to.max_switch_depth = 1; { struct sw_chain c = { diff --git a/bit_frames.c b/bit_frames.c index 347c15d..ee519df 100644 --- a/bit_frames.c +++ b/bit_frames.c @@ -165,15 +165,6 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits) continue; } - // any logic block will enable r0ma17mi22b980 - if (!get_bit(bits, /*row*/ 0, /*major*/ 17, - /*minor*/ 22, /*bit_i*/ 980)) { - HERE(); - continue; - } - clear_bit(bits, /*row*/ 0, /*major*/ 17, - /*minor*/ 22, /*bit_i*/ 980); - dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOGX); if (dev_idx == NO_DEV) FAIL(EINVAL); dev = FPGA_DEV(model, y, x, dev_idx); @@ -216,6 +207,36 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits) *(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off) = 0; *(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off) = 0; } +#if 0 + // M-LUTs + lut64 = read_lut64(&maj_bits[24*130], frame_off+32); + { int logic_base[6] = {0,1,0,0,1,0}; + lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); } + if (*lut_str) + printf("r%i ma%i clb i%i s0_A6LUT \"%s\"\n", + row, major, i-start, lut_str); + + lut64 = read_lut64(&maj_bits[21*130], frame_off+32); + { int logic_base[6] = {1,1,0,1,0,1}; + lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); } + if (*lut_str) + printf("r%i ma%i clb i%i s0_B6LUT \"%s\"\n", + row, major, i-start, lut_str); + + lut64 = read_lut64(&maj_bits[24*130], frame_off); + { int logic_base[6] = {0,1,0,0,1,0}; + lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); } + if (*lut_str) + printf("r%i ma%i clb i%i s0_C6LUT \"%s\"\n", + row, major, i-start, lut_str); + + lut64 = read_lut64(&maj_bits[21*130], frame_off); + { int logic_base[6] = {1,1,0,1,0,1}; + lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); } + if (*lut_str) + printf("r%i ma%i clb i%i s0_D6LUT \"%s\"\n", + row, major, i-start, lut_str); +#endif } } } diff --git a/bit_regs.c b/bit_regs.c index a519125..e058d79 100644 --- a/bit_regs.c +++ b/bit_regs.c @@ -713,103 +713,28 @@ static void print_ramb16_cfg(ramb16_cfg_t* cfg) printf("}\n"); } -static void printf_clb(uint8_t* maj_bits, int row, int major) +static void printf_routing_2minors(uint8_t* bits, int row, int major, + int even_minor) { - int i, j, start, max_idx, frame_off; - const char* lut_str; - uint64_t lut64; + int y, i, hclk; + uint64_t u64_0, u64_1; + char bit_str[128]; - // the first two slots on top and bottom row are not used for clb - if (!row) { - start = 0; - max_idx = 14; - } else if (row == 3) { - start = 2; - max_idx = 16; - } else { - start = 0; - max_idx = 16; - } - - for (i = start; i < max_idx; i++) { - if (clb_empty(maj_bits, i)) - continue; - frame_off = i*64; - if (i >= 8) - frame_off += 16; // skip clock bits for idx >= 8 - - // LUTs - lut64 = read_lut64(&maj_bits[24*130], frame_off+32); - { int logic_base[6] = {0,1,0,0,1,0}; - lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); } - if (*lut_str) - printf("r%i ma%i clb i%i s0_A6LUT \"%s\"\n", - row, major, i-start, lut_str); - - lut64 = read_lut64(&maj_bits[21*130], frame_off+32); - { int logic_base[6] = {1,1,0,1,0,1}; - lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); } - if (*lut_str) - printf("r%i ma%i clb i%i s0_B6LUT \"%s\"\n", - row, major, i-start, lut_str); - - lut64 = read_lut64(&maj_bits[24*130], frame_off); - { int logic_base[6] = {0,1,0,0,1,0}; - lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); } - if (*lut_str) - printf("r%i ma%i clb i%i s0_C6LUT \"%s\"\n", - row, major, i-start, lut_str); - - lut64 = read_lut64(&maj_bits[21*130], frame_off); - { int logic_base[6] = {1,1,0,1,0,1}; - lut_str = lut2bool(lut64, 64, &logic_base, 1 /* flip_b0 */); } - if (*lut_str) - printf("r%i ma%i clb i%i s0_D6LUT \"%s\"\n", - row, major, i-start, lut_str); - - lut64 = read_lut64(&maj_bits[27*130], frame_off+32); - { int logic_base[6] = {1,1,0,1,1,0}; - lut_str = lut2bool(lut64, 64, &logic_base, 0 /* flip_b0 */); } - if (*lut_str) - printf("r%i ma%i clb i%i s1_A6LUT \"%s\"\n", - row, major, i-start, lut_str); - - lut64 = read_lut64(&maj_bits[29*130], frame_off+32); - { int logic_base[6] = {1,1,0,1,1,0}; - lut_str = lut2bool(lut64, 64, &logic_base, 0 /* flip_b0 */); } - if (*lut_str) - printf("r%i ma%i clb i%i s1_B6LUT \"%s\"\n", - row, major, i-start, lut_str); - - lut64 = read_lut64(&maj_bits[27*130], frame_off); - { int logic_base[6] = {0,1,0,0,0,1}; - lut_str = lut2bool(lut64, 64, &logic_base, 0 /* flip_b0 */); } - if (*lut_str) - printf("r%i ma%i clb i%i s1_C6LUT \"%s\"\n", - row, major, i-start, lut_str); - - lut64 = read_lut64(&maj_bits[29*130], frame_off); - { int logic_base[6] = {0,1,0,0,0,1}; - lut_str = lut2bool(lut64, 64, &logic_base, 0 /* flip_b0 */); } - if (*lut_str) - printf("r%i ma%i clb i%i s1_D6LUT \"%s\"\n", - row, major, i-start, lut_str); - - // bits - for (j = 0; j < 64; j++) { - if (frame_get_bit(&maj_bits[20*130], frame_off + j)) - printf("r%i ma%i clb i%i mi20 bit %i\n", - row, major, i-start, j); - } - for (j = 0; j < 64; j++) { - if (frame_get_bit(&maj_bits[23*130], frame_off + j)) - printf("r%i ma%i clb i%i mi23 bit %i\n", - row, major, i-start, j); - } - for (j = 0; j < 64; j++) { - if (frame_get_bit(&maj_bits[26*130], frame_off + j)) - printf("r%i ma%i clb i%i mi26 bit %i\n", - row, major, i-start, j); + for (y = 0; y < 16; y++) { + hclk = (y < 8) ? 0 : 2; + u64_0 = frame_get_u64(bits + y*8 + hclk); + u64_1 = frame_get_u64(bits + y*8 + hclk + FRAME_SIZE); + if (u64_0 || u64_1) { + for (i = 0; i < sizeof(bit_str); i++) + bit_str[i] = '0'; + for (i = 0; i < 64; i++) { + if (u64_0 & (1ULL << i)) + bit_str[i*2] = '1'; + if (u64_1 & (1ULL << i)) + bit_str[i*2+1] = '1'; + } + printf("r%i ma%i v64_%i mip%i %s\n", + row, major, y, even_minor, bit_str); } } } @@ -823,7 +748,8 @@ static int dump_bits(struct fpga_config* cfg) for (row = 0; row < 4; row++) { for (major = 0; major < 18; major++) { // todo: the macc/bram/logic special cases can be removed - if (0 && major == 7) { // MACC + if (get_major_type(cfg->reg[cfg->idcode_reg].int_v, + major) == MAJ_MACC) { int last_extra_minor; if (!row || row == 3) @@ -851,30 +777,25 @@ static int dump_bits(struct fpga_config* cfg) } } } - } else if (0 && (major == 2 || major == 5 || major == 8 || major == 10 - || major == 12 || major == 15)) { // logic_m + } else if (get_major_type(cfg->reg[cfg->idcode_reg].int_v, major) == MAJ_LOGIC_XM) { + // clock + for (minor = 0; minor < 31; minor++) + printf_clock( + &cfg->bits.d[off+minor*130], + row, major, minor); + + // bitwise minor = 0; - while (minor < 20) { + while (minor < 31) { minor += printf_frames(&cfg->bits.d[off - +minor*130], 31 - minor, row, - major, minor, /*print_empty*/ 0); + +minor*130], 31 - minor, + row, major, minor, /*print_empty*/ 0); } - // clock - for (minor = 20; minor < 31; minor++) - printf_clock(&cfg->bits.d[off+minor*130], - row, major, minor); - // extra bits at bottom of row0 and top of row3 - if (row == 3) - printf_extrabits(&cfg->bits.d[off], 20, 11, - 0, 128, row, major); - else if (!row) - printf_extrabits(&cfg->bits.d[off], 20, 11, - 14*64 + 16, 128, row, major); - - // clbs - printf_clb(&cfg->bits.d[off], row, major); - } else if (0 && (major == 4 || major == 14)) { // bram + // 0:20 routing minor pairs + for (i = 0; i < 10; i++) + printf_routing_2minors(&cfg->bits.d[off+i*2*FRAME_SIZE], row, major, i*2); + } else if (get_major_type(cfg->reg[cfg->idcode_reg].int_v, major) == MAJ_BRAM) { ramb16_cfg_t ramb16_cfg[4]; // minors 0..22 @@ -910,7 +831,7 @@ static int dump_bits(struct fpga_config* cfg) } } else { int major_minors = - get_major_minors(XC6SLX9, major); + get_major_minors(cfg->reg[cfg->idcode_reg].int_v, major); minor = 0; while (minor < major_minors) { minor += printf_frames(&cfg->bits.d[off diff --git a/control.c b/control.c index 1363882..c734ffc 100644 --- a/control.c +++ b/control.c @@ -312,12 +312,67 @@ const char* fdev_pinw_idx2str(int devtype, pinw_idx_t idx) return 0; } -static void free_required_pins(struct fpga_device* dev) +static int reset_required_pins(struct fpga_device* dev) { - free(dev->pinw_req_for_cfg); - dev->pinw_req_for_cfg = 0; + int rc; + + if (!dev->pinw_req_for_cfg) { + dev->pinw_req_for_cfg = malloc(dev->num_pinw_total + * sizeof(*dev->pinw_req_for_cfg)); + if (!dev->pinw_req_for_cfg) FAIL(ENOMEM); + } dev->pinw_req_total = 0; dev->pinw_req_in = 0; + return 0; +fail: + return rc; +} + +void fdev_print_required_pins(struct fpga_model* model, int y, int x, + int type, int type_idx) +{ + struct fpga_device* dev; + int i; + + dev = fdev_p(model, y, x, type, type_idx); + if (!dev) { HERE(); return; } + + printf("y%02i x%02i %s %i inpin", y, x, fdev_type2str(type), type_idx); + if (!dev->pinw_req_in) + printf(" -\n"); + else { + for (i = 0; i < dev->pinw_req_in; i++) + printf(" %s", fdev_pinw_idx2str(type, dev->pinw_req_for_cfg[i])); + printf("\n"); + } + + printf("y%02i x%02i %s %i outpin", y, x, fdev_type2str(type), type_idx); + if (dev->pinw_req_total <= dev->pinw_req_in) + printf(" -\n"); + else { + for (i = dev->pinw_req_in; i < dev->pinw_req_total; i++) + printf(" %s", fdev_pinw_idx2str(type, dev->pinw_req_for_cfg[i])); + printf("\n"); + } +} + +static void add_req_inpin(struct fpga_device* dev, pinw_idx_t pinw_i) +{ + if (dev->pinw_req_total > dev->pinw_req_in) { + memmove(&dev->pinw_req_for_cfg[dev->pinw_req_in+1], + &dev->pinw_req_for_cfg[dev->pinw_req_in], + (dev->pinw_req_total-dev->pinw_req_in) + *sizeof(*dev->pinw_req_for_cfg)); + } + dev->pinw_req_for_cfg[dev->pinw_req_in] = pinw_i; + dev->pinw_req_in++; + dev->pinw_req_total++; +} + +static void add_req_outpin(struct fpga_device* dev, pinw_idx_t pinw_i) +{ + dev->pinw_req_for_cfg[dev->pinw_req_total] = pinw_i; + dev->pinw_req_total++; } #define MAX_LUT_LEN 512 @@ -331,7 +386,8 @@ int fdev_logic_set_lut(struct fpga_model* model, int y, int x, int type_idx, dev = fdev_p(model, y, x, DEV_LOGIC, type_idx); if (!dev) FAIL(EINVAL); - free_required_pins(dev); + rc = reset_required_pins(dev); + if (rc) FAIL(rc); luts = dev->u.logic.luts; if (!luts[which_lut]) { @@ -371,23 +427,50 @@ fail: return rc; } +static void scan_lut_digits(const char* s, int* digits) +{ + int i; + + for (i = 0; i < 6; i++) + digits[i] = 0; + if (!s) return; + for (i = 0; s[i]; i++) { + if (s[i] >= '1' && s[i] <= '6') + digits[s[i]-'1']++; + } +} + int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type, int type_idx) { struct fpga_device* dev; - int rc; + int digits[6]; + int i, j, rc; dev = fdev_p(model, y, x, type, type_idx); if (!dev) FAIL(EINVAL); - free_required_pins(dev); + rc = reset_required_pins(dev); + if (rc) FAIL(rc); if (type == DEV_LOGIC) { -#if 0 -TODO: - // required pinwires depend on the given config and will - // be deleted/invalidated on any config change. - int pinw_req_total, pinw_req_in; - pinw_idx_t* pinw_req_for_cfg; -#endif + if (dev->u.logic.A_used) + add_req_outpin(dev, LOGIC_OUT_A); + if (dev->u.logic.B_used) + add_req_outpin(dev, LOGIC_OUT_B); + if (dev->u.logic.C_used) + add_req_outpin(dev, LOGIC_OUT_C); + if (dev->u.logic.D_used) + add_req_outpin(dev, LOGIC_OUT_D); + for (i = 0; i < sizeof(dev->u.logic.luts) + /sizeof(dev->u.logic.luts[0]); i++) { + if (!dev->u.logic.luts[i]) continue; + scan_lut_digits(dev->u.logic.luts[i], digits); + for (j = 0; j < 6; j++) { + // i/2 because luts order is A5-A6 B5-B6, etc. + if (digits[j]) + add_req_inpin(dev, + LOGIC_IN_A1+(i/2)*6+j); + } + } } return 0; fail: @@ -402,7 +485,10 @@ void fdev_delete(struct fpga_model* model, int y, int x, int type, int type_idx) dev = fdev_p(model, y, x, type, type_idx); if (!dev) { HERE(); return; } if (!dev->instantiated) return; - free_required_pins(dev); + free(dev->pinw_req_for_cfg); + dev->pinw_req_for_cfg = 0; + dev->pinw_req_total = 0; + dev->pinw_req_in = 0; if (dev->type == DEV_LOGIC) { for (i = 0; i < sizeof(dev->u.logic.luts) /sizeof(dev->u.logic.luts[0]); i++) { @@ -825,7 +911,7 @@ int fpga_switch_conns(struct sw_conns* conns) conns->chain.y = conns->y; conns->chain.x = conns->x; conns->chain.start_switch = conns->start_switch; - conns->chain.from_to = SW_FROM; + conns->chain.from_to = conns->from_to; conns->chain.max_chain_size = conns->max_switch_depth; conns->start_switch = STRIDX_NO_ENTRY; @@ -841,7 +927,7 @@ int fpga_switch_conns(struct sw_conns* conns) end_of_chain_str = fpga_switch_str_i(conns->model, conns->y, conns->x, conns->chain.set.sw[conns->chain.set.len-1], - SW_TO); + !conns->from_to); if (end_of_chain_str == STRIDX_NO_ENTRY) { HERE(); goto internal_error; } conns->dest_i = 0; @@ -865,7 +951,7 @@ internal_error: } void printf_swchain(struct fpga_model* model, int y, int x, - str16_t sw, int max_depth, int from_to) + str16_t sw, int from_to, int max_depth) { struct sw_chain chain = { .model = model, .y = y, .x = x, .start_switch = sw, @@ -877,14 +963,14 @@ void printf_swchain(struct fpga_model* model, int y, int x, } void printf_swconns(struct fpga_model* model, int y, int x, - str16_t sw, int max_depth) + str16_t sw, int from_to, int max_depth) { struct sw_conns conns = { .model = model, .y = y, .x = x, .start_switch = sw, - .max_switch_depth = max_depth }; + .from_to = from_to, .max_switch_depth = max_depth }; while (fpga_switch_conns(&conns) != NO_CONN) { printf("sw %s conn y%02i x%02i %s\n", fmt_swset(model, y, x, - &conns.chain.set, SW_FROM), + &conns.chain.set, from_to), conns.dest_y, conns.dest_x, strarray_lookup(&model->str, conns.dest_str_i)); } @@ -894,7 +980,7 @@ int fpga_switch_to_yx(struct switch_to_yx* p) { struct sw_conns conns = { .model = p->model, .y = p->y, .x = p->x, - .start_switch = p->start_switch, + .start_switch = p->start_switch, .from_to = p->from_to, .max_switch_depth = (p->flags & SWTO_YX_MAX_SWITCH_DEPTH) ? p->max_switch_depth : MAX_SW_DEPTH }; @@ -942,6 +1028,18 @@ int fpga_switch_to_yx(struct switch_to_yx* p) return 0; } +void printf_switch_to_result(struct switch_to_yx* p) +{ + printf("switch_to_yx() from y%02i x%02i connpt %s (%s)\n", + p->y, p->x, strarray_lookup(&p->model->str, p->start_switch), + p->from_to == SW_FROM ? "SW_FROM" : "SW_TO"); + printf(" %s y%02i x%02i %s via %s\n", + p->from_to == SW_FROM ? "to" : "from", + p->dest_y, p->dest_x, + strarray_lookup(&p->model->str, p->dest_connpt), + fmt_swset(p->model, p->y, p->x, &p->set, p->from_to)); +} + #define NET_ALLOC_INCREMENT 64 static int fpga_net_useidx(struct fpga_model* model, net_idx_t new_idx) @@ -981,6 +1079,26 @@ int fpga_net_new(struct fpga_model* model, net_idx_t* new_idx) return 0; } +void fpga_net_delete(struct fpga_model* model, net_idx_t net_idx) +{ + struct fpga_net* net; + int i; + + net = &model->nets[net_idx-1]; + for (i = 0; i < net->len; i++) { + if (net->el[i].idx & NET_IDX_IS_PINW) + continue; + if (!fpga_switch_is_used(model, net->el[i].y, net->el[i].x, + net->el[i].idx)) + HERE(); + fpga_switch_disable(model, net->el[i].y, net->el[i].x, + net->el[i].idx); + } + model->nets[net_idx-1].len = 0; + if (model->highest_used_net == net_idx) + model->highest_used_net--; +} + int fpga_net_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next) { int i; @@ -1029,6 +1147,15 @@ fail: return rc; } +int fpga_net_add_switch(struct fpga_model* model, net_idx_t net_i, + int y, int x, swidx_t one_sw) +{ + struct sw_set set; + set.sw[0] = one_sw; + set.len = 1; + return fpga_net_add_switches(model, net_i, y, x, &set); +} + int fpga_net_add_switches(struct fpga_model* model, net_idx_t net_i, int y, int x, const struct sw_set* set) { diff --git a/control.h b/control.h index 54d8854..4d52912 100644 --- a/control.h +++ b/control.h @@ -43,6 +43,8 @@ int fdev_logic_set_lut(struct fpga_model* model, int y, int x, int type_idx, int which_lut, const char* lut_str, int lut_len); int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type, int type_idx); +void fdev_print_required_pins(struct fpga_model* model, int y, int x, + int type, int type_idx); void fdev_delete(struct fpga_model* model, int y, int x, int type, int type_idx); @@ -139,6 +141,7 @@ struct sw_conns int x; // start_switch will be set to STRIDX_NO_ENTRY (0) after first call str16_t start_switch; + int from_to; int max_switch_depth; // return values: @@ -156,9 +159,9 @@ struct sw_conns int fpga_switch_conns(struct sw_conns* conns); void printf_swchain(struct fpga_model* model, int y, int x, - str16_t sw, int max_depth, int from_to); + str16_t sw, int from_to, int max_depth); void printf_swconns(struct fpga_model* model, int y, int x, - str16_t sw, int max_depth); + str16_t sw, int from_to, int max_depth); #define SWTO_YX_DEF 0 #define SWTO_YX_CLOSEST 0x0001 @@ -174,6 +177,7 @@ struct switch_to_yx int y; int x; str16_t start_switch; + int from_to; int max_switch_depth; // only if SWTO_YX_MAX_SWITCH_DEPTH is set str16_t target_connpt; // only if SWTO_YX_TARGET_CONNPT is set @@ -185,6 +189,7 @@ struct switch_to_yx }; int fpga_switch_to_yx(struct switch_to_yx* p); +void printf_switch_to_result(struct switch_to_yx* p); // // nets @@ -221,11 +226,14 @@ typedef int net_idx_t; // net indices are 1-based #define NO_NET 0 int fpga_net_new(struct fpga_model* model, net_idx_t* new_idx); +void fpga_net_delete(struct fpga_model* model, net_idx_t net_idx); // start a new enumeration by calling with last==NO_NET int fpga_net_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next); struct fpga_net* fpga_net_get(struct fpga_model* model, net_idx_t net_i); int fpga_net_add_port(struct fpga_model* model, net_idx_t net_i, int y, int x, dev_idx_t dev_idx, pinw_idx_t pinw_idx); +int fpga_net_add_switch(struct fpga_model* model, net_idx_t net_i, + int y, int x, swidx_t one_sw); int fpga_net_add_switches(struct fpga_model* model, net_idx_t net_i, int y, int x, const struct sw_set* set); void fpga_net_free_all(struct fpga_model* model); diff --git a/model.h b/model.h index f1c5ac3..2e2a8bd 100644 --- a/model.h +++ b/model.h @@ -348,7 +348,8 @@ typedef int dev_type_idx_t; enum { LOGIC_M = 1, LOGIC_L, LOGIC_X }; // All LOGICIN_IN A..D sequences must be exactly sequential as -// here to match initialization in model_device:init_logic(). +// here to match initialization in model_devices.c:init_logic() +// and control.c:fdev_set_required_pins(). enum { // input: LOGIC_IN_A1 = 0, LOGIC_IN_A2, LOGIC_IN_A3, LOGIC_IN_A4, LOGIC_IN_A5, LOGIC_IN_A6, @@ -385,8 +386,11 @@ enum { // input: "AQ", "BQ", "CQ", "DQ", \ "COUT" } -// offsets into fpgadev_logic:luts[] -enum { A5_LUT = 0, A6_LUT, B5_LUT, B6_LUT, C5_LUT, C6_LUT, D5_LUT, D6_LUT, NUM_LUTS }; +// offsets into fpgadev_logic:luts[], also hardcoded in +// control.c:fdev_set_required_pins(), where we assume +// that div2 will lead to A-D +enum { A5_LUT = 0, A6_LUT, B5_LUT, B6_LUT, + C5_LUT, C6_LUT, D5_LUT, D6_LUT, NUM_LUTS }; #define FP_LUT_STR \ { "A5_lut", "A6_lut", "B5_lut", "B6_lut", \ "C5_lut", "C6_lut", "D5_lut", "D6_lut" } diff --git a/parts.c b/parts.c index 6e1c924..dc884d9 100644 --- a/parts.c +++ b/parts.c @@ -70,30 +70,29 @@ const char* get_iob_sitename(int idcode, int idx) return iob_xc6slx9_sitenames[idx]; } -static const int minors_per_major[] = // for slx4 and slx9 -{ - /* 0 */ 4, // 505 bytes = middle 8-bit for each minor? - /* 1 */ 30, // left - /* 2 */ 31, // logic M - /* 3 */ 30, // logic L - /* 4 */ 25, // bram - /* 5 */ 31, // logic M - /* 6 */ 30, // logic L - /* 7 */ 24, // macc - /* 8 */ 31, // logic M - /* 9 */ 31, // center - /* 10 */ 31, // logic M - /* 11 */ 30, // logic L - /* 12 */ 31, // logic M - /* 13 */ 30, // logic L - /* 14 */ 25, // bram - /* 15 */ 31, // logic M - /* 16 */ 30, // logic L - /* 17 */ 30, // right -}; - int get_major_minors(int idcode, int major) { + static const int minors_per_major[] = // for slx9 + { + /* 0 */ 4, // 505 bytes = middle 8-bit for each minor? + /* 1 */ 30, // left + /* 2 */ 31, // logic M + /* 3 */ 30, // logic L + /* 4 */ 25, // bram + /* 5 */ 31, // logic M + /* 6 */ 30, // logic L + /* 7 */ 24, // macc + /* 8 */ 31, // logic M + /* 9 */ 31, // center + /* 10 */ 31, // logic M + /* 11 */ 30, // logic L + /* 12 */ 31, // logic M + /* 13 */ 30, // logic L + /* 14 */ 25, // bram + /* 15 */ 31, // logic M + /* 16 */ 30, // logic L + /* 17 */ 30, // right + }; if ((idcode & IDCODE_MASK) != XC6SLX9) EXIT(1); if (major < 0 || major @@ -101,3 +100,34 @@ int get_major_minors(int idcode, int major) EXIT(1); return minors_per_major[major]; } + +enum major_type get_major_type(int idcode, int major) +{ + static const int major_types[] = // for slx9 + { + /* 0 */ MAJ_ZERO, + /* 1 */ MAJ_LEFT, + /* 2 */ MAJ_LOGIC_XM, + /* 3 */ MAJ_LOGIC_XL, + /* 4 */ MAJ_BRAM, + /* 5 */ MAJ_LOGIC_XM, + /* 6 */ MAJ_LOGIC_XL, + /* 7 */ MAJ_MACC, + /* 8 */ MAJ_LOGIC_XM, + /* 9 */ MAJ_CENTER, + /* 10 */ MAJ_LOGIC_XM, + /* 11 */ MAJ_LOGIC_XL, + /* 12 */ MAJ_LOGIC_XM, + /* 13 */ MAJ_LOGIC_XL, + /* 14 */ MAJ_BRAM, + /* 15 */ MAJ_LOGIC_XM, + /* 16 */ MAJ_LOGIC_XL, + /* 17 */ MAJ_RIGHT + }; + if ((idcode & IDCODE_MASK) != XC6SLX9) + EXIT(1); + if (major < 0 || major + > sizeof(major_types)/sizeof(major_types[0])) + EXIT(1); + return major_types[major]; +} diff --git a/parts.h b/parts.h index c890162..01867bb 100644 --- a/parts.h +++ b/parts.h @@ -39,5 +39,10 @@ #define BITS_LEN (IOB_DATA_START+IOB_DATA_LEN) int get_major_minors(int idcode, int major); + +enum major_type { MAJ_ZERO, MAJ_LEFT, MAJ_RIGHT, MAJ_CENTER, + MAJ_LOGIC_XM, MAJ_LOGIC_XL, MAJ_BRAM, MAJ_MACC }; +enum major_type get_major_type(int idcode, int major); + int get_num_iobs(int idcode); const char* get_iob_sitename(int idcode, int idx);