From 56d9220064dc91a51df95aa0c9253a99753b8f2a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 10 Dec 2024 14:43:20 +0100 Subject: [PATCH] Tile tile detection more robust --- gatemate/die.py | 363 ++++++++++++++++++++---------------------------- 1 file changed, 150 insertions(+), 213 deletions(-) diff --git a/gatemate/die.py b/gatemate/die.py index 02452e5..46e49a1 100644 --- a/gatemate/die.py +++ b/gatemate/die.py @@ -31,7 +31,7 @@ def get_sb_type(x,y): return "SB_BIG" if is_sb_big(x,y) else "SB_SML" def is_cpe(x,y): - return not(x<=0 or x>=160 or y<=0 or y>=120) + return x>=1 and x<=160 and y>=1 and y<=128 def is_outmux(x,y): return is_cpe(x,y) and (x+1) % 2 == (y+1) % 2 @@ -76,86 +76,77 @@ def is_gpio(x,y): return y % 2==1 return False -def get_tile_type_list(): - return [ "CPE_BIG", "CPE_SML", "CPE", - "SB_BIG", "SB_SML", - "GPIO_T", "EDGE_IO_T", "EDGE_T", - "GPIO_B", "EDGE_IO_B", "EDGE_B", - "GPIO_L", "EDGE_IO_L", "EDGE_L", - "GPIO_R", "EDGE_IO_R", "EDGE_R", - "NONE" ] - class PinType(Enum): INPUT = 0 OUTPUT = 1 INOUT = 2 - -CPE_PINS = { - "RAM_I1" : PinType.INPUT, - "RAM_I2" : PinType.INPUT, - "IN1" : PinType.INPUT, - "IN2" : PinType.INPUT, - "IN3" : PinType.INPUT, - "IN4" : PinType.INPUT, - "IN5" : PinType.INPUT, - "IN6" : PinType.INPUT, - "IN7" : PinType.INPUT, - "IN8" : PinType.INPUT, - "CLK" : PinType.INPUT, - "EN" : PinType.INPUT, - "SR" : PinType.INPUT, - "CINX" : PinType.INPUT, - "PINX" : PinType.INPUT, - "CINY1" : PinType.INPUT, - "PINY1" : PinType.INPUT, - "CINY2" : PinType.INPUT, - "PINY2" : PinType.INPUT, - "OUT1" : PinType.OUTPUT, - "OUT2" : PinType.OUTPUT, - "RAM_O1" : PinType.OUTPUT, - "RAM_O2" : PinType.OUTPUT, - "COUTX" : PinType.OUTPUT, - "POUTX" : PinType.OUTPUT, - "COUTY1" : PinType.OUTPUT, - "POUTY1" : PinType.OUTPUT, - "COUTY2" : PinType.OUTPUT, - "POUTY2" : PinType.OUTPUT -} - -GPIO_PINS = { - "IN1" : PinType.OUTPUT, - "IN2" : PinType.OUTPUT, - "OUT1" : PinType.INPUT, - "OUT2" : PinType.INPUT, - "OUT3" : PinType.INPUT, - "OUT4" : PinType.INPUT, - "DDR" : PinType.INPUT, - "RESET" : PinType.INPUT, - "CLOCK1" : PinType.INPUT, - "CLOCK2" : PinType.INPUT, - "CLOCK3" : PinType.INPUT, - "CLOCK4" : PinType.INPUT, +PRIMITIVES_PINS = { + "CPE": { + "RAM_I1" : [ PinType.INPUT, "CPE_WIRE_L" ], + "RAM_I2" : [ PinType.INPUT, "CPE_WIRE_L" ], + "IN1" : [ PinType.INPUT, "CPE_WIRE_L" ], + "IN2" : [ PinType.INPUT, "CPE_WIRE_L" ], + "IN3" : [ PinType.INPUT, "CPE_WIRE_L" ], + "IN4" : [ PinType.INPUT, "CPE_WIRE_L" ], + "IN5" : [ PinType.INPUT, "CPE_WIRE_L" ], + "IN6" : [ PinType.INPUT, "CPE_WIRE_L" ], + "IN7" : [ PinType.INPUT, "CPE_WIRE_L" ], + "IN8" : [ PinType.INPUT, "CPE_WIRE_L" ], + "CLK" : [ PinType.INPUT, "CPE_WIRE_L" ], + "EN" : [ PinType.INPUT, "CPE_WIRE_L" ], + "SR" : [ PinType.INPUT, "CPE_WIRE_L" ], + "CINX" : [ PinType.INPUT, "CPE_WIRE_L" ], + "PINX" : [ PinType.INPUT, "CPE_WIRE_L" ], + "CINY1" : [ PinType.INPUT, "CPE_WIRE_B" ], + "PINY1" : [ PinType.INPUT, "CPE_WIRE_B" ], + "CINY2" : [ PinType.INPUT, "CPE_WIRE_B" ], + "PINY2" : [ PinType.INPUT, "CPE_WIRE_B" ], + "OUT1" : [ PinType.OUTPUT, "CPE_WIRE_B" ], + "OUT2" : [ PinType.OUTPUT, "CPE_WIRE_B" ], + "RAM_O1" : [ PinType.OUTPUT, "CPE_WIRE_B" ], + "RAM_O2" : [ PinType.OUTPUT, "CPE_WIRE_B" ], + "COUTX" : [ PinType.OUTPUT, "CPE_WIRE_B" ], + "POUTX" : [ PinType.OUTPUT, "CPE_WIRE_B" ], + "COUTY1" : [ PinType.OUTPUT, "CPE_WIRE_T" ], + "POUTY1" : [ PinType.OUTPUT, "CPE_WIRE_T" ], + "COUTY2" : [ PinType.OUTPUT, "CPE_WIRE_T" ], + "POUTY2" : [ PinType.OUTPUT, "CPE_WIRE_T" ], + }, + "GPIO" : { + "IN1" : [ PinType.OUTPUT, "GPIO_WIRE" ], + "IN2" : [ PinType.OUTPUT, "GPIO_WIRE" ], + "OUT1" : [ PinType.INPUT, "GPIO_WIRE" ], + "OUT2" : [ PinType.INPUT, "GPIO_WIRE" ], + "OUT3" : [ PinType.INPUT, "GPIO_WIRE" ], + "OUT4" : [ PinType.INPUT, "GPIO_WIRE" ], + "DDR" : [ PinType.INPUT, "GPIO_WIRE" ], + "RESET" : [ PinType.INPUT, "GPIO_WIRE" ], + "CLOCK1" : [ PinType.INPUT, "GPIO_WIRE" ], + "CLOCK2" : [ PinType.INPUT, "GPIO_WIRE" ], + "CLOCK3" : [ PinType.INPUT, "GPIO_WIRE" ], + "CLOCK4" : [ PinType.INPUT, "GPIO_WIRE" ], + } } def get_groups_for_type(type): groups = [] def create_group(name, type): groups.append({"name":name, "type":type}) - if type.startswith("CPE"): + if "CPE" in type: # CPE - for p in range(12): - create_group(f"INMUX_P{p+1:02d}", "INMUX") - if "_" in type and p>7: # OUTMUX only on CPE_BIG and CPE_SML - create_group(f"OUTMUX_P{p+1:02d}", "OUTMUX") - if "BIG" in type: + for p in range(1,13): + create_group(f"INMUX_P{p:02d}", "INMUX") + if "OUTMUX" in type and p>=9: + create_group(f"OUTMUX_P{p:02d}", "OUTMUX") + if "SB_BIG" in type: # SB_BIG - for p in range(12): - create_group(f"SB_BIG_P{p+1:02d}", "SB_BIG") - if "SML" in type: + for p in range(1,13): + create_group(f"SB_BIG_P{p:02d}", "SB_BIG") + if "SB_SML" in type: # SB_SML - for p in range(12): - create_group(f"SB_SML_P{p+1:02d}", "SB_SML") + for p in range(1,13): + create_group(f"SB_SML_P{p:02d}", "SB_SML") #if "GPIO" in type: # # GPIO #if "EDGE_IO" in type: @@ -163,84 +154,50 @@ def get_groups_for_type(type): return groups def get_bels_for_type(type): - if type.startswith("CPE"): - return [{"name":"CPE", "type":"CPE", "z":0}] + bels = [] + if "CPE" in type: + bels.append({"name":"CPE", "type":"CPE", "z":0}) if "GPIO" in type: - return [{"name":"GPIO", "type":"GPIO", "z":0}] - return [] + bels.append({"name":"GPIO", "type":"GPIO", "z":0}) + return bels def get_bel_pins(bel): - if bel == "CPE": - return CPE_PINS.items() - elif bel == "GPIO": - return GPIO_PINS.items() - return [] - + return PRIMITIVES_PINS[bel].items() def get_endpoints_for_type(type): wires = [] def create_wire(name, type): wires.append({"name":name, "type":type}) - if type.startswith("CPE"): + + for bel in get_bels_for_type(type): + for k,v in get_bel_pins(bel["type"]): + create_wire(f"{bel["name"]}.{k}", type=f"{v[1]}") + + if "CPE" in type: # CPE - create_wire("CPE.IN1", type="CPE_WIRE_L") - create_wire("CPE.IN2", type="CPE_WIRE_L") - create_wire("CPE.IN3", type="CPE_WIRE_L") - create_wire("CPE.IN4", type="CPE_WIRE_L") - create_wire("CPE.IN5", type="CPE_WIRE_L") - create_wire("CPE.IN6", type="CPE_WIRE_L") - create_wire("CPE.IN7", type="CPE_WIRE_L") - create_wire("CPE.IN8", type="CPE_WIRE_L") - create_wire("CPE.CLK", type="CPE_WIRE_L") - create_wire("CPE.EN", type="CPE_WIRE_L") - create_wire("CPE.SR", type="CPE_WIRE_L") - - create_wire("CPE.RAM_I2", type="CPE_WIRE_L") - create_wire("CPE.RAM_I1", type="CPE_WIRE_L") - create_wire("CPE.CINX", type="CPE_WIRE_L") - create_wire("CPE.PINX", type="CPE_WIRE_L") - - create_wire("CPE.CINY1", type="CPE_WIRE_B") - create_wire("CPE.PINY1", type="CPE_WIRE_B") - create_wire("CPE.CINY2", type="CPE_WIRE_B") - create_wire("CPE.PINY2", type="CPE_WIRE_B") - - create_wire("CPE.OUT2", type="CPE_WIRE_R") - create_wire("CPE.OUT1", type="CPE_WIRE_R") - - create_wire("CPE.RAM_O2", type="CPE_WIRE_R") - create_wire("CPE.RAM_O1", type="CPE_WIRE_R") - create_wire("CPE.COUTX", type="CPE_WIRE_R") - create_wire("CPE.POUTX", type="CPE_WIRE_R") - - create_wire("CPE.COUTY1", type="CPE_WIRE_T") - create_wire("CPE.POUTY1", type="CPE_WIRE_T") - create_wire("CPE.COUTY2", type="CPE_WIRE_T") - create_wire("CPE.POUTY2", type="CPE_WIRE_T") - - for p in range(12): - plane = f"{p+1:02d}" + for p in range(1,13): + plane = f"{p:02d}" for i in range(8): create_wire(f"INMUX.P{plane}.D{i}", type="INMUX_WIRE") create_wire(f"INMUX.P{plane}.Y", type="INMUX_WIRE") - if "_" in type and p>7: # OUTMUX only on CPE_BIG and CPE_SML + if "OUTMUX" in type and p>=9: for i in range(4): create_wire(f"OUTMUX.P{plane}.D{i}", type="OUTMUX_WIRE") create_wire(f"OUTMUX.P{plane}.Y", type="OUTMUX_WIRE") - if "BIG" in type: + if "SB_BIG" in type: # SB_BIG - for p in range(12): - plane = f"{p+1:02d}" + for p in range(1,13): + plane = f"{p:02d}" create_wire(f"SB_BIG.P{plane}.D0", type="SB_BIG_WIRE") - for i in range(4): - create_wire(f"SB_BIG.P{plane}.D2_{i+1}", type="SB_BIG_WIRE") - create_wire(f"SB_BIG.P{plane}.D3_{i+1}", type="SB_BIG_WIRE") - create_wire(f"SB_BIG.P{plane}.D4_{i+1}", type="SB_BIG_WIRE") - create_wire(f"SB_BIG.P{plane}.D5_{i+1}", type="SB_BIG_WIRE") - create_wire(f"SB_BIG.P{plane}.D6_{i+1}", type="SB_BIG_WIRE") - create_wire(f"SB_BIG.P{plane}.D7_{i+1}", type="SB_BIG_WIRE") - create_wire(f"SB_BIG.P{plane}.Y{i+1}", type="SB_BIG_WIRE") + for i in range(1,5): + create_wire(f"SB_BIG.P{plane}.D2_{i}", type="SB_BIG_WIRE") + create_wire(f"SB_BIG.P{plane}.D3_{i}", type="SB_BIG_WIRE") + create_wire(f"SB_BIG.P{plane}.D4_{i}", type="SB_BIG_WIRE") + create_wire(f"SB_BIG.P{plane}.D5_{i}", type="SB_BIG_WIRE") + create_wire(f"SB_BIG.P{plane}.D6_{i}", type="SB_BIG_WIRE") + create_wire(f"SB_BIG.P{plane}.D7_{i}", type="SB_BIG_WIRE") + create_wire(f"SB_BIG.P{plane}.Y{i}", type="SB_BIG_WIRE") create_wire(f"SB_BIG.P{plane}.YDIAG", type="SB_BIG_WIRE") create_wire(f"SB_BIG.P{plane}.X34", type="SB_BIG_WIRE") @@ -248,36 +205,23 @@ def get_endpoints_for_type(type): create_wire(f"SB_BIG.P{plane}.X12", type="SB_BIG_WIRE") create_wire(f"SB_BIG.P{plane}.X23", type="SB_BIG_WIRE") - if "SML" in type: + if "SB_SML" in type: # SB_SML - for p in range(12): - plane = f"{p+1:02d}" + for p in range(1,13): + plane = f"{p:02d}" create_wire(f"SB_SML.P{plane}.D0", type="SB_SML_WIRE") - for i in range(4): - create_wire(f"SB_SML.P{plane}.D2_{i+1}", type="SB_SML_WIRE") - create_wire(f"SB_SML.P{plane}.D3_{i+1}", type="SB_SML_WIRE") - create_wire(f"SB_SML.P{plane}.Y{i+1}", type="SB_SML_WIRE") + for i in range(1,5): + create_wire(f"SB_SML.P{plane}.D2_{i}", type="SB_SML_WIRE") + create_wire(f"SB_SML.P{plane}.D3_{i}", type="SB_SML_WIRE") + create_wire(f"SB_SML.P{plane}.Y{i}", type="SB_SML_WIRE") create_wire(f"SB_SML.P{plane}.YDIAG", type="SB_SML_WIRE") create_wire(f"SB_SML.P{plane}.X34", type="SB_SML_WIRE") create_wire(f"SB_SML.P{plane}.X14", type="SB_SML_WIRE") create_wire(f"SB_SML.P{plane}.X12", type="SB_SML_WIRE") create_wire(f"SB_SML.P{plane}.X23", type="SB_SML_WIRE") - if "GPIO" in type: + #if "GPIO" in type: # GPIO - create_wire("GPIO.IN1", type="GPIO_WIRE") - create_wire("GPIO.IN2", type="GPIO_WIRE") - create_wire("GPIO.OUT1", type="GPIO_WIRE") - create_wire("GPIO.OUT2", type="GPIO_WIRE") - create_wire("GPIO.OUT3", type="GPIO_WIRE") - create_wire("GPIO.OUT4", type="GPIO_WIRE") - create_wire("GPIO.DDR", type="GPIO_WIRE") - create_wire("GPIO.RESET", type="GPIO_WIRE") - create_wire("GPIO.CLOCK1", type="GPIO_WIRE") - create_wire("GPIO.CLOCK2", type="GPIO_WIRE") - create_wire("GPIO.CLOCK3", type="GPIO_WIRE") - create_wire("GPIO.CLOCK4", type="GPIO_WIRE") - #if "EDGE_IO" in type: # # EDGE_IO return wires @@ -288,30 +232,30 @@ def get_mux_connections_for_type(type): mux = dst.replace(".","_") + "_MUX" muxes.append({"src":src, "dst":dst, "mux":mux, "bits":bits, "value": value}) - if type.startswith("CPE"): + if "CPE" in type: # CPE - for p in range(12): - plane = f"{p+1:02d}" + for p in range(1,13): + plane = f"{p:02d}" for i in range(8): create_mux(f"INMUX.P{plane}.D{i}", f"INMUX.P{plane}.Y", 3, i) - if "_" in type and p>7: # OUTMUX only on CPE_BIG and CPE_SML + if "OUTMUX" in type and p>=9: for i in range(4): create_mux(f"OUTMUX.P{plane}.D{i}", f"OUTMUX.P{plane}.Y", 2, i) - if "BIG" in type: + if "SB_BIG" in type: # SB_BIG - for p in range(12): - plane = f"{p+1:02d}" + for p in range(1,13): + plane = f"{p:02d}" # Per Y output mux - for i in range(4): - create_mux(f"SB_BIG.P{plane}.D0", f"SB_BIG.P{plane}.Y{i+1}", 3, 0) - create_mux(f"SB_BIG.P{plane}.YDIAG", f"SB_BIG.P{plane}.Y{i+1}", 3, 1) - create_mux(f"SB_BIG.P{plane}.D2_{i+1}", f"SB_BIG.P{plane}.Y{i+1}", 3, 2) - create_mux(f"SB_BIG.P{plane}.D3_{i+1}", f"SB_BIG.P{plane}.Y{i+1}", 3, 3) - create_mux(f"SB_BIG.P{plane}.D4_{i+1}", f"SB_BIG.P{plane}.Y{i+1}", 3, 4) - create_mux(f"SB_BIG.P{plane}.D5_{i+1}", f"SB_BIG.P{plane}.Y{i+1}", 3, 5) - create_mux(f"SB_BIG.P{plane}.D6_{i+1}", f"SB_BIG.P{plane}.Y{i+1}", 3, 6) - create_mux(f"SB_BIG.P{plane}.D7_{i+1}", f"SB_BIG.P{plane}.Y{i+1}", 3, 7) + for i in range(1,5): + create_mux(f"SB_BIG.P{plane}.D0", f"SB_BIG.P{plane}.Y{i}", 3, 0) + create_mux(f"SB_BIG.P{plane}.YDIAG", f"SB_BIG.P{plane}.Y{i}", 3, 1) + create_mux(f"SB_BIG.P{plane}.D2_{i}", f"SB_BIG.P{plane}.Y{i}", 3, 2) + create_mux(f"SB_BIG.P{plane}.D3_{i}", f"SB_BIG.P{plane}.Y{i}", 3, 3) + create_mux(f"SB_BIG.P{plane}.D4_{i}", f"SB_BIG.P{plane}.Y{i}", 3, 4) + create_mux(f"SB_BIG.P{plane}.D5_{i}", f"SB_BIG.P{plane}.Y{i}", 3, 5) + create_mux(f"SB_BIG.P{plane}.D6_{i}", f"SB_BIG.P{plane}.Y{i}", 3, 6) + create_mux(f"SB_BIG.P{plane}.D7_{i}", f"SB_BIG.P{plane}.Y{i}", 3, 7) # YDIAG output mux create_mux(f"SB_BIG.P{plane}.Y1", f"SB_BIG.P{plane}.YDIAG", 3, 0) @@ -322,16 +266,16 @@ def get_mux_connections_for_type(type): create_mux(f"SB_BIG.P{plane}.X14", f"SB_BIG.P{plane}.YDIAG", 3, 5) create_mux(f"SB_BIG.P{plane}.X12", f"SB_BIG.P{plane}.YDIAG", 3, 6) create_mux(f"SB_BIG.P{plane}.X23", f"SB_BIG.P{plane}.YDIAG", 3, 7) - if "SML" in type: + if "SB_SML" in type: # SB_SML - for p in range(12): - plane = f"{p+1:02d}" + for p in range(1,13): + plane = f"{p:02d}" # Per Y output mux - for i in range(4): - create_mux(f"SB_SML.P{plane}.D0", f"SB_SML.P{plane}.Y{i+1}", 2, 0) - create_mux(f"SB_SML.P{plane}.YDIAG", f"SB_SML.P{plane}.Y{i+1}", 2, 1) - create_mux(f"SB_SML.P{plane}.D2_{i+1}", f"SB_SML.P{plane}.Y{i+1}", 2, 2) - create_mux(f"SB_SML.P{plane}.D3_{i+1}", f"SB_SML.P{plane}.Y{i+1}", 2, 3) + for i in range(1,5): + create_mux(f"SB_SML.P{plane}.D0", f"SB_SML.P{plane}.Y{i}", 2, 0) + create_mux(f"SB_SML.P{plane}.YDIAG", f"SB_SML.P{plane}.Y{i}", 2, 1) + create_mux(f"SB_SML.P{plane}.D2_{i}", f"SB_SML.P{plane}.Y{i}", 2, 2) + create_mux(f"SB_SML.P{plane}.D3_{i}", f"SB_SML.P{plane}.Y{i}", 2, 3) # YDIAG output mux create_mux(f"SB_SML.P{plane}.Y1", f"SB_SML.P{plane}.YDIAG", 3, 0) @@ -350,47 +294,40 @@ def get_mux_connections_for_type(type): return muxes def get_tile_type(x,y): - if is_cpe(x,y): # core section - if is_sb_big(x,y): - return "CPE_BIG" # CPE + SB_BIG + INMUX + OUTMUX - elif is_sb_sml(x,y): - return "CPE_SML" # CPE + SB_SML + INMUX + OUTMUX - else: - return "CPE" # CPE + INMUX - elif is_sb_big(x,y): - return "SB_BIG" # SB_BIG - elif is_sb_sml(x,y): - return "SB_SML" # SB_SML - elif is_edge_top(x,y): - if is_gpio(x,y): - return "GPIO_T" # GPIO + EDGE_IO + EDGE_T - elif is_edge_io(x,y): - return "EDGE_IO_T" # EDGE_IO + EDGE_T - else: - return "EDGE_T" # EDGE_T - elif is_edge_bottom(x,y): - if is_gpio(x,y): - return "GPIO_B" # GPIO + EDGE_IO + EDGE_B - elif is_edge_io(x,y): - return "EDGE_IO_B" # EDGE_IO + EDGE_B - else: - return "EDGE_B" # EDGE_B - elif is_edge_left(x,y): - if is_gpio(x,y): - return "GPIO_L" # GPIO + EDGE_IO + EDGE_L - elif is_edge_io(x,y): - return "EDGE_IO_L" # EDGE_IO + EDGE_L - else: - return "EDGE_L" # EDGE_L - elif is_edge_right(x,y): - if is_gpio(x,y): - return "GPIO_R" # GPIO + EDGE_IO + EDGE_R - elif is_edge_io(x,y): - return "EDGE_IO_R" # EDGE_IO + EDGE_R - else: - return "EDGE_R" # EDGE_R - else: - return "NONE" + val = list() + if is_cpe(x,y): + val.append("CPE") + if is_outmux(x,y): + val.append("OUTMUX") + + if is_sb_big(x,y): + val.append("SB_BIG") + if is_sb_sml(x,y): + val.append("SB_SML") + if is_gpio(x,y): + val.append("GPIO") + if is_edge_io(x,y): + val.append("EDGE_IO") + if is_edge_top(x,y): + val.append("TOP") + if is_edge_bottom(x,y): + val.append("BOTTOM") + if is_edge_left(x,y): + val.append("LEFT") + if is_edge_right(x,y): + val.append("RIGHT") + + if not val: + val.append("NONE") + return "_".join(val) + +def get_tile_type_list(): + tt = set() + for y in range(-2, max_row()+1): + for x in range(-2, max_col()+1): + tt.add(get_tile_type(x,y)) + + return tt conn = dict() debug_conn = False