prjpeppercorn/gatemate/die.py

517 lines
18 KiB
Python
Raw Normal View History

2024-12-10 15:45:11 +01:00
#
# prjpeppercorn -- GateMate FPGAs Bitstream Documentation and Tools
#
# Copyright (C) 2024 The Project Peppercorn Authors.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
2024-12-09 18:41:42 +01:00
from enum import Enum
2024-12-10 15:45:11 +01:00
from dataclasses import dataclass
2024-12-09 18:41:42 +01:00
2024-12-09 10:57:04 +01:00
def max_row():
return 131
def max_col():
return 163
2024-12-10 13:45:12 +01:00
def is_sb(x,y):
if (x>=-1 and x<=162 and y>=-1 and y<=130):
return (x+1) % 2 == (y+1) % 2
return False
2024-12-09 10:57:04 +01:00
def is_sb_big(x,y):
if (x>=-1 and x<=162 and y>=-1 and y<=130):
if (x+1) % 2 == 1 and (y+1) % 2 == 1:
return False if (x+1) % 4 == (y+1) % 4 else True
if (x+1) % 2 == 0 and (y+1) % 2 == 0:
return False if (x+1) % 4 != (y+1) % 4 else True
return False
def is_sb_sml(x,y):
if (x>=-1 and x<=162 and y>=-1 and y<=130):
if (x+1) % 2 == 1 and (y+1) % 2 == 1:
return True if (x+1) % 4 == (y+1) % 4 else False
if (x+1) % 2 == 0 and (y+1) % 2 == 0:
return True if (x+1) % 4 != (y+1) % 4 else False
return False
2024-12-10 13:45:12 +01:00
def get_sb_type(x,y):
return "SB_BIG" if is_sb_big(x,y) else "SB_SML"
2024-12-09 10:57:04 +01:00
def is_cpe(x,y):
2024-12-10 14:43:20 +01:00
return x>=1 and x<=160 and y>=1 and y<=128
2024-12-09 10:57:04 +01:00
def is_outmux(x,y):
return is_cpe(x,y) and (x+1) % 2 == (y+1) % 2
def is_edge_left(x,y):
return x==-2 and y>=1 and y<=130
def is_edge_right(x,y):
return x==max_col() and y>=1 and y<=128
def is_edge_bottom(x,y):
return y==-2 and x>=-1 and x<=162
def is_edge_top(x,y):
return y==max_row() and x>=1 and x<=162
def is_edge_io(x,y):
2024-12-11 15:22:35 +01:00
if (y==-2 and x>=5 and x<=40): # IO Bank S3/WA
2024-12-09 10:57:04 +01:00
return True
2024-12-11 15:22:35 +01:00
if (y==-2 and x>=57 and x<=92): # IO Bank S1/WB
2024-12-09 10:57:04 +01:00
return True
2024-12-11 15:22:35 +01:00
if (y==-2 and x>=101 and x<=136): # IO Bank S2/WC
2024-12-09 10:57:04 +01:00
return True
2024-12-11 15:22:35 +01:00
if (x==-2 and y>=25 and y<=60): # IO Bank W1/SA
2024-12-09 10:57:04 +01:00
return True
2024-12-11 15:22:35 +01:00
if (x==-2 and y>=69 and y<=104): # IO Bank W2/SB
2024-12-09 10:57:04 +01:00
return True
2024-12-11 15:22:35 +01:00
if (x==max_col() and y>=25 and y<=60): # IO Bank E1/NA
2024-12-09 10:57:04 +01:00
return True
2024-12-11 15:22:35 +01:00
if (x==max_col() and y>=69 and y<=104): # IO Bank E2/NB
2024-12-09 10:57:04 +01:00
return True
2024-12-11 15:22:35 +01:00
if (y==max_row() and x>=57 and x<=92): # IO Bank N1/EA
2024-12-09 10:57:04 +01:00
return True
2024-12-11 15:22:35 +01:00
if (y==max_row() and x>=101 and x<=136): # IO Bank N2/EB
2024-12-09 10:57:04 +01:00
return True
def is_gpio(x,y):
if is_edge_io(x,y):
if (y==-2 or y==max_row()):
return x % 2==1
if (x==-2 or x==max_col()):
return y % 2==1
return False
2024-12-09 18:41:42 +01:00
class PinType(Enum):
INPUT = 0
OUTPUT = 1
INOUT = 2
2024-12-10 15:45:11 +01:00
@dataclass
class Primitive:
name : str
type : str
z : int
@dataclass
class Pin:
name : str
dir : PinType
wire_type : str
@dataclass
class Group:
name : str
type : str
@dataclass
class Endpoint:
name : str
type : str
@dataclass
class MUX:
src : str
dst : str
name : str
bits : int
value : int
2024-12-11 15:22:35 +01:00
invert: bool
2024-12-10 15:45:11 +01:00
@dataclass
class Connection:
x : int
y : int
name : str
2024-12-10 14:43:20 +01:00
PRIMITIVES_PINS = {
2024-12-10 15:45:11 +01:00
"CPE": [
Pin("RAM_I1" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("RAM_I2" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("IN1" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("IN2" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("IN3" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("IN4" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("IN5" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("IN6" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("IN7" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("IN8" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("CLK" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("EN" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("SR" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("CINX" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("PINX" ,PinType.INPUT, "CPE_WIRE_L"),
Pin("CINY1" ,PinType.INPUT, "CPE_WIRE_B"),
Pin("PINY1" ,PinType.INPUT, "CPE_WIRE_B"),
Pin("CINY2" ,PinType.INPUT, "CPE_WIRE_B"),
Pin("PINY2" ,PinType.INPUT, "CPE_WIRE_B"),
Pin("OUT1" ,PinType.OUTPUT, "CPE_WIRE_B"),
Pin("OUT2" ,PinType.OUTPUT, "CPE_WIRE_B"),
Pin("RAM_O1" ,PinType.OUTPUT, "CPE_WIRE_B"),
Pin("RAM_O2" ,PinType.OUTPUT, "CPE_WIRE_B"),
Pin("COUTX" ,PinType.OUTPUT, "CPE_WIRE_B"),
Pin("POUTX" ,PinType.OUTPUT, "CPE_WIRE_B"),
Pin("COUTY1" ,PinType.OUTPUT, "CPE_WIRE_T"),
Pin("POUTY1" ,PinType.OUTPUT, "CPE_WIRE_T"),
Pin("COUTY2" ,PinType.OUTPUT, "CPE_WIRE_T"),
Pin("POUTY2" ,PinType.OUTPUT, "CPE_WIRE_T"),
],
"GPIO" : [
Pin("IN1" , PinType.OUTPUT,"GPIO_WIRE"),
Pin("IN2" , PinType.OUTPUT,"GPIO_WIRE"),
Pin("OUT1" , PinType.INPUT, "GPIO_WIRE"),
Pin("OUT2" , PinType.INPUT, "GPIO_WIRE"),
Pin("OUT3" , PinType.INPUT, "GPIO_WIRE"),
Pin("OUT4" , PinType.INPUT, "GPIO_WIRE"),
Pin("DDR" , PinType.INPUT, "GPIO_WIRE"),
Pin("RESET" , PinType.INPUT, "GPIO_WIRE"),
Pin("CLOCK1", PinType.INPUT, "GPIO_WIRE"),
Pin("CLOCK2", PinType.INPUT, "GPIO_WIRE"),
Pin("CLOCK3", PinType.INPUT, "GPIO_WIRE"),
Pin("CLOCK4", PinType.INPUT, "GPIO_WIRE"),
]
2024-12-10 09:18:45 +01:00
}
2024-12-09 18:41:42 +01:00
def get_groups_for_type(type):
groups = []
def create_group(name, type):
2024-12-10 15:45:11 +01:00
groups.append(Group(name,type))
2024-12-10 14:43:20 +01:00
if "CPE" in type:
2024-12-09 18:41:42 +01:00
# CPE
2024-12-10 14:43:20 +01:00
for p in range(1,13):
2024-12-11 15:22:35 +01:00
create_group(f"IM_P{p:02d}", "IM")
if "OM" in type and p>=9:
create_group(f"OM_P{p:02d}", "OM")
2024-12-10 14:43:20 +01:00
if "SB_BIG" in type:
2024-12-09 18:41:42 +01:00
# SB_BIG
2024-12-10 14:43:20 +01:00
for p in range(1,13):
create_group(f"SB_BIG_P{p:02d}", "SB_BIG")
if "SB_SML" in type:
2024-12-09 18:41:42 +01:00
# SB_SML
2024-12-10 14:43:20 +01:00
for p in range(1,13):
create_group(f"SB_SML_P{p:02d}", "SB_SML")
2024-12-09 18:41:42 +01:00
#if "GPIO" in type:
# # GPIO
2024-12-11 15:22:35 +01:00
#if "IOES" in type:
# # IOES
2024-12-09 18:41:42 +01:00
return groups
2024-12-10 15:45:11 +01:00
def get_primitives_for_type(type):
primitives = []
2024-12-10 14:43:20 +01:00
if "CPE" in type:
2024-12-10 15:45:11 +01:00
primitives.append(Primitive("CPE","CPE",0))
2024-12-10 09:18:45 +01:00
if "GPIO" in type:
2024-12-10 15:45:11 +01:00
primitives.append(Primitive("GPIO","GPIO",0))
return primitives
2024-12-09 18:41:42 +01:00
2024-12-10 15:45:11 +01:00
def get_primitive_pins(bel):
return PRIMITIVES_PINS[bel]
2024-12-09 18:41:42 +01:00
def get_endpoints_for_type(type):
wires = []
def create_wire(name, type):
2024-12-10 15:45:11 +01:00
wires.append(Endpoint(name,type))
2024-12-10 14:43:20 +01:00
2024-12-10 15:45:11 +01:00
for prim in get_primitives_for_type(type):
for pin in get_primitive_pins(prim.type):
create_wire(f"{prim.name}.{pin.name}", type=f"{pin.wire_type}")
2024-12-10 14:43:20 +01:00
if "CPE" in type:
2024-12-09 18:41:42 +01:00
# CPE
2024-12-10 14:43:20 +01:00
for p in range(1,13):
plane = f"{p:02d}"
2024-12-09 18:41:42 +01:00
for i in range(8):
2024-12-11 15:22:35 +01:00
create_wire(f"IM.P{plane}.D{i}", type="IM_WIRE")
create_wire(f"IM.P{plane}.Y", type="IM_WIRE")
if "OM" in type and p>=9:
2024-12-09 18:41:42 +01:00
for i in range(4):
2024-12-11 15:22:35 +01:00
create_wire(f"OM.P{plane}.D{i}", type="OM_WIRE")
create_wire(f"OM.P{plane}.Y", type="OM_WIRE")
2024-12-09 18:41:42 +01:00
2024-12-10 14:43:20 +01:00
if "SB_BIG" in type:
2024-12-09 18:41:42 +01:00
# SB_BIG
2024-12-10 14:43:20 +01:00
for p in range(1,13):
plane = f"{p:02d}"
2024-12-09 18:41:42 +01:00
create_wire(f"SB_BIG.P{plane}.D0", type="SB_BIG_WIRE")
2024-12-10 14:43:20 +01:00
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")
2024-12-09 18:41:42 +01:00
create_wire(f"SB_BIG.P{plane}.YDIAG", type="SB_BIG_WIRE")
create_wire(f"SB_BIG.P{plane}.X34", type="SB_BIG_WIRE")
create_wire(f"SB_BIG.P{plane}.X14", type="SB_BIG_WIRE")
create_wire(f"SB_BIG.P{plane}.X12", type="SB_BIG_WIRE")
create_wire(f"SB_BIG.P{plane}.X23", type="SB_BIG_WIRE")
2024-12-10 14:43:20 +01:00
if "SB_SML" in type:
2024-12-09 18:41:42 +01:00
# SB_SML
2024-12-10 14:43:20 +01:00
for p in range(1,13):
plane = f"{p:02d}"
2024-12-09 18:41:42 +01:00
create_wire(f"SB_SML.P{plane}.D0", type="SB_SML_WIRE")
2024-12-10 14:43:20 +01:00
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")
2024-12-09 18:41:42 +01:00
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")
2024-12-10 14:43:20 +01:00
#if "GPIO" in type:
2024-12-10 09:18:45 +01:00
# GPIO
2024-12-11 15:22:35 +01:00
#if "IOES" in type:
# # IOES
2024-12-09 18:41:42 +01:00
return wires
def get_mux_connections_for_type(type):
muxes = []
2024-12-11 15:22:35 +01:00
def create_mux(src, dst, bits, value, invert):
2024-12-10 15:45:11 +01:00
name = dst.replace(".","_") + "_MUX"
2024-12-11 15:22:35 +01:00
muxes.append(MUX(src, dst, name, bits, value, invert))
2024-12-09 18:41:42 +01:00
2024-12-10 14:43:20 +01:00
if "CPE" in type:
2024-12-09 18:41:42 +01:00
# CPE
2024-12-10 14:43:20 +01:00
for p in range(1,13):
plane = f"{p:02d}"
2024-12-09 18:41:42 +01:00
for i in range(8):
2024-12-11 15:22:35 +01:00
create_mux(f"IM.P{plane}.D{i}", f"IM.P{plane}.Y", 3, i, True)
if "OM" in type and p>=9:
2024-12-09 18:41:42 +01:00
for i in range(4):
2024-12-11 15:22:35 +01:00
create_mux(f"OM.P{plane}.D{i}", f"OM.P{plane}.Y", 2, i, True)
2024-12-09 18:41:42 +01:00
2024-12-10 14:43:20 +01:00
if "SB_BIG" in type:
2024-12-09 18:41:42 +01:00
# SB_BIG
2024-12-10 14:43:20 +01:00
for p in range(1,13):
plane = f"{p:02d}"
2024-12-09 18:41:42 +01:00
# Per Y output mux
2024-12-10 14:43:20 +01:00
for i in range(1,5):
2024-12-11 15:22:35 +01:00
create_mux(f"SB_BIG.P{plane}.D0", f"SB_BIG.P{plane}.Y{i}", 3, 0, True)
create_mux(f"SB_BIG.P{plane}.YDIAG", f"SB_BIG.P{plane}.Y{i}", 3, 1, True)
create_mux(f"SB_BIG.P{plane}.D2_{i}", f"SB_BIG.P{plane}.Y{i}", 3, 2, True)
create_mux(f"SB_BIG.P{plane}.D3_{i}", f"SB_BIG.P{plane}.Y{i}", 3, 3, True)
create_mux(f"SB_BIG.P{plane}.D4_{i}", f"SB_BIG.P{plane}.Y{i}", 3, 4, True)
create_mux(f"SB_BIG.P{plane}.D5_{i}", f"SB_BIG.P{plane}.Y{i}", 3, 5, True)
create_mux(f"SB_BIG.P{plane}.D6_{i}", f"SB_BIG.P{plane}.Y{i}", 3, 6, True)
create_mux(f"SB_BIG.P{plane}.D7_{i}", f"SB_BIG.P{plane}.Y{i}", 3, 7, True)
2024-12-09 18:41:42 +01:00
# YDIAG output mux
2024-12-11 15:22:35 +01:00
create_mux(f"SB_BIG.P{plane}.Y1", f"SB_BIG.P{plane}.YDIAG", 3, 0, True)
create_mux(f"SB_BIG.P{plane}.Y2", f"SB_BIG.P{plane}.YDIAG", 3, 1, True)
create_mux(f"SB_BIG.P{plane}.Y3", f"SB_BIG.P{plane}.YDIAG", 3, 2, True)
create_mux(f"SB_BIG.P{plane}.Y4", f"SB_BIG.P{plane}.YDIAG", 3, 3, True)
create_mux(f"SB_BIG.P{plane}.X34", f"SB_BIG.P{plane}.YDIAG", 3, 4, True)
create_mux(f"SB_BIG.P{plane}.X14", f"SB_BIG.P{plane}.YDIAG", 3, 5, True)
create_mux(f"SB_BIG.P{plane}.X12", f"SB_BIG.P{plane}.YDIAG", 3, 6, True)
create_mux(f"SB_BIG.P{plane}.X23", f"SB_BIG.P{plane}.YDIAG", 3, 7, True)
2024-12-10 14:43:20 +01:00
if "SB_SML" in type:
2024-12-09 18:41:42 +01:00
# SB_SML
2024-12-10 14:43:20 +01:00
for p in range(1,13):
plane = f"{p:02d}"
2024-12-09 18:41:42 +01:00
# Per Y output mux
2024-12-10 14:43:20 +01:00
for i in range(1,5):
2024-12-11 15:22:35 +01:00
create_mux(f"SB_SML.P{plane}.D0", f"SB_SML.P{plane}.Y{i}", 2, 0, True)
create_mux(f"SB_SML.P{plane}.YDIAG", f"SB_SML.P{plane}.Y{i}", 2, 1, True)
create_mux(f"SB_SML.P{plane}.D2_{i}", f"SB_SML.P{plane}.Y{i}", 2, 2, True)
create_mux(f"SB_SML.P{plane}.D3_{i}", f"SB_SML.P{plane}.Y{i}", 2, 3, True)
2024-12-09 18:41:42 +01:00
# YDIAG output mux
2024-12-11 15:22:35 +01:00
create_mux(f"SB_SML.P{plane}.Y1", f"SB_SML.P{plane}.YDIAG", 3, 0, True)
create_mux(f"SB_SML.P{plane}.Y2", f"SB_SML.P{plane}.YDIAG", 3, 1, True)
create_mux(f"SB_SML.P{plane}.Y3", f"SB_SML.P{plane}.YDIAG", 3, 2, True)
create_mux(f"SB_SML.P{plane}.Y4", f"SB_SML.P{plane}.YDIAG", 3, 3, True)
create_mux(f"SB_SML.P{plane}.X34", f"SB_SML.P{plane}.YDIAG", 3, 4, True)
create_mux(f"SB_SML.P{plane}.X14", f"SB_SML.P{plane}.YDIAG", 3, 5, True)
create_mux(f"SB_SML.P{plane}.X12", f"SB_SML.P{plane}.YDIAG", 3, 6, True)
create_mux(f"SB_SML.P{plane}.X23", f"SB_SML.P{plane}.YDIAG", 3, 7, True)
2024-12-09 18:41:42 +01:00
#if "GPIO" in type:
# # GPIO
2024-12-11 15:22:35 +01:00
#if "IOES" in type:
# # IOES
2024-12-09 18:41:42 +01:00
return muxes
2024-12-10 18:00:20 +01:00
def get_tile_types(x,y):
2024-12-10 14:43:20 +01:00
val = list()
if is_cpe(x,y):
val.append("CPE")
2024-12-11 15:22:35 +01:00
val.append("IM")
2024-12-10 14:43:20 +01:00
if is_outmux(x,y):
2024-12-11 15:22:35 +01:00
val.append("OM")
2024-12-10 14:43:20 +01:00
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):
2024-12-11 15:22:35 +01:00
val.append("IOES")
2024-12-10 14:43:20 +01:00
if is_edge_top(x,y):
2024-12-11 15:22:35 +01:00
val.append("TES")
2024-12-10 14:43:20 +01:00
if is_edge_bottom(x,y):
2024-12-11 15:22:35 +01:00
val.append("BES")
2024-12-10 14:43:20 +01:00
if is_edge_left(x,y):
2024-12-11 15:22:35 +01:00
val.append("LES")
2024-12-10 14:43:20 +01:00
if is_edge_right(x,y):
2024-12-11 15:22:35 +01:00
val.append("RES")
2024-12-10 18:00:20 +01:00
return val
2024-12-10 14:43:20 +01:00
2024-12-10 18:00:20 +01:00
def get_tile_type(x,y):
val = get_tile_types(x,y)
2024-12-10 14:43:20 +01:00
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
2024-12-09 18:41:42 +01:00
2024-12-10 13:45:12 +01:00
conn = dict()
debug_conn = False
def create_conn(src_x,src_y, src, dst_x, dst_y, dst):
key_val = f"{src_x}/{src_y}/{src}"
2024-12-10 15:45:11 +01:00
key = Connection(src_x, src_y, src)
item = Connection(dst_x, dst_y, dst)
2024-12-10 13:45:12 +01:00
if key_val not in conn:
conn[key_val] = list()
conn[key_val].append(key)
conn[key_val].append(item)
if debug_conn:
print(f"({src_x},{src_y}) {src} => ({dst_x},{dst_y}) {dst}")
def alt_plane(dir,plane):
alt = [[5, 6, 7, 8, 1, 2, 3, 4,11,12, 9,10],
[9,10,11,12, 9,10,11,12,12,11,10, 9]]
return alt[dir][plane-1]
def create_cpe(x,y):
2024-12-11 15:22:35 +01:00
create_conn(x,y,"IM.P01.Y", x,y,"CPE.IN1")
create_conn(x,y,"IM.P02.Y", x,y,"CPE.IN2")
create_conn(x,y,"IM.P03.Y", x,y,"CPE.IN3")
create_conn(x,y,"IM.P04.Y", x,y,"CPE.IN4")
create_conn(x,y,"IM.P05.Y", x,y,"CPE.IN5")
create_conn(x,y,"IM.P06.Y", x,y,"CPE.IN6")
create_conn(x,y,"IM.P07.Y", x,y,"CPE.IN7")
create_conn(x,y,"IM.P08.Y", x,y,"CPE.IN8")
create_conn(x,y,"IM.P09.Y", x,y,"CPE.CLK")
create_conn(x,y,"IM.P10.Y", x,y,"CPE.EN")
create_conn(x,y,"IM.P11.Y", x,y,"CPE.SR")
2024-12-10 13:45:12 +01:00
if is_cpe(x,y-1):
create_conn(x,y-1,"CPE.COUTY1", x,y,"CPE.CINY1")
create_conn(x,y-1,"CPE.COUTY2", x,y,"CPE.CINY2")
create_conn(x,y-1,"CPE.POUTY1", x,y,"CPE.PINY1")
create_conn(x,y-1,"CPE.POUTY2", x,y,"CPE.PINY2")
if is_cpe(x-1,y):
create_conn(x-1,y,"CPE.COUTX", x,y,"CPE.CINX")
create_conn(x-1,y,"CPE.POUTX", x,y,"CPE.PINX")
def create_inmux(x,y):
for p in range(1,13):
plane = f"{p:02d}"
# D0 - D3 are from nearby SBs
offset = 2 if is_sb(x,y) else 1
2024-12-11 15:22:35 +01:00
create_conn(x-offset,y,f"{get_sb_type(x-offset,y)}.P{plane}.Y1", x,y,f"IM.P{plane}.D0")
create_conn(x,y-offset,f"{get_sb_type(x,y-offset)}.P{plane}.Y2", x,y,f"IM.P{plane}.D1")
create_conn(x+offset,y,f"{get_sb_type(x+offset,y)}.P{plane}.Y3", x,y,f"IM.P{plane}.D2")
create_conn(x,y+offset,f"{get_sb_type(x,y+offset)}.P{plane}.Y4", x,y,f"IM.P{plane}.D3")
2024-12-10 13:45:12 +01:00
# D4 and D5 are from diagonal INMUX
if is_cpe(x-1,y-1):
2024-12-11 15:22:35 +01:00
create_conn(x-1,y-1,f"IM.P{plane}.Y", x,y,f"IM.P{plane}.D4")
2024-12-10 13:45:12 +01:00
if is_cpe(x+1,y+1):
2024-12-11 15:22:35 +01:00
create_conn(x+1,y+1,f"IM.P{plane}.Y", x,y,f"IM.P{plane}.D5")
2024-12-10 13:45:12 +01:00
# D6 and D7 are from alternate planes
alt = f"{alt_plane(0,p):02d}"
2024-12-11 15:22:35 +01:00
create_conn(x,y,f"IM.P{alt}.Y", x,y,f"IM.P{plane}.D6")
2024-12-10 13:45:12 +01:00
alt = f"{alt_plane(1,p):02d}"
2024-12-11 15:22:35 +01:00
create_conn(x,y,f"IM.P{alt}.Y", x,y,f"IM.P{plane}.D7")
2024-12-10 13:45:12 +01:00
OUT_PLANE_1 = [ 2, 1, 2, 1, 1, 2, 1, 2]
OUT_PLANE_2 = [ 1, 2, 1, 2, 2, 1, 2, 1]
def create_sb(x,y):
block_x = ((x-1) & ~1) + 1
block_y = ((y-1) & ~1) + 1
sb_type = get_sb_type(x,y)
for p in range(1,13):
plane = f"{p:02d}"
# Handling input D0
if is_cpe(x,y):
# Core section SBs are connected to CPE
if (p<9):
# planes 1..8
# for SB in lower left section of block
# x offset +0 y offset +0 output 2 plane 1
# x offset +0 y offset +1 output 1 plane 2
# x offset +1 y offset +0 output 2 plane 3
# x offset +1 y offset +1 output 1 plane 4
# x offset +0 y offset +0 output 1 plane 5
# x offset +0 y offset +1 output 2 plane 6
# x offset +1 y offset +0 output 1 plane 7
# x offset +1 y offset +1 output 2 plane 8
# for SB in upper right section of block
# difference is only that outputs are reversed
x_cpe = block_x + (1 if (p-1) & 2 else 0)
y_cpe = block_y + (1 if (p-1) & 1 else 0)
out = OUT_PLANE_1[p-1] if x & 1 else OUT_PLANE_2[p-1]
create_conn(x_cpe,y_cpe,f"CPE.OUT{out}", x,y,f"{sb_type}.P{plane}.D0")
else:
# planes 9..12
2024-12-11 15:22:35 +01:00
create_conn(x,y,f"OM.P{plane}.Y", x,y,f"{sb_type}.P{plane}.D0")
2024-12-10 13:45:12 +01:00
# else:
# Handling GPIO connections
# Handling other inputs
def create_outmux(x,y):
block_x = ((x-1) & ~1) + 1
block_y = ((y-1) & ~1) + 1
for p in range(9,13):
plane = f"{p:02d}"
output_1 = 1 if (x % 2) ^ (p % 2) else 2
output_2 = 2 if (x % 2) ^ (p % 2) else 1
2024-12-11 15:22:35 +01:00
create_conn(block_x, block_y, f"CPE.OUT{output_1}", x,y, f"OM.P{plane}.D0")
create_conn(block_x, block_y+1, f"CPE.OUT{output_1}", x,y, f"OM.P{plane}.D1")
create_conn(block_x+1, block_y, f"CPE.OUT{output_2}", x,y, f"OM.P{plane}.D2")
create_conn(block_x+1, block_y+1, f"CPE.OUT{output_2}", x,y, f"OM.P{plane}.D3")
2024-12-09 18:41:42 +01:00
2024-12-10 13:45:12 +01:00
def get_connections():
2024-12-09 18:41:42 +01:00
for y in range(-2, max_row()+1):
for x in range(-2, max_col()+1):
if is_cpe(x,y):
2024-12-10 13:45:12 +01:00
create_cpe(x,y)
create_inmux(x,y)
if is_outmux(x,y):
create_outmux(x,y)
if is_sb(x,y):
create_sb(x,y)
2024-12-09 18:41:42 +01:00
return conn.items()