Global Router with Keepouts and 3D Extension

physdes-py

2026

๐Ÿงญ Global Router with Keepouts and 3D Extension

VLSI Physical Design Automation

Rectilinear Shapes

๐Ÿ“‹ Agenda

  1. Introduction - What is Global Routing? ๐ŸŽฏ
  2. Core Architecture - GlobalRouter & RoutingTree ๐Ÿ—๏ธ
  3. Routing Strategies - Simple, Steiner, Constraints โšก
  4. Keepouts - Avoiding Obstacles ๐Ÿšง
  5. 3D Extension - Multi-layer Routing ๐Ÿ“ฆ
  6. Visualization - SVG Output Examples ๐Ÿ–ผ๏ธ
  7. Code Demo - Live Examples ๐Ÿ’ป
  8. Summary & Future Work ๐Ÿ”ฎ

๐ŸŽฏ What is Global Routing?

Global routing determines the general path of each net through the chip, while detailed routing refines the exact wire positions.

graph TD
    A[Net List] --> B[Global Routing]
    B --> C[Routing Regions]
    C --> D[Detailed Routing]
    D --> E[Final Layout]

    style A fill:#e1f5fe
    style B fill:#b3e5fc
    style C fill:#81d4fa
    style D fill:#4fc3f7
    style E fill:#29b6f6

Key Objectives:


๐Ÿ—๏ธ Core Architecture

GlobalRouter Class

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              GlobalRouter                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  - source_position: Point      (start)       โ”‚
โ”‚  - terminal_positions: List[Point] (sinks)  โ”‚
โ”‚  - keepouts: List[Point] (obstacles)        โ”‚
โ”‚  - tree: GlobalRoutingTree (result)         โ”‚
โ”‚  - worst_wirelength: int (constraint)       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Key Methods:

Method Purpose
route_simple() Direct connection
route_with_steiners() Optimal wirelength
route_with_constraints() Performance-driven

๐ŸŒณ Routing Tree Structure

class GlobalRoutingTree:
    """
    Global routing tree that supports 
    Steiner node and terminal node insertion.
    """
    
    # Node Types:
    # - SOURCE: Starting point
    # - STEINER: Intermediate optimization points
    # - TERMINAL: End points (sinks)

Tree Visualization:

                    +--.----------o (terminal)
                    |   `.
                    |     `.      (steiner)
                    |       `.
                    o---------`---+ (source)

         +--<---o
         |
         *-------->---o
         |
  o--->--+

โšก Routing Strategy 1: Simple

route_simple() - Direct Connection

Connects each terminal directly to the nearest node in the existing tree.

def route_simple(self) -> None:
    for t in self.terminal_positions:
        self.tree.insert_terminal_node(t)

Visual Example:

graph LR
    S[Source<br/>๐Ÿ“] --> T1[Terminal 1]
    S --> T2[Terminal 2]
    S --> T3[Terminal 3]

    style S fill:#ff9800
    style T1 fill:#4caf50
    style T2 fill:#4caf50
    style T3 fill:#4caf50

Pros/Cons:


๐ŸŒฟ Routing Strategy 2: Steiner Points

route_with_steiners() - Wirelength Optimization

Inserts Steiner points to reduce total wirelength by creating shared paths.

def route_with_steiners(self) -> None:
    for t in self.terminal_positions:
        self.tree.insert_terminal_with_steiner(t, self.keepouts)

The Steiner Problem:

Given n terminals, find minimum spanning tree.

Minimize: โˆ‘i,โ€†jwijโ€…โ‹…โ€…xij

Where xijโ€„=โ€„1 if edge (i,โ€†j) is in the tree.

Visual:

graph TD
    S[Source] --> SP[Steiner Point]
    SP --> T1[Terminal 1]
    SP --> T2[Terminal 2]

    style S fill:#ff9800
    style SP fill:#9c27b0
    style T1 fill:#4caf50
    style T2 fill:#4caf50

โฑ๏ธ Routing Strategy 3: Constraints

route_with_constraints() - Performance-Driven

Balances wirelength with timing constraints using ฮฑ parameter.

def route_with_constraints(self, alpha: float = 1.0) -> None:
    allowed_wirelength = round(self.worst_wirelength * alpha)
    for t in self.terminal_positions:
        self.tree.insert_terminal_with_constraints(
            t, allowed_wirelength, self.keepouts
        )

Constraint Equation:

allowed_lengthโ€„=โ€„ฮฑโ€…ร—โ€…worst_wirelength

Where ฮฑโ€„โˆˆโ€„[0.5,โ€†2.0] typically.

When to Use:

Scenario ฮฑ Value
High-performance 0.5 - 0.8
Balanced 1.0
Relaxed timing 1.2 - 2.0

๐Ÿšง Keepouts Implementation

What are Keepouts?

Keepouts are rectangular regions that the router must avoid - like pre-routed wires, macros, or IP blocks.

# Define keepouts as intervals
keepouts = [
    Point(Interval(1600, 1900), Interval(1000, 1500)),
    Point(Interval(500, 800), Interval(600, 900)),
]

Visual Representation:

rectangle
    title Keepout Regions
    direction LR
    A[Routing Area]
    B{Keepout 1}
    C{Keepout 2}
    D[Free to Route]

    A --> B
    A --> C
    A --> D

Blocking Detection:

# From routing_tree.py
for keepout in keepouts:
    if (keepout.contains(nearest_pt) or 
        keepout.blocks(path1) or 
        keepout.blocks(path2) or 
        keepout.blocks(path3)):
        block = True

๐Ÿ” Keepout Path Avoidance Algorithm

_find_insertion_point() Method

def _find_insertion_point(
    point: Point,
    keepouts: Optional[List[Point]] = None,
    allowed_wirelength: Optional[int] = None,
) -> Tuple[Optional[RoutingNode], RoutingNode]:

Algorithm Flow:

flowchart TD
    A[Start] --> B{Traverse Tree}
    B --> C[Calculate Path to Point]
    C --> D{Keepouts Block?}
    D -->|Yes| E[Skip This Branch]
    D -->|No| F{Distance < Min?}
    F -->|Yes| G[Update Nearest]
    F -->|No| H[Continue]
    G --> I{Allowed Wirelength?}
    I -->|Yes| J[Check Constraint]
    J -->|Pass| K[Select as Candidate]
    I -->|No| K
    H --> B
    K --> L[Return Parent & Nearest]

    style A fill:#ff9800
    style K fill:#4caf50

๐Ÿ“ฆ 3D Extension

Multi-Layer Routing

The router supports 3D coordinates - useful for multi-layer chips (e.g., 2D + metal layers).

2D vs 3D Point:

# 2D Point
p2d = Point(100, 200)

# 3D Point (x, y, z) where z = layer
p3d = Point(Point(100, 200), 3)  # Layer 3

Visual:

graph LR
    subgraph "2D View"
        A[x, y]
    end
    subgraph "3D View"
        B[x, y, z]
    end

    A -->|"extend"| B

    style A fill:#e3f2fd
    style B fill:#bbdefb

Distance Calculation:


๐Ÿ“Š 3D Wirelength Comparison

Scenario 2D Wirelength 3D Wirelength Savings
Same layer L2 L2โ€…+โ€…2z -
Multi-layer L L/2โ€…+โ€…z โœ… ~50%

Example from Code:

>>> tree2d = GlobalRoutingTree(Point(0, 0))
>>> tree2d.insert_steiner_node(Point(2, 2))
>>> tree2d.calculate_total_wirelength()
4

>>> tree3d = GlobalRoutingTree(Point(Point(0, 0), 0))
>>> tree3d.insert_steiner_node(Point(Point(2, 2), 2))
>>> tree3d.calculate_total_wirelength()
6  # 2 + 2 + 2 (includes z-layer cost)

๐Ÿ–ผ๏ธ Visualization Examples - 2D

1. Routing with Steiner Points

Routing with Steiner Points

Optimal wirelength using Steiner points


๐Ÿ–ผ๏ธ With Constraints

2. Routing with Timing Constraints

Routing with Constraints

Performance-driven routing with timing budget


๐Ÿ–ผ๏ธ With Keepouts

3. Routing with Obstacles

Routing with Keepouts

Routes detour around gray keepout regions


๐Ÿ–ผ๏ธ Steiner + Keepouts

4. Optimal Routing with Obstacles

Steiner with Keepouts

Combines Steiner optimization with keepout avoidance


๐Ÿ–ผ๏ธ 3D Routing Examples

5. 3D Routing with Steiner Points

3D Steiner

6. 3D with Constraints & Keepouts

3D Constraints

๐Ÿ’ป Code Demo

Basic Usage

from physdes.point import Point
from physdes.router.global_router import GlobalRouter

# Define source and terminals
source = Point(0, 0)
terminals = [Point(10, 0), Point(5, 5), Point(8, 3)]

# Create router
router = GlobalRouter(source, terminals)

# Choose strategy
router.route_simple()          # Fast, direct
# or
router.route_with_steiners()   # Optimal wirelength
# or
router.route_with_constraints(1.0)  # With timing budget

With Keepouts

from physdes.interval import Interval

# Define keepout regions
keepouts = [
    Point(Interval(4, 6), Interval(-1, 1)),  # Block in middle
]

router = GlobalRouter(source, terminals, keepouts)
router.route_with_steiners()

# Calculate total wirelength
total_wl = router.tree.calculate_total_wirelength()
print(f"Total wirelength: {total_wl}")

With 3D Coordinates

# 3D routing (e.g., 2-metal layer design)
source_3d = Point(Point(0, 0), 0)      # Layer 0
terminals_3d = [
    Point(Point(10, 1), 1),  # Layer 1
    Point(Point(5, 2), 2),   # Layer 2
]

router_3d = GlobalRouter(source_3d, terminals_3d)
router_3d.route_with_steiners()

Visualization

from physdes.router.routing_visualizer import (
    save_routing_tree_svg,
    visualize_routing_tree_svg
)

# Generate SVG string
svg = visualize_routing_tree_svg(
    router.tree, 
    keepouts, 
    width=1000, 
    height=1000
)
print(svg)

# Save to file
save_routing_tree_svg(
    router.tree, 
    keepouts,
    filename="my_route.svg"
)

๐Ÿ“ˆ Algorithm Complexity

Operation Time Complexity
route_simple() O(nโ€…โ‹…โ€…m)
route_with_steiners() O(nโ€…โ‹…โ€…mโ€…โ‹…โ€…k)
_find_insertion_point() O(m) per call

Where: - n = number of terminals - m = nodes in tree - k = number of keepouts


๐Ÿ”ฌ Key Data Structures

Point Class (Generic)

class Point(T1, T2):
    """Supports both 2D and 3D coordinates"""
    
    xcoord: T1  # int or Interval
    ycoord: T2  # int or Interval

RoutingNode

class RoutingNode:
    id: str
    type: NodeType  # SOURCE, STEINER, TERMINAL
    pt: Point
    children: List[RoutingNode]
    parent: Optional[RoutingNode]
    path_length: int  # for constraint checking

๐ŸŽฏ Key Algorithms

def _find_nearest_node(self, point: Point) -> RoutingNode:
    """Find node with minimum Manhattan distance"""
    nearest = self.source
    min_distance = self.source.manhattan_distance(target)
    
    for node in self.nodes.values():
        dist = node.manhattan_distance(target)
        if dist < min_distance:
            nearest = node
    return nearest

2. Steiner Point Insertion

def insert_terminal_with_steiner(self, point, keepouts=None):
    parent, nearest = self._find_insertion_point(point, keepouts)
    
    if parent is None:
        nearest.add_child(terminal)
    else:
        # Insert Steiner point on the branch
        nearest_pt = possible_path.nearest_to(point)
        steiner = RoutingNode(..., nearest_pt)
        # Reconnect: parent -> steiner -> nearest + terminal

๐Ÿงช Testing

Run Tests

# All tests
pytest

# Specific test
pytest tests/test_global_router_with_keepouts.py -v

# With coverage
pytest --cov physdes --cov-report term-missing

Test Coverage:

Module Tests
global_router.py โœ… test_route_*
routing_tree.py โœ… Tree operations
keepouts โœ… test_global_router_with_keepouts.py
3D โœ… test_global_router3d*.py

๐Ÿ“Š Output Examples - Global Router

2D Routing Results

Image Description
Steiner Routing with Steiner points
Constraints Routing with timing constraints
Keepouts Routing with keepout obstacles
Steiner+Keepouts Steiner points + keepouts

3D Routing Results

Image Description
3D Steiner 3D routing with Steiner points
3D Constraints 3D with constraints & keepouts

๐Ÿ”„ Flow Diagram

flowchart TB
    subgraph Input
        A[Source Point] --> R[GlobalRouter]
        B[Terminals] --> R
        C[Keepouts] --> R
    end

    R --> D{route_simple}
    R --> E{route_with_steiners}
    R --> F{route_with_constraints}

    D --> G[Direct Connection]
    E --> H[Find Optimal Branch]
    F --> I[Check Wirelength Budget]

    G --> J[GlobalRoutingTree]
    H --> J
    I --> J

    J --> K[Calculate Wirelength]
    K --> L[Visualize SVG]

    style R fill:#ff9800
    style J fill:#4caf50
    style L fill:#2196f3

๐Ÿ’ก Design Patterns Used

1. Strategy Pattern

Different routing algorithms as interchangeable strategies.

# GlobalRouter supports multiple strategies
router.route_simple()           # Strategy A
router.route_with_steiners()    # Strategy B  
router.route_with_constraints() # Strategy C

2. Composite Pattern

Routing tree as hierarchical structure.

graph TD
    Source --> Steiner1
    Source --> Steiner2
    Steiner1 --> Terminal1
    Steiner1 --> Terminal2
    Steiner2 --> Terminal3

    style Source fill:#ff9800
    style Steiner1 fill:#9c27b0
    style Steiner2 fill:#9c27b0
    style Terminal1 fill:#4caf50
    style Terminal2 fill:#4caf50
    style Terminal3 fill:#4caf50

๐Ÿ”ง Extensions & Future Work

Potential Enhancements

Feature Description Difficulty
Congestion-aware Consider track usage โญโญโญ
Timing-driven Use slack-based costs โญโญโญ
Power routing Optimize for IR drop โญโญโญ
Net ordering Priority-based routing โญโญ
Layer assignment Auto metal layer select โญโญ

๐Ÿ“š References

Papers

Code References

Documentation

# Generate docs
sphinx-build -b html docs/ docs/_build/html

# View at http://localhost:8000

โœ… Summary

What We Covered:

  1. GlobalRouter class with 3 routing strategies
  2. Keepouts for obstacle avoidance
  3. 3D extension for multi-layer chips
  4. Visualization via SVG output
  5. Code examples and test cases

Key Takeaways:


๐Ÿ Q&A

Questions?

Routing

Contact


๐Ÿ“Ž Appendix: Mathematical Formulas

Manhattan Distance

d2((x1,โ€†y1),โ€†(x2,โ€†y2))โ€„=โ€„|x1โ€…โˆ’โ€…x2|+|y1โ€…โˆ’โ€…y2|

3D Manhattan Distance

d3((x1,โ€†y1,โ€†z1),โ€†(x2,โ€†y2,โ€†z2))โ€„=โ€„|x1โ€…โˆ’โ€…x2|+|y1โ€…โˆ’โ€…y2|+|z1โ€…โˆ’โ€…z2|

Wirelength Budget

budgetโ€„=โ€„ฮฑโ€…ร—โ€…maxi(dist(source,โ€†terminali))


๐Ÿ“Ž Appendix: Point Class API

Creation

# 2D
p = Point(100, 200)

# 2D with intervals (for keepouts)
p = Point(Interval(10, 20), Interval(30, 40))

# 3D
p3d = Point(Point(100, 200), 3)  # (x,y), layer

Methods

Method Description
min_dist_with(other) Manhattan distance
hull_with(other) Bounding box (Interval)
contains(point) Point in rect?
blocks(path) Path intersects rect?
nearest_to(point) Closest point on rect edge

๐Ÿ“Ž Appendix: File Structure

physdes-py/
โ”œโ”€โ”€ src/physdes/
โ”‚   โ”œโ”€โ”€ router/
โ”‚   โ”‚   โ”œโ”€โ”€ global_router.py      # Main router โญ
โ”‚   โ”‚   โ”œโ”€โ”€ routing_tree.py       # Tree structure โญ
โ”‚   โ”‚   โ””โ”€โ”€ routing_visualizer.py # SVG output
โ”‚   โ”œโ”€โ”€ point.py                  # Point/Interval classes
โ”‚   โ”œโ”€โ”€ interval.py               # Interval arithmetic
โ”‚   โ””โ”€โ”€ cts/
โ”‚       โ””โ”€โ”€ dme_algorithm.py       # Clock tree synthesis
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ test_global_router*.py    # Router tests
โ”‚   โ””โ”€โ”€ test_routing_tree*.py     # Tree tests
โ”œโ”€โ”€ outputs/                       # Generated SVGs
โ”‚   โ”œโ”€โ”€ example_route*.svg
โ”‚   โ””โ”€โ”€ *clock_tree*.svg
โ””โ”€โ”€ README.md

Appendix: Mermaid Diagram Styles

Color Legend

graph TD
    A[Source/Start] --> B[Process]
    B --> C[Output]
    B --> D[Alternative]

    style A fill:#ff9800,color:#000
    style B fill:#2196f3,color:#fff
    style C fill:#4caf50,color:#000
    style D fill:#f44336,color:#fff
Color Meaning
๐ŸŸ  Orange Start/Source
๐Ÿ”ต Blue Process/Action
๐ŸŸข Green Success/Output
๐Ÿ”ด Red Error/Alternative

๐ŸŽฌ End of Presentation

Thank you! ๐ŸŽ‰

physdes-py - VLSI Physical Design Python Library

Logo