From d54a0ff81d1ce0e019b29b36cff54e5b448a47bb Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Thu, 13 Sep 2012 09:08:47 +0200 Subject: [PATCH] more switches --- bit_frames.c | 134 +++++++++++++++++++++++++++++++++++++++++++++--- control.c | 112 +++++++++++++++++++++++++++++++++++++++- control.h | 6 ++- model.h | 89 ++++++++++++++++++++++---------- model_devices.c | 6 +-- 5 files changed, 307 insertions(+), 40 deletions(-) diff --git a/bit_frames.c b/bit_frames.c index 7385c3f..50750a6 100644 --- a/bit_frames.c +++ b/bit_frames.c @@ -321,11 +321,12 @@ fail: return rc; } -static int mip_is_set(struct extract_state* es, int y, int x, +static int bitpos_is_set(struct extract_state* es, int y, int x, struct sw_bitpos* swpos, int* is_set) { int row_num, row_pos, start_in_frame, two_bits_val, rc; +// TODO: does not support minor20 correctly *is_set = 0; is_in_row(es->model, y, &row_num, &row_pos); if (row_num == -1 || row_pos == -1 @@ -353,11 +354,12 @@ fail: return rc; } -static int mip_clear_bits(struct extract_state* es, int y, int x, +static int bitpos_clear_bits(struct extract_state* es, int y, int x, struct sw_bitpos* swpos) { int row_num, row_pos, start_in_frame, rc; +// TODO: does not support minor20 correctly is_in_row(es->model, y, &row_num, &row_pos); if (row_num == -1 || row_pos == -1 || row_pos == HCLK_POS) FAIL(EINVAL); @@ -387,7 +389,7 @@ static int extract_routing_switches(struct extract_state* es, int y, int x) if (y != 68 || x != 12) return 0; for (i = 0; i < es->num_bit_pos; i++) { - rc = mip_is_set(es, y, x, &es->bit_pos[i], &is_set); + rc = bitpos_is_set(es, y, x, &es->bit_pos[i], &is_set); if (rc) FAIL(rc); if (!is_set) continue; @@ -401,7 +403,7 @@ if (y != 68 || x != 12) return 0; es->yx_pos[es->num_yx_pos].x = x; es->yx_pos[es->num_yx_pos].idx = es->bit_pos[i].uni_dir; es->num_yx_pos++; - rc = mip_clear_bits(es, y, x, &es->bit_pos[i]); + rc = bitpos_clear_bits(es, y, x, &es->bit_pos[i]); if (rc) FAIL(rc); } return 0; @@ -483,6 +485,31 @@ static int mod4_calc(int a, int b) return (unsigned int) (a+b)%4; } +struct sw_mip_src +{ + int m0_sw_to; + int m0_two_bits_o; + int m0_two_bits_val; + int m0_one_bit_start; + + int m1_sw_to; + int m1_two_bits_o; + int m1_two_bits_val; + int m1_one_bit_start; + + int src_wire[6]; +}; + +struct sw_mi20_src +{ + int sw_to; + int two_bits_o; + int two_bits_val; + int one_bit_start; + + int src_wire[6]; +}; + static int construct_extract_state(struct extract_state* es, struct fpga_model* model) { char from_str[MAX_WIRENAME_LEN], to_str[MAX_WIRENAME_LEN]; @@ -494,6 +521,35 @@ static int construct_extract_state(struct extract_state* es, struct fpga_model* if (model->first_routing_y == -1) FAIL(EINVAL); + // mip 10 + { const struct sw_mip_src src[] = { + {DW + ((W_EL1*4+2) | DIR_BEG), 0, 2, 3, DW + ((W_NR1*4+3) | DIR_BEG), 14, 1, 2, + {LW + (LO_BMUX|LD1), LW + (LO_DQ|LD1), LW + (LO_D|LD1), + LW + LO_BMUX, LW + LO_DQ, LW + LO_D}}}; + + for (i = 0; i < sizeof(src)/sizeof(*src); i++) { + for (j = 0; j < sizeof(src[0].src_wire)/sizeof(src[0].src_wire[0]); j++) { + if (src[i].src_wire[j] == UNDEF) continue; + + es->bit_pos[es->num_bit_pos].minor = 20; + es->bit_pos[es->num_bit_pos].two_bits_o = src[i].m0_two_bits_o; + es->bit_pos[es->num_bit_pos].two_bits_val = src[i].m0_two_bits_val; + es->bit_pos[es->num_bit_pos].one_bit_o = src[i].m0_one_bit_start + j*2; + es->bit_pos[es->num_bit_pos].uni_dir = fpga_switch_lookup(es->model, + es->model->first_routing_y, es->model->first_routing_x, + fpga_wirestr_i(es->model, src[i].src_wire[j]), + fpga_wirestr_i(es->model, src[i].m0_sw_to)); + if (es->bit_pos[es->num_bit_pos].uni_dir == NO_SWITCH) { + fprintf(stderr, "#E routing switch %s -> %s not in model\n", + fpga_wirestr(es->model, src[i].src_wire[j]), + fpga_wirestr(es->model, src[i].m0_sw_to)); + FAIL(EINVAL); + } + es->bit_pos[es->num_bit_pos].rev_dir = NO_SWITCH; + es->num_bit_pos++; + } + }} +#if 0 // switches from logicout to dirwires (6*2*2*4*6=576 switches) for (i = 0; i < DIRBEG_ROW; i++) { cur_pair_start = (i/2)*2; @@ -530,7 +586,8 @@ static int construct_extract_state(struct extract_state* es, struct fpga_model* } } } - +#endif +#if 0 // VCC (32 switches) and GFAN (32 switches +4 bidir) for (i = 12; i <= 18; i+=2) { // mip12/14/16/18 for (j = 0; j <= 3; j++) { // 4 rows @@ -610,6 +667,64 @@ static int construct_extract_state(struct extract_state* es, struct fpga_model* } } } + + // minor 20 switches (SR, CLK, GFAN = 113 switches (4 bidir added on other side)) + { const struct sw_mi20_src src[] = { + {SR1, 6, 3, 0, {GCLK11, GCLK10, GCLK13, GCLK12, GCLK9, GCLK8}}, + {SR1, 6, 2, 0, {DW+W_WR1*4+2, DW+W_NR1*4+2, + VCC_WIRE, GND_WIRE, DW+W_ER1*4+2, DW+W_SR1*4+2}}, + {SR1, 6, 1, 0, {FAN_B, LW+(LI_DI|LD1), LW+(LI_BX|LD1), + LW+LI_BX, GCLK15, GCLK14}}, + + {SR0, 8, 3, 10, {GCLK8, GCLK9, GCLK10, GCLK13, GCLK12, GCLK11}}, + {SR0, 8, 2, 10, {GCLK14, GCLK15, LW+(LI_DI|LD1), LW+(LI_BX|LD1), + LW+LI_BX, FAN_B}}, + {SR0, 8, 1, 10, {DW+W_SR1*4+2, DW+W_ER1*4+2, DW+W_NR1*4+2, + VCC_WIRE, UNDEF, DW+W_WR1*4+2}}, + + {CLK0, 16, 3, 18, {GCLK0, GCLK1, GCLK2, GCLK5, GCLK4, GCLK3}}, + {CLK0, 16, 2, 18, {GCLK6, GCLK7, GCLK8, GCLK11, GCLK10, GCLK9}}, + {CLK0, 16, 1, 18, {GCLK12, GCLK13, GCLK14, LW+(LI_BX|LD1), LW+(LI_CI|LD1), GCLK15}}, + {CLK0, 16, 0, 18, {DW+W_NR1*4+2, DW+W_WR1*4+2, + DW+W_SR1*4+1, VCC_WIRE, UNDEF, DW+W_ER1*4+1}}, + + {CLK1, 46, 3, 40, {GCLK3, GCLK2, GCLK5, GCLK4, GCLK1, GCLK0}}, + {CLK1, 46, 2, 40, {GCLK15, GCLK14, LW+(LI_BX|LD1), LW+(LI_CI|LD1), GCLK13, GCLK12}}, + {CLK1, 46, 1, 40, {GCLK9, GCLK8, GCLK11, GCLK10, GCLK7, GCLK6}}, + {CLK1, 46, 0, 40, {DW+W_ER1*4+1, DW+W_SR1*4+1, VCC_WIRE, + UNDEF, DW+W_WR1*4+2, DW+W_NR1*4+2}}, + + {GFAN0, 54, 3, 48, {GCLK3, GCLK4, GCLK5, GCLK2, GCLK1, GCLK0}}, + {GFAN0, 54, 2, 48, {DW+W_WR1*4+1, GND_WIRE, VCC_WIRE, DW+W_NR1*4+1, DW+W_ER1*4+1, DW+W_SR1*4+1}}, + {GFAN0, 54, 1, 48, {LW+(LI_CE|LD1), UNDEF, UNDEF, LW+(LI_CI|LD1), GCLK7, GCLK6}}, + + {GFAN1, 56, 3, 58, {GCLK0, GCLK1, GCLK4, GCLK5, GCLK2, GCLK3}}, + {GFAN1, 56, 2, 58, {GCLK6, GCLK7, LW+(LI_AX|LD1), LW+LI_AX, UNDEF, UNDEF}}, + {GFAN1, 56, 1, 58, {DW+W_SR1*4+1, DW+W_ER1*4+1, GND_WIRE, VCC_WIRE, DW+W_NR1*4+1, DW+W_WR1*4+1}}}; + + for (i = 0; i < sizeof(src)/sizeof(*src); i++) { + for (j = 0; j < sizeof(src[0].src_wire)/sizeof(src[0].src_wire[0]); j++) { + if (src[i].src_wire[j] == UNDEF) continue; + + es->bit_pos[es->num_bit_pos].minor = 20; + es->bit_pos[es->num_bit_pos].two_bits_o = src[i].two_bits_o; + es->bit_pos[es->num_bit_pos].two_bits_val = src[i].two_bits_val; + es->bit_pos[es->num_bit_pos].one_bit_o = src[i].one_bit_start + j; + es->bit_pos[es->num_bit_pos].uni_dir = fpga_switch_lookup(es->model, + es->model->first_routing_y, es->model->first_routing_x, + fpga_wirestr_i(es->model, src[i].src_wire[j]), + fpga_wirestr_i(es->model, src[i].sw_to)); + if (es->bit_pos[es->num_bit_pos].uni_dir == NO_SWITCH) { + fprintf(stderr, "#E routing switch %s -> %s not in model\n", + fpga_wirestr(es->model, src[i].src_wire[j]), + fpga_wirestr(es->model, src[i].sw_to)); + FAIL(EINVAL); + } + es->bit_pos[es->num_bit_pos].rev_dir = NO_SWITCH; + es->num_bit_pos++; + } + }} +#endif return 0; fail: return rc; @@ -656,14 +771,17 @@ int printf_swbits(struct fpga_model* model) { struct extract_state es; char bit_str[129]; - int i, j, rc; + int i, j, width, rc; rc = construct_extract_state(&es, model); if (rc) FAIL(rc); - bit_str[128] = 0; for (i = 0; i < es.num_bit_pos; i++) { - for (j = 0; j < 128; j++) + + width = (es.bit_pos[i].minor == 20) ? 64 : 128; + for (j = 0; j < width; j++) bit_str[j] = '0'; + bit_str[j] = 0; + if (es.bit_pos[i].two_bits_val & 2) bit_str[es.bit_pos[i].two_bits_o] = '1'; if (es.bit_pos[i].two_bits_val & 1) diff --git a/control.c b/control.c index 732bbb7..9a5f1d3 100644 --- a/control.c +++ b/control.c @@ -344,7 +344,7 @@ str16_t fdev_logic_pinstr_i(struct fpga_model* model, pinw_idx_t idx, int ld1_ty return str_i; } -int fdev_logic_inbit(pinw_idx_t idx, int ld1_type) +int fdev_logic_inbit(pinw_idx_t idx) { if (idx & LD1) { idx &= ~LD1; @@ -382,6 +382,45 @@ int fdev_logic_inbit(pinw_idx_t idx, int ld1_type) return -1; } +int fdev_logic_outbit(pinw_idx_t idx) +{ + if (idx & LD1) { + idx &= ~LD1; + switch (idx) { + case LO_A: return M_A; + case LO_AMUX: return M_AMUX; + case LO_AQ: return M_AQ; + case LO_B: return M_B; + case LO_BMUX: return M_BMUX; + case LO_BQ: return M_BQ; + case LO_C: return M_C; + case LO_CMUX: return M_CMUX; + case LO_CQ: return M_CQ; + case LO_D: return M_D; + case LO_DMUX: return M_DMUX; + case LO_DQ: return M_DQ; + } + HERE(); + return -1; + } + switch (idx) { + case LO_A: return X_A; + case LO_AMUX: return X_AMUX; + case LO_AQ: return X_AQ; + case LO_B: return X_B; + case LO_BMUX: return X_BMUX; + case LO_BQ: return X_BQ; + case LO_C: return X_C; + case LO_CMUX: return X_CMUX; + case LO_CQ: return X_CQ; + case LO_D: return X_D; + case LO_DMUX: return X_DMUX; + case LO_DQ: return X_DQ; + } + HERE(); + return -1; +} + static int reset_required_pins(struct fpga_device* dev) { int rc; @@ -1788,3 +1827,74 @@ void fprintf_net(FILE* f, struct fpga_model* model, net_idx_t net_i) net->el[i].x, net->el[i].idx)); } } + +const char* fpga_wirestr(struct fpga_model* model, enum extra_wires wire) +{ + enum { NUM_BUFS = 8, BUF_SIZE = 64 }; + static char buf[NUM_BUFS][BUF_SIZE]; + static int last_buf = 0; + + switch (wire) { + case GFAN0: return "GFAN0"; + case GFAN1: return "GFAN1"; + case CLK0: return "CLK0"; + case CLK1: return "CLK1"; + case SR0: return "SR0"; + case SR1: return "SR1"; + case GND_WIRE: return "GND_WIRE"; + case VCC_WIRE: return "VCC_WIRE"; + case FAN_B: return "FAN_B"; + case LOGICIN20: return "LOGICIN20"; + case LOGICIN21: return "LOGICIN21"; + case LOGICIN44: return "LOGICIN44"; + case LOGICIN52: return "LOGICIN52"; + case LOGICIN_N21: return "LOGICIN_N21"; + case LOGICIN_N28: return "LOGICIN_N28"; + case LOGICIN_N52: return "LOGICIN_N52"; + case LOGICIN_N60: return "LOGICIN_N60"; + case LOGICIN_S20: return "LOGICIN_S20"; + case LOGICIN_S36: return "LOGICIN_S36"; + case LOGICIN_S44: return "LOGICIN_S44"; + case LOGICIN_S62: return "LOGICIN_S62"; + default: ; + } + + last_buf = (last_buf+1)%NUM_BUFS; + buf[last_buf][0] = 0; + if (wire >= GCLK0 && wire <= GCLK15) + snprintf(buf[last_buf], sizeof(buf[0]), "GCLK%i", wire-GCLK0); + else if (wire >= DW && wire <= DW_LAST) { + char beg_end; + int s0n3_flag; + + wire -= DW; + beg_end = (wire & DIR_BEG) ? 'B' : 'E'; + s0n3_flag = wire & DIR_S0N3; + wire &= ~(DIR_BEG|DIR_S0N3); + if (s0n3_flag) { + if (wire%4 == 0) { + snprintf(buf[last_buf], sizeof(buf[0]), + "%s%c_S0", wire_base(wire/4), beg_end); + } else if (wire%4 == 3) { + snprintf(buf[last_buf], sizeof(buf[0]), + "%s%c_N3", wire_base(wire/4), beg_end); + } else HERE(); + } else + snprintf(buf[last_buf], sizeof(buf[0]), + "%s%c%i", wire_base(wire/4), beg_end, wire%4); + + } else if (wire >= LW && wire <= LW_LAST) { + wire -= LW; + if ((wire&(~LD1)) >= LI_FIRST && (wire&(~LD1)) <= LI_LAST) + snprintf(buf[last_buf], sizeof(buf[0]), "LOGICIN_B%i", fdev_logic_inbit(wire)); + else if ((wire&(~LD1)) >= LO_FIRST && (wire&(~LD1)) <= LO_LAST) + snprintf(buf[last_buf], sizeof(buf[0]), "LOGICOUT%i", fdev_logic_outbit(wire)); + else HERE(); + } else HERE(); + return buf[last_buf]; +} + +str16_t fpga_wirestr_i(struct fpga_model* model, enum extra_wires wire) +{ + return strarray_find(&model->str, fpga_wirestr(model, wire)); +} diff --git a/control.h b/control.h index a58b6bf..be72bf9 100644 --- a/control.h +++ b/control.h @@ -44,7 +44,8 @@ const char* fdev_pinw_idx2str(int devtype, pinw_idx_t idx); // the second logic device (L or M). const char* fdev_logic_pinstr(pinw_idx_t idx, int ld1_type); str16_t fdev_logic_pinstr_i(struct fpga_model* model, pinw_idx_t idx, int ld1_type); -int fdev_logic_inbit(pinw_idx_t idx, int ld1_type); +int fdev_logic_inbit(pinw_idx_t idx); +int fdev_logic_outbit(pinw_idx_t idx); // lut_a2d is LUT_A to LUT_D value, lut_5or6 is int 5 or int 6. int fdev_logic_set_lut(struct fpga_model* model, int y, int x, int type_idx, @@ -324,3 +325,6 @@ int fpga_net_remove_sw(struct fpga_model* model, net_idx_t net_i, void fpga_net_free_all(struct fpga_model* model); void fprintf_net(FILE* f, struct fpga_model* model, net_idx_t net_i); + +const char* fpga_wirestr(struct fpga_model* model, enum extra_wires wire); +str16_t fpga_wirestr_i(struct fpga_model* model, enum extra_wires wire); diff --git a/model.h b/model.h index f7d41fc..3622d54 100644 --- a/model.h +++ b/model.h @@ -362,8 +362,11 @@ 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_devices.c:init_logic() // and control.c:fdev_set_required_pins(). -enum { // input: - LI_A1 = 0, +enum { + // input: + LI_FIRST = 0, + + LI_A1 = LI_FIRST, LI_A2, LI_A3, LI_A4, LI_A5, LI_A6, LI_B1, LI_B2, LI_B3, LI_B4, LI_B5, LI_B6, @@ -377,13 +380,18 @@ enum { // input: LI_CIN, // only some L and M devs have this // only for M: LI_WE, LI_AI, LI_BI, LI_CI, LI_DI, + + LI_LAST = LI_DI, + // output: - LO_A, LO_B, LO_C, LO_D, + LO_FIRST, + + LO_A = LO_FIRST, LO_B, LO_C, LO_D, LO_AMUX, LO_BMUX, LO_CMUX, LO_DMUX, LO_AQ, LO_BQ, LO_CQ, LO_DQ, - LO_COUT }; // only some L and M devs have this -#define LOGIC_LAST_INPUT_PINW LI_DI -#define LOGIC_LAST_OUTPUT_PINW LO_COUT + LO_COUT, // only some L and M devs have this + + LO_LAST = LO_COUT }; #define LOGIC_PINW_STR \ { "A1", "A2", "A3", "A4", "A5", "A6", \ "B1", "B2", "B3", "B4", "B5", "B6", \ @@ -703,27 +711,6 @@ enum logicout_wire { 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 { - UNDEF = 100, - FAN_B, - GFAN0, - GFAN1, - LOGICIN20, - LOGICIN21, - LOGICIN44, - LOGICIN52, - LOGICIN_N21, - LOGICIN_N28, - LOGICIN_N52, - LOGICIN_N60, - LOGICIN_S20, - LOGICIN_S36, - LOGICIN_S44, - LOGICIN_S62 -}; - // The wires are ordered clockwise. Order is important for // wire_to_NESW4(). enum wire_type @@ -778,3 +765,51 @@ enum wire_type const char* wire_base(enum wire_type w); enum wire_type rotate_wire(enum wire_type cur, int off); enum wire_type wire_to_len(enum wire_type w, int first_len); + +// Those two flags can be OR'ed into the DW..DW_LAST range. +// DIR_BEG signals a 'B' line - the default is 'E' endpoint. +// DIR_S0N3 turns 0 into _S0 and 3 into _N3. +#define DIR_BEG 0x100 +#define DIR_S0N3 0x200 + +// 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 { + UNDEF = 100, + FAN_B, + GFAN0, + GFAN1, + CLK0, + CLK1, + SR0, + SR1, + LOGICIN20, + LOGICIN21, + LOGICIN44, + LOGICIN52, + LOGICIN_N21, + LOGICIN_N28, + LOGICIN_N52, + LOGICIN_N60, + LOGICIN_S20, + LOGICIN_S36, + LOGICIN_S44, + LOGICIN_S62, + VCC_WIRE = 150, + GND_WIRE, + GCLK0 = 200, GCLK1, GCLK2, GCLK3, GCLK4, GCLK5, GCLK6, GCLK7, + GCLK8, GCLK9, GCLK10, GCLK11, GCLK12, GCLK13, GCLK14, GCLK15, + + // direction wires + DW = 500, + // dirwires can be encoded times-4, for example + // NL1E2 = DW + W_NL1*4 + 2 + // DIR_BEG and DIR_S0N3 can be OR'ed into this range. + DW_LAST = 1499, + + // logic wires + LW, + // logic wires are encoded here as LOGIC_BEG+LI_A1. LD1 (0x100) + // can be OR'ed to the LI or LO value. + LW_LAST = 1999 +}; diff --git a/model_devices.c b/model_devices.c index 771c6af..e43c864 100644 --- a/model_devices.c +++ b/model_devices.c @@ -453,11 +453,11 @@ static int init_logic(struct fpga_model* model, int y, int x, int idx) ? "XX_" : "X_"; } else FAIL(EINVAL); - tile->devs[idx].pinw = calloc((LOGIC_LAST_OUTPUT_PINW+1) + tile->devs[idx].pinw = calloc((LO_LAST+1) *sizeof(tile->devs[idx].pinw[0]), /*elsize*/ 1); if (!tile->devs[idx].pinw) FAIL(ENOMEM); - tile->devs[idx].num_pinw_total = LOGIC_LAST_OUTPUT_PINW+1; - tile->devs[idx].num_pinw_in = LOGIC_LAST_INPUT_PINW+1; + tile->devs[idx].num_pinw_total = LO_LAST+1; + tile->devs[idx].num_pinw_in = LI_LAST+1; for (i = 0; i < 4; i++) { // 'A' to 'D' for (j = 0; j < 6; j++) {