From 8f0b8a06f2ca33a648fec4323854c114eeb3de41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Milanovi=C4=87?= Date: Mon, 22 Dec 2025 15:10:11 +0100 Subject: [PATCH] Extending for LUT permutation (#14) --- gatemate/chip.py | 41 +++++++++++- gatemate/die.py | 163 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 202 insertions(+), 2 deletions(-) diff --git a/gatemate/chip.py b/gatemate/chip.py index 661d71e..46a0135 100644 --- a/gatemate/chip.py +++ b/gatemate/chip.py @@ -23,7 +23,7 @@ from dataclasses import dataclass from typing import List, Dict from timing import decompress_timing -DATABASE_VERSION = 1.10 +DATABASE_VERSION = 1.11 @dataclass(eq=True, order=True) class Pad: @@ -304,12 +304,51 @@ def get_timings(name): name = f"om_x{i1+1}_y{i2+1}_p{i3+9}_d{i4}" val[name] = convert_delay(d) + cnt_ccy1 = 1 + cnt_cpy1 = 1 + cnt_pcy1 = 1 + cnt_ppy1 = 1 for i1 in range(10): # [0..9] for i2 in range(19): # [1..19] for i3 in range(10): # [1..10] d = timing_data.CPE_del_tile_arr[i1][i2][i3] if d.name == "CPE": # not used continue + # These are wrong names in timing database + # and need fixing + if d.name == "_ROUTING_CINY2_COUTY": + d.name = "_ROUTING_CINY2_COUTY2" + if d.name == "_ROUTING_PINY2_POUTY": + d.name = "_ROUTING_PINY2_POUTY2" + + if d.name == "_ROUTING_CINY1_COUTY": + if cnt_ccy1 == 1: + d.name = "_ROUTING_CINY1_COUTY1" + cnt_ccy1 = 2 + else: + d.name = "_ROUTING_CINY1_COUTY2" + cnt_ccy1 = 1 + if d.name == "_ROUTING_CINY1_POUTY": + if cnt_cpy1 == 1: + d.name = "_ROUTING_CINY1_POUTY1" + cnt_cpy1 = 2 + else: + d.name = "_ROUTING_CINY1_POUTY2" + cnt_cpy1 = 1 + if d.name == "_ROUTING_PINY1_COUTY": + if cnt_pcy1 == 1: + d.name = "_ROUTING_PINY1_COUTY1" + cnt_pcy1 = 2 + else: + d.name = "_ROUTING_PINY1_COUTY2" + cnt_pcy1 = 1 + if d.name == "_ROUTING_PINY1_POUTY": + if cnt_ppy1 == 1: + d.name = "_ROUTING_PINY1_POUTY1" + cnt_ppy1 = 2 + else: + d.name = "_ROUTING_PINY1_POUTY2" + cnt_ppy1 = 1 val[d.name] = convert_delay(d.val) for i1 in range(165): # [-2..162] diff --git a/gatemate/die.py b/gatemate/die.py index 1280a1b..e5bd697 100644 --- a/gatemate/die.py +++ b/gatemate/die.py @@ -513,10 +513,21 @@ RAM_HALF_PINS = [ PRIMITIVES_PINS = { "CPE_LT_U": [ + # LUT2 first level + Pin("D0_00" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D1_00" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D0_01" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D1_01" ,PinType.INPUT, "CPE_WIRE", True), + # LUT2 2nd level + Pin("D0_10" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D1_10" ,PinType.INPUT, "CPE_WIRE", True), + + # regular inputs Pin("IN1" ,PinType.INPUT, "CPE_WIRE", True), Pin("IN2" ,PinType.INPUT, "CPE_WIRE", True), Pin("IN3" ,PinType.INPUT, "CPE_WIRE", True), Pin("IN4" ,PinType.INPUT, "CPE_WIRE", True), + Pin("OUT" ,PinType.OUTPUT, "CPE_WIRE", True), Pin("CPOUT" ,PinType.OUTPUT, "CPE_WIRE", True), Pin("PINY1" ,PinType.INPUT, "CPE_WIRE", True), @@ -536,11 +547,25 @@ PRIMITIVES_PINS = { Pin("RAM_O" ,PinType.OUTPUT, "CPE_WIRE", True), ], "CPE_LT_L": [ + # LUT2 first level + Pin("D0_00" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D1_00" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D0_01" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D1_01" ,PinType.INPUT, "CPE_WIRE", True), + # LUT2 2nd level + Pin("D0_10" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D1_10" ,PinType.INPUT, "CPE_WIRE", True), + + # LUT2 3rd level input + Pin("COMBIN" ,PinType.INPUT, "CPE_WIRE", True), + + # regular inputs Pin("IN1" ,PinType.INPUT, "CPE_WIRE", True), Pin("IN2" ,PinType.INPUT, "CPE_WIRE", True), Pin("IN3" ,PinType.INPUT, "CPE_WIRE", True), Pin("IN4" ,PinType.INPUT, "CPE_WIRE", True), - Pin("COMBIN" ,PinType.INPUT, "CPE_WIRE", True), + + # outputs Pin("OUT" ,PinType.OUTPUT, "CPE_WIRE", True), Pin("CPOUT" ,PinType.OUTPUT, "CPE_WIRE", True), @@ -582,6 +607,18 @@ PRIMITIVES_PINS = { Pin("MUXOUT" ,PinType.OUTPUT, "CPE_WIRE", True), ], "CPE_LT_FULL": [ + Pin("D0_00" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D1_00" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D0_01" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D1_01" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D0_02" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D1_02" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D0_03" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D1_03" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D0_10" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D1_10" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D0_11" ,PinType.INPUT, "CPE_WIRE", True), + Pin("D1_11" ,PinType.INPUT, "CPE_WIRE", True), Pin("IN1" ,PinType.INPUT, "CPE_WIRE", True), Pin("IN2" ,PinType.INPUT, "CPE_WIRE", True), Pin("IN3" ,PinType.INPUT, "CPE_WIRE", True), @@ -2960,6 +2997,18 @@ def get_pin_connection_name(prim, pin): return "CPE.COMBOUT2_int" case "CPOUT": return "CPE.CPOUT2_int" + case "D0_00": + return "CPE.D0_00_int" + case "D1_00": + return "CPE.D1_00_int" + case "D0_01": + return "CPE.D0_01_int" + case "D1_01": + return "CPE.D1_01_int" + case "D0_10": + return "CPE.D0_10_int" + case "D1_10": + return "CPE.D1_10_int" case "IN1": return "CPE.IN1_int" case "IN2": @@ -2976,6 +3025,10 @@ def get_pin_connection_name(prim, pin): return "CPE.DIN2_int" case "DOUT": return "CPE.DOUT2_int" + case "CLK": + return "CPE.CLK_int" + case "EN": + return "CPE.EN_int" case _: return f"CPE.{pin.name}" elif prim.type == "CPE_RAMIO_U": @@ -2996,6 +3049,18 @@ def get_pin_connection_name(prim, pin): return "CPE.COMBOUT1_int" case "CPOUT": return "CPE.CPOUT1_int" + case "D0_00": + return "CPE.D0_02_int" + case "D1_00": + return "CPE.D1_02_int" + case "D0_01": + return "CPE.D0_03_int" + case "D1_01": + return "CPE.D1_03_int" + case "D0_10": + return "CPE.D0_11_int" + case "D1_10": + return "CPE.D1_11_int" case "IN1": return "CPE.IN5_int" case "IN2": @@ -3010,6 +3075,30 @@ def get_pin_connection_name(prim, pin): return f"CPE.{pin.name}" elif prim.type == "CPE_LT_FULL": match pin.name: + case "D0_00": + return "CPE.D0_00_int" + case "D1_00": + return "CPE.D1_00_int" + case "D0_01": + return "CPE.D0_01_int" + case "D1_01": + return "CPE.D1_01_int" + case "D0_10": + return "CPE.D0_10_int" + case "D1_10": + return "CPE.D1_10_int" + case "D0_02": + return "CPE.D0_02_int" + case "D1_02": + return "CPE.D1_02_int" + case "D0_03": + return "CPE.D0_03_int" + case "D1_03": + return "CPE.D1_03_int" + case "D0_11": + return "CPE.D0_11_int" + case "D1_11": + return "CPE.D1_11_int" case "OUT1": return "CPE.COMBOUT1_int" case "OUT2": @@ -3066,6 +3155,10 @@ def get_pin_connection_name(prim, pin): return "CPE.DIN1_int" case "DOUT": return "CPE.DOUT1_int" + case "CLK": + return "CPE.CLK_int" + case "EN": + return "CPE.EN_int" case _: return f"CPE.{pin.name}" elif prim.type == "CPE_RAMIO_L": @@ -3141,6 +3234,21 @@ def get_endpoints_for_type(type): 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.D0_00_int", type="CPE_WIRE_INT") + create_wire("CPE.D1_00_int", type="CPE_WIRE_INT") + create_wire("CPE.D0_01_int", type="CPE_WIRE_INT") + create_wire("CPE.D1_01_int", type="CPE_WIRE_INT") + create_wire("CPE.D0_10_int", type="CPE_WIRE_INT") + create_wire("CPE.D1_10_int", type="CPE_WIRE_INT") + + create_wire("CPE.D0_02_int", type="CPE_WIRE_INT") + create_wire("CPE.D1_02_int", type="CPE_WIRE_INT") + create_wire("CPE.D0_03_int", type="CPE_WIRE_INT") + create_wire("CPE.D1_03_int", type="CPE_WIRE_INT") + create_wire("CPE.D0_11_int", type="CPE_WIRE_INT") + create_wire("CPE.D1_11_int", type="CPE_WIRE_INT") + create_wire("CPE.IN1_int", type="CPE_WIRE_INT") create_wire("CPE.IN2_int", type="CPE_WIRE_INT") create_wire("CPE.IN3_int", type="CPE_WIRE_INT") @@ -3149,6 +3257,12 @@ def get_endpoints_for_type(type): create_wire("CPE.IN6_int", type="CPE_WIRE_INT") create_wire("CPE.IN7_int", type="CPE_WIRE_INT") create_wire("CPE.IN8_int", type="CPE_WIRE_INT") + + create_wire("CPE.TI2_int", type="CPE_WIRE_INT") + create_wire("CPE.TI4_int", type="CPE_WIRE_INT") + create_wire("CPE.TI6_int", type="CPE_WIRE_INT") + create_wire("CPE.TI8_int", type="CPE_WIRE_INT") + create_wire("CPE.OUT1_int", type="CPE_WIRE_INT") create_wire("CPE.OUT2_int", type="CPE_WIRE_INT") create_wire("CPE.COMBOUT1_int", type="CPE_WIRE_INT") @@ -3169,6 +3283,8 @@ def get_endpoints_for_type(type): create_wire("CPE.DOUT2_int", type="CPE_WIRE_INT") create_wire("CPE.CLK" , type="CPE_WIRE_L") create_wire("CPE.EN" , type="CPE_WIRE_L") + create_wire("CPE.CLK_int", type="CPE_WIRE_INT") + create_wire("CPE.EN_int" , type="CPE_WIRE_INT") create_wire("CPE.SR" , type="CPE_WIRE_L") create_wire("CPE.OUT1" , type="CPE_WIRE_B") create_wire("CPE.OUT2" , type="CPE_WIRE_B") @@ -3371,6 +3487,51 @@ def get_mux_connections_for_type(type): # CPE for i in range(1,9): create_direct(f"CPE.IN{i}", f"CPE.IN{i}_int", delay="del_dummy") + + create_mux("CPE.IN2_int", "CPE.TI2_int", 1, 0, False, "C_I1", False, delay="del_dummy") + create_mux("CPE.IN4_int", "CPE.TI4_int", 1, 0, False, "C_I2", False, delay="del_dummy") + create_mux("CPE.IN6_int", "CPE.TI6_int", 1, 0, False, "C_I3", False, delay="del_dummy") + create_mux("CPE.IN8_int", "CPE.TI8_int", 1, 0, False, "C_I4", False, delay="del_dummy") + create_mux("CPE.PINY1", "CPE.TI2_int", 1, 1, False, "C_I1", False, delay="del_dummy") + create_mux("CPE.CINX", "CPE.TI4_int", 1, 1, False, "C_I2", False, delay="del_dummy") + create_mux("CPE.PINY1", "CPE.TI6_int", 1, 1, False, "C_I3", False, delay="del_dummy") + create_mux("CPE.PINX", "CPE.TI8_int", 1, 1, False, "C_I4", False, delay="del_dummy") + + create_mux("CPE.IN1_int", "CPE.D0_00_int", 1, 0, False, "LUT2_00", False, delay="del_dummy") + create_mux("CPE.TI2_int", "CPE.D1_00_int", 1, 0, False, "LUT2_00", False, delay="del_dummy") + create_mux("CPE.TI2_int", "CPE.D0_00_int", 1, 1, False, "LUT2_00", False, delay="del_dummy") + create_mux("CPE.IN1_int", "CPE.D1_00_int", 1, 1, False, "LUT2_00", False, delay="del_dummy") + + create_mux("CPE.IN3_int", "CPE.D0_01_int", 1, 0, False, "LUT2_01", False, delay="del_dummy") + create_mux("CPE.TI4_int", "CPE.D1_01_int", 1, 0, False, "LUT2_01", False, delay="del_dummy") + create_mux("CPE.TI4_int", "CPE.D0_01_int", 1, 1, False, "LUT2_01", False, delay="del_dummy") + create_mux("CPE.IN3_int", "CPE.D1_01_int", 1, 1, False, "LUT2_01", False, delay="del_dummy") + + create_mux("CPE.D0_00_int", "CPE.D0_10_int", 1, 0, False, "LUT2_10", False, delay="del_dummy") + create_mux("CPE.D0_01_int", "CPE.D1_10_int", 1, 0, False, "LUT2_10", False, delay="del_dummy") + create_mux("CPE.D0_01_int", "CPE.D0_10_int", 1, 1, False, "LUT2_10", False, delay="del_dummy") + create_mux("CPE.D0_00_int", "CPE.D1_10_int", 1, 1, False, "LUT2_10", False, delay="del_dummy") + + create_mux("CPE.IN5_int", "CPE.D0_02_int", 1, 0, False, "LUT2_02", False, delay="del_dummy") + create_mux("CPE.TI6_int", "CPE.D1_02_int", 1, 0, False, "LUT2_02", False, delay="del_dummy") + create_mux("CPE.TI6_int", "CPE.D0_02_int", 1, 1, False, "LUT2_02", False, delay="del_dummy") + create_mux("CPE.IN5_int", "CPE.D1_02_int", 1, 1, False, "LUT2_02", False, delay="del_dummy") + + create_mux("CPE.IN7_int", "CPE.D0_03_int", 1, 0, False, "LUT2_03", False, delay="del_dummy") + create_mux("CPE.TI8_int", "CPE.D1_03_int", 1, 0, False, "LUT2_03", False, delay="del_dummy") + create_mux("CPE.TI8_int", "CPE.D0_03_int", 1, 1, False, "LUT2_03", False, delay="del_dummy") + create_mux("CPE.IN7_int", "CPE.D1_03_int", 1, 1, False, "LUT2_03", False, delay="del_dummy") + + create_mux("CPE.D0_02_int", "CPE.D0_11_int", 1, 0, False, "LUT2_11", False, delay="del_dummy") + create_mux("CPE.D0_03_int", "CPE.D1_11_int", 1, 0, False, "LUT2_11", False, delay="del_dummy") + create_mux("CPE.D0_03_int", "CPE.D0_11_int", 1, 1, False, "LUT2_11", False, delay="del_dummy") + create_mux("CPE.D0_02_int", "CPE.D1_11_int", 1, 1, False, "LUT2_11", False, delay="del_dummy") + + create_mux("CPE.CLK", "CPE.CLK_int", 1, 0, False, "C_CLKSEL", False, delay="del_dummy") + #create_mux("CPE.CINY2", "CPE.CLK_int", 1, 1, False, "C_CLKSEL", False, delay="del_dummy") + create_mux("CPE.EN", "CPE.EN_int", 1, 0, False, "C_ENSEL", False, delay="del_dummy") + #create_mux("CPE.PINY2", "CPE.EN_int", 1, 1, False, "C_ENSEL", False, delay="del_dummy") + for p in range(1,13): plane = f"{p:02d}" for i in range(8):