diff --git a/merge_log.sh b/merge_log.sh index ef38812..55cd5ee 100755 --- a/merge_log.sh +++ b/merge_log.sh @@ -1,3 +1,3 @@ #!/bin/bash -grep '^+net\|^+r0.*v64_'|awk '/^+r0.*v64_/{printf "%s %s\n",$0,x};{x=$0};'|sort +grep '^+net\|^+r0.*v64_'|awk '/^+r0.*v64_/{if (x~/^+net/) printf "%s %s\n",$0,x};{x=$0};'|sort diff --git a/model_switches.c b/model_switches.c index 998ca75..1c0924f 100644 --- a/model_switches.c +++ b/model_switches.c @@ -1299,6 +1299,7 @@ static int add_switches(struct set_of_switches* dest, return 0; } +// todo: should try to rewrite this using groups... static int build_dirwire_switches(struct set_of_switches* dest, enum wire_type src_wire) { @@ -1331,6 +1332,23 @@ xout: return rc; } +// See this as an array of groups of 4 wires, the order inside +// the groups is significant as well. It's how the wire structure +// is expressed best - several places build their logic on this, +// search for logicin_g4. +// todo: not sure this is deal. vcc goes to 0/1 and 6/7, and logicio_extra +// seems to have groups also corresponding to 0/1/6/7 and 2-5 +static int logicin_g4[] = { + /* g00 mip16-3 */ M_B6, X_A6, M_C1, X_AX, /* g01 mip18-3 */ M_AI, X_B1, M_D3, X_C3, + /* g02 mip12-3 */ M_C3, X_D3, M_B2, M_WE, /* g03 mip14-3 */ M_AX, X_C2, M_A6, X_B6, + /* g04 mip16-2 */ M_B5, X_A5, M_BX, X_D2, /* g05 mip18-2 */ M_A2, M_BI, M_D4, X_C4, + /* g06 mip12-2 */ M_C4, X_D4, X_A1, X_CE, /* g07 mip14-2 */ M_D1, X_BX, M_A5, X_B5, + /* g08 mip16-1 */ M_B4, X_A4, X_CX, X_D1, /* g09 mip18-1 */ M_A1, M_CE, M_D5, X_C5, + /* g10 mip12-1 */ M_C5, X_D5, M_CI, X_A2, /* g11 mip14-1 */ M_CX, M_D2, M_A4, X_B4, + /* g12 mip16-0 */ M_B3, X_A3, M_C2, M_DX, /* g13 mip18-0 */ X_B2, FAN_B, M_D6, X_C6, + /* g14 mip12-0 */ M_C6, X_D6, M_B1, M_DI, /* g15 mip14-0 */ X_C1, X_DX, M_A3, X_B3, +}; + static int add_logicio_extra(struct fpga_model* model, int y, int x, int routing_io) { @@ -1354,7 +1372,7 @@ static int add_logicio_extra(struct fpga_model* model, /* group 14 */ M_A3, M_C6, X_B3, X_D6, /* group 15 */ M_A4, M_C5, X_B4, X_D5, }; - // 16 groups of 5. Order of groups in sync with in_w. + // 16 groups of 5. Order of groups in sync with dest_w. // Each dest_w group can only have 1 bidir wire, which is // flagged there. The flag in src_w signals whether that one // bidir line in dest_w is to be driven as bidir or not. @@ -1429,11 +1447,18 @@ xout: return rc; } +// switch device: +// - position of 2-bit selector, either 2 bits in 1 minor (mi20), or 1+1 +// bits in 2 minors (mip0-18) +// - array of 4 pointers to wire groups, each containing up to 6 wires + + static int add_logicout_switches(struct fpga_model* model, int y, int x, int routing_io) { // 8 groups of 3. The order inside the group does not matter, // but the order of the groups does. +// TODO: these out_wires[] groups also matter in bit positions, fix positions! static int out_wires[] = { /* group 0 */ M_A, M_CMUX, X_AQ, /* group 1 */ M_AQ, X_A, X_CMUX, @@ -1441,22 +1466,8 @@ static int add_logicout_switches(struct fpga_model* model, /* group 3 */ M_B, M_DMUX, X_BQ, /* group 4 */ M_AMUX, M_C, X_CQ, /* group 5 */ M_CQ, X_AMUX, X_C, - /* group 6 */ M_BMUX, M_D, X_DQ, - /* group 7 */ M_DQ, X_BMUX, X_D - }; - // Those are the logicout wires going back into logicin, for - // each group of out wires. Again the order inside the groups - // does not matter, but the group order must match the out wire - // group order. - static int logicin_wires[] = { - /* group 0 */ M_AI, M_B6, M_C1, M_D3, X_A6, X_AX, X_B1, X_C3, - /* group 1 */ M_A6, M_AX, M_B2, M_C3, M_WE, X_B6, X_C2, X_D3, - /* group 2 */ M_A2, M_B5, M_BI, M_BX, M_D4, X_A5, X_C4, X_D2, - /* group 3 */ M_A5, M_C4, M_D1, X_A1, X_B5, X_BX, X_CE, X_D4, - /* group 4 */ M_A1, M_B4, M_CE, M_D5, X_A4, X_C5, X_CX, X_D1, - /* group 5 */ M_A4, M_C5, M_CI, M_CX, M_D2, X_A2, X_B4, X_D5, - /* group 6 */ M_A3, M_B1, M_C6, M_DI, X_B3, X_C1, X_D6, X_DX, - /* group 7 */ M_B3, M_C2, M_D6, M_DX, X_A3, X_B2, X_C6, FAN_B + /* group 6 */ M_DQ, X_BMUX, X_D, + /* group 7 */ M_BMUX, M_D, X_DQ, }; enum wire_type wire; char from_str[32], to_str[32]; @@ -1511,10 +1522,10 @@ static int add_logicout_switches(struct fpga_model* model, // back to logicin for (j = 0; j < 8; j++) { - if (logicin_wires[(i/3)*8 + j] == FAN_B) + if (logicin_g4[(i/3)*8 + j] == FAN_B) strcpy(to_str, "FAN_B"); else - strcpy(to_str, logicin_s(logicin_wires[(i/3)*8 + j], routing_io)); + strcpy(to_str, logicin_s(logicin_g4[(i/3)*8 + j], routing_io)); rc = add_switch(model, y, x, from_str, to_str, 0 /* bidir */); if (rc) goto xout; @@ -1532,6 +1543,13 @@ static int add_logicin_switch(struct fpga_model* model, int y, int x, char from_str[32], to_str[32]; int rc; + if (dirwire == W_NW2 || dirwire == W_NL1) { + dirwire_num++; + if (dirwire_num > 3) + dirwire_num = 0; + } + if (dirwire_num == -1) + dirwire_num = 3; if (dirwire_num == 0 && logicin_num & LWF_SOUTH0) snprintf(from_str, sizeof(from_str), "%sE_S0", wire_base(dirwire)); @@ -1555,121 +1573,104 @@ xout: return rc; } -// This function adds the switches for all dirwires in the -// quarter belonging to dirwire. So dirwire should only be -// one of W_NN2, W_EE2, W_SS2 or W_WW2 - the rest is handled -// inside the function. -static int add_logicin_switch_quart(struct fpga_model* model, int y, int x, - enum wire_type dirwire, int dirwire_num, - int logicin_num) -{ - enum wire_type len1; - int rc; - - rc = add_logicin_switch(model, y, x, dirwire, dirwire_num, - logicin_num); - if (rc) goto xout; - len1 = W_COUNTER_CLOCKWISE(W_TO_LEN1(dirwire)); - rc = add_logicin_switch(model, y, x, len1, - dirwire_num, logicin_num); - if (rc) goto xout; - - if (dirwire == W_WW2) { - int nw_num = dirwire_num+1; - if (nw_num > 3) - nw_num = 0; - rc = add_logicin_switch(model, y, x, W_NW2, nw_num, - logicin_num); - if (rc) goto xout; - rc = add_logicin_switch(model, y, x, W_NL1, nw_num, - logicin_num); - if (rc) goto xout; - } else { - rc = add_logicin_switch(model, y, x, W_CLOCKWISE(dirwire), - dirwire_num, logicin_num); - if (rc) goto xout; - len1 = rotate_wire(len1, 3); - rc = add_logicin_switch(model, y, x, len1, - dirwire_num, logicin_num); - if (rc) goto xout; - } - return 0; -xout: - return rc; -} - -static int loop_and_rotate_over_wires(struct fpga_model* model, int y, int x, - int* wires, int num_wires, int early_decrement) -{ - int i, rc; - - // - // We loop over the wires times 4 because each wire will - // be processed at NN, EE, SS and WW. - // - // i/4 position in the wire array - // 3-(i/4)%4 num of wire 0:3 for current element in the wire array - // i%4 NN (0) - EE (1) - SS (2) - WW (3) - // - - for (i = 0; i < num_wires*4; i++) { - rc = add_logicin_switch_quart(model, y, x, FIRST_LEN2+(i%4)*2, - 3-((i+early_decrement)/4)%4, wires[i/4]); - if (rc) goto xout; - } - return 0; -xout: - return rc; -} +static enum wire_type dirwire_g4[] = { + W_NN2, W_NE2, W_WR1, W_EL1, + W_EE2, W_SE2, W_NR1, W_SL1, + W_SS2, W_SW2, W_ER1, W_WL1, + W_WW2, W_NW2, W_SR1, W_NL1 +}; static int add_logicin_switches(struct fpga_model* model, int y, int x) { - int rc; - { static int decrement_at_NN[] = - { M_DI | LWF_SOUTH0, M_CI, X_CE, M_WE, - M_B1 | LWF_SOUTH0, X_A2, X_A1, M_B2, - M_C6 | LWF_SOUTH0, M_C5, M_C4, M_C3, - X_D6 | LWF_SOUTH0, X_D5, X_D4, X_D3 }; + int logicin_wire, i, j, k, l, rc; - rc = loop_and_rotate_over_wires(model, y, x, decrement_at_NN, - sizeof(decrement_at_NN)/sizeof(decrement_at_NN[0]), - 0 /* early_decrement */); - if (rc) goto xout; } + // + // There are probably ways to merge all 4 loops into one + // nicely by regrouping better. For now we have 4 loops + // that differ like this: + // + // 1) g4 groups: 2 6 10 14 + // LWF_SOUTH0 for i == 3 (group 14) + // decrement at NN (=never), k > 3 + // + // 2) g4 groups: 15 3 7 11 + // LWF_SOUTH0 for i == 0 (group 15) + // decrement at EE, k > 0 + // + // 3) g4 groups: 1 5 9 13 + // LWF_NORTH3 for i == 0 (group 1) + // decrement at SS, k > 1 + // + // 4) g4 groups: 0 4 8 12 + // LWF_NORTH3 for i == 0 (group 0) + // decrement at WW, k > 2 + // - { static int decrement_at_EE[] = - { M_CX, X_BX, M_AX, X_DX | LWF_SOUTH0, - M_D2, M_D1, X_C2, X_C1 | LWF_SOUTH0, - M_A4, M_A5, M_A6, M_A3 | LWF_SOUTH0, - X_B4, X_B5, X_B6, X_B3 | LWF_SOUTH0 }; + // i = logicin groups (the destinations of our switches) + for (i = 0; i < 4; i++) { // we want: 2, 6, 10, 14 + // j = each destination logicin wire + for (j = 0; j < 4; j++) { + logicin_wire = logicin_g4[((2+i*4)%16)*4 + j]; + if (i == 3) + logicin_wire |= LWF_SOUTH0; + for (k = 0; k < 4; k++) { // k = dirwire groups/quarts + for (l = 0; l < 4; l++) { // l = each dirwire in a group/quart + rc = add_logicin_switch(model, y, x, dirwire_g4[k*4+l], k > 3 ? i-1 : i, logicin_wire); + if (rc) FAIL(rc); + } + } + } + } - rc = loop_and_rotate_over_wires(model, y, x, decrement_at_EE, - sizeof(decrement_at_EE)/sizeof(decrement_at_EE[0]), - 3 /* early_decrement */); - if (rc) goto xout; } + // i = logicin groups (the destinations of our switches) + for (i = 0; i < 4; i++) { // we want: 15, 3, 7, 11 + // j = each destination logicin wire + for (j = 0; j < 4; j++) { + logicin_wire = logicin_g4[((15+i*4)%16)*4 + j]; + if (i == 0) + logicin_wire |= LWF_SOUTH0; + for (k = 0; k < 4; k++) { // k = dirwire groups/quarts + for (l = 0; l < 4; l++) { // l = each dirwire in a group/quart + rc = add_logicin_switch(model, y, x, dirwire_g4[k*4+l], k > 0 ? i-1 : i, logicin_wire); + if (rc) FAIL(rc); + } + } + } + } - { static int decrement_at_SS[] = - { FAN_B, M_CE, M_BI, M_AI | LWF_NORTH3, - X_B2, M_A1, M_A2, X_B1 | LWF_NORTH3, - X_C6, X_C5, X_C4, X_C3 | LWF_NORTH3, - M_D6, M_D5, M_D4, M_D3 | LWF_NORTH3 }; + // i = logicin groups (the destinations of our switches) + for (i = 0; i < 4; i++) { // we want: 1, 5, 9, 13 + // j = each destination logicin wire + for (j = 0; j < 4; j++) { + logicin_wire = logicin_g4[((1+i*4)%16)*4 + j]; + if (i == 0) + logicin_wire |= LWF_NORTH3; + for (k = 0; k < 4; k++) { // k = dirwire groups/quarts + for (l = 0; l < 4; l++) { // l = each dirwire in a group/quart + rc = add_logicin_switch(model, y, x, dirwire_g4[k*4+l], k > 1 ? i-1 : i, logicin_wire); + if (rc) FAIL(rc); + } + } + } + } - rc = loop_and_rotate_over_wires(model, y, x, decrement_at_SS, - sizeof(decrement_at_SS)/sizeof(decrement_at_SS[0]), - 2 /* early_decrement */); - if (rc) goto xout; } - - { static int decrement_at_WW[] = - { M_DX, X_CX, M_BX, X_AX | LWF_NORTH3, - M_C2, X_D1, X_D2, M_C1 | LWF_NORTH3, - X_A3, X_A4, X_A5, X_A6 | LWF_NORTH3, - M_B3, M_B4, M_B5, M_B6 | LWF_NORTH3 }; - - rc = loop_and_rotate_over_wires(model, y, x, decrement_at_WW, - sizeof(decrement_at_WW)/sizeof(decrement_at_WW[0]), - 1 /* early_decrement */); - if (rc) goto xout; } + // i = logicin groups (the destinations of our switches) + for (i = 0; i < 4; i++) { // we want: 0, 4, 8, 12 + // j = each destination logicin wire + for (j = 0; j < 4; j++) { + logicin_wire = logicin_g4[((0+i*4)%16)*4 + j]; + if (i == 0) + logicin_wire |= LWF_NORTH3; + for (k = 0; k < 4; k++) { // k = dirwire groups/quarts + for (l = 0; l < 4; l++) { // l = each dirwire in a group/quart + rc = add_logicin_switch(model, y, x, dirwire_g4[k*4+l], k > 2 ? i-1 : i, logicin_wire); + if (rc) FAIL(rc); + } + } + } + } return 0; -xout: +fail: return rc; } @@ -1695,17 +1696,15 @@ static int init_routing_tile(struct fpga_model* model, int y, int x) if (rc) FAIL(rc); // VCC - { int vcc_dest[] = { - X_A3, X_A4, X_A5, X_A6, X_B3, X_B4, X_B5, X_B6, - X_C3, X_C4, X_C5, X_C6, X_D3, X_D4, X_D5, X_D6, - M_A3, M_A4, M_A5, M_A6, M_B3, M_B4, M_B5, M_B6, - M_C3, M_C4, M_C5, M_C6, M_D3, M_D4, M_D5, M_D6 }; - - for (i = 0; i < sizeof(vcc_dest)/sizeof(vcc_dest[0]); i++) { + for (i = 0; i < sizeof(logicin_g4)/sizeof(logicin_g4[0])/2; i++) { + // VCC goes to the first 2 wires of even groups, and + // last 2 wires of odd groups. In the array, it goes to: + // 0 1 .. 6 7 8 9 .. 14 15 16 17 .. rc = add_switch(model, y, x, "VCC_WIRE", - logicin_s(vcc_dest[i], routing_io), 0 /* bidir */); + logicin_s(logicin_g4[i + ((i+2)/4)*4], + routing_io), 0 /* bidir */); if (rc) FAIL(rc); - }} + } // KEEP1 for (i = X_A1; i <= M_WE; i++) {