| """ |
| This file contains definitions of various data structutes used to hold tilegrid |
| and routing information of a Quicklogic FPGA. |
| """ |
| from collections import namedtuple |
| from enum import Enum |
| |
| # ============================================================================= |
| """ |
| Pin direction in terms of its function. |
| """ |
| |
| |
| class PinDirection(Enum): |
| UNSPEC = 0 |
| INPUT = 1 |
| OUTPUT = 2 |
| |
| |
| """ |
| An opposite direction map |
| """ |
| OPPOSITE_DIRECTION = { |
| PinDirection.UNSPEC: PinDirection.UNSPEC, |
| PinDirection.INPUT: PinDirection.OUTPUT, |
| PinDirection.OUTPUT: PinDirection.INPUT, |
| } |
| """ |
| A generic pin |
| """ |
| Pin = namedtuple("Pin", "name direction attrib") |
| """ |
| Pin direction in therms where is it "standing out" of a tile. |
| """ |
| |
| |
| class PinSide(Enum): |
| UNSPEC = 0 |
| NORTH = 1 |
| SOUTH = 2 |
| EAST = 3 |
| WEST = 4 |
| |
| |
| """ |
| This is a generic location in the tilegrid. Note that it also encounters for |
| the sub-tile index z. |
| """ |
| Loc = namedtuple("Loc", "x y z") |
| """ |
| FPGA grid quadrant. |
| """ |
| Quadrant = namedtuple("Quadrant", "name x0 y0 x1 y1") |
| """ |
| Forwads and backward location mapping |
| """ |
| LocMap = namedtuple("LocMap", "fwd bwd") |
| |
| # ============================================================================= |
| """ |
| A cell type within a tile type representation (should be named "site" ?). |
| Holds the cell type name and the list of its pins. |
| """ |
| CellType = namedtuple("CellType", "type pins") |
| """ |
| A cell instance within a tile. Binds a cell name with its type. |
| |
| type - Cell type |
| index - Index within the tile |
| name - Cell name (not necessarly unique) |
| alias - Cell alias (if present) |
| """ |
| Cell = namedtuple("Cell", "type index name alias") |
| |
| # ============================================================================= |
| |
| |
| class TileType(object): |
| """ |
| A tile type representation. The Quicklogic FPGA fabric does not define tiles. |
| It has rather a group of cells bound to a common geographical location. |
| """ |
| |
| def __init__(self, type, cells, fake_const_pin=False): |
| self.type = type |
| self.cells = cells |
| self.pins = [] |
| self.fake_const_pin = fake_const_pin |
| |
| def make_pins(self, cells_library): |
| """ |
| Basing on the cell list and their pins generates the tile pins. |
| """ |
| self.pins = [] |
| |
| # Copy pins from all cells. Prefix their names with a cell name. |
| for cell_type, cell_count in self.cells.items(): |
| for i in range(cell_count): |
| for pin in cells_library[cell_type].pins: |
| name = "{}{}_{}".format(cell_type, i, pin.name) |
| |
| self.pins.append( |
| Pin( |
| name=name, |
| direction=pin.direction, |
| attrib=pin.attrib |
| ) |
| ) |
| |
| # Add the fake constant connection pin if marked |
| if self.fake_const_pin: |
| self.pins.append( |
| Pin( |
| name="FAKE_CONST", direction=PinDirection.INPUT, attrib={} |
| ) |
| ) |
| |
| |
| """ |
| A tile instance within a tilegrid |
| |
| type - Tile type |
| name - Tile instance name |
| cells - A list of Cell objects |
| """ |
| Tile = namedtuple("Tile", "type name cells") |
| |
| # ============================================================================= |
| |
| |
| class SwitchboxPinType(Enum): |
| """ |
| Switchbox pin types. |
| """ |
| UNSPEC = 0 # Unknown. |
| LOCAL = 1 # Connects to the tile at the same location as the switchbox. |
| HOP = 2 # Generic hop, connects to another switchbox. |
| GCLK = 3 # Connects to the global clock network. |
| CONST = 4 # Connects to the global const network. |
| FOREIGN = 5 # Connects to a tile at a different location. |
| |
| |
| """ |
| A location that identifies a pin inside a switchbox. |
| |
| stage_id - Stage id |
| switch_id - Switch id within the stage |
| mux_id - Mux id within the switch |
| pin_id - Pin id of the mux |
| pin_direction - Logical direction of the pin |
| """ |
| SwitchboxPinLoc = namedtuple( |
| "SwitchboxPinLoc", "stage_id switch_id mux_id pin_id pin_direction" |
| ) |
| """ |
| A top-level switchbox pin. |
| |
| in - Pin id. |
| name - Pin name |
| direction - Pin direction. |
| locs - A list of SwitchboxPinLoc objects representing connections to |
| switches within the switchbox. |
| type - The pin type as according to SwitchboxPinType |
| """ |
| SwitchboxPin = namedtuple("SwitchboxPin", "id name direction locs type") |
| """ |
| A switch pin within a switchbox |
| |
| id - Pin id. |
| name - Pin name. Only for top-level pins. For others is None. |
| direction - Pin direction. |
| """ |
| SwitchPin = namedtuple("SwitchPin", "id name direction") |
| """ |
| A connection within a switchbox |
| |
| src - Source location (always an output pin) |
| dst - Destination location (always an input pin) |
| """ |
| SwitchConnection = namedtuple("SwitchConnection", "src dst") |
| """ |
| Sink timing |
| |
| tdel - Constant propagation delay. |
| c - Load capacitance. |
| vpr_switch - VPR switch name |
| """ |
| SinkTiming = namedtuple("SinkTiming", "tdel c vpr_switch") |
| """ |
| Driver timing |
| |
| tdel - Constant propagation delay. |
| r - Driver resitance. |
| vpr_switch - VPR switch name |
| """ |
| DriverTiming = namedtuple("DriverTiming", "tdel r vpr_switch") |
| """ |
| Mux edge timing data |
| |
| driver - Driver parameters |
| sink - Sink parameters |
| """ |
| MuxEdgeTiming = namedtuple("MuxEdgeTiming", "driver sink") |
| |
| # ============================================================================= |
| |
| |
| class Switchbox(object): |
| """ |
| This class holds information about a routing switchbox of a particular type. |
| |
| A switchbox is implemented in CLOS architecture. It contains of multiple |
| "stages". Outputs of previous stage go to the next one. A stage contains |
| multiple switches. Each switch is a small M-to-N routing box. |
| """ |
| |
| class Mux(object): |
| """ |
| An individual multiplexer inside a switchbox |
| """ |
| |
| def __init__(self, id, switch): |
| self.id = id # The mux ID |
| self.switch = switch # Parent switch od |
| self.inputs = {} # Input pins by their IDs |
| self.output = None # The output pin |
| self.timing = {} # Input timing (per input) |
| |
| @property |
| def pins(self): |
| """ |
| Yields all pins of the mux |
| """ |
| for pin in self.inputs.values(): |
| yield pin |
| |
| yield self.output |
| |
| class Switch(object): |
| """ |
| This is a sub-switchbox of a switchbox stage. |
| """ |
| |
| def __init__(self, id, stage): |
| self.id = id # The switch ID |
| self.stage = stage # Parent stage id |
| self.muxes = {} # Muxes by their IDs |
| |
| @property |
| def pins(self): |
| """ |
| Yields all pins of the switch |
| """ |
| for mux in self.muxes.values(): |
| yield from mux.pins |
| |
| class Stage(object): |
| """ |
| Represents a routing stage which has some attributes and consists of |
| a column of Switch objects |
| """ |
| |
| def __init__(self, id, type=None): |
| self.id = id # The stage ID |
| self.type = type # The stage type ("HIGHWAY" or "STREET") |
| self.switches = {} # Switches indexed by their IDs |
| |
| @property |
| def pins(self): |
| """ |
| Yields all pins of the stage |
| """ |
| for switch in self.switches.values(): |
| yield from switch.pins |
| |
| # ............................................................... |
| |
| def __init__(self, type): |
| self.type = type # Switchbox type |
| self.inputs = {} # Top-level inputs by their names |
| self.outputs = {} # Top-level outputs by their names |
| self.stages = {} # Stages by their IDs |
| |
| self.connections = set() # Connections between stages |
| |
| @property |
| def pins(self): |
| """ |
| Yields all pins of the switchbox |
| """ |
| for pin in self.inputs.values(): |
| yield pin |
| for pin in self.outputs.values(): |
| yield pin |
| |
| |
| # ============================================================================= |
| """ |
| A global clock network cell |
| |
| type - Cell type. |
| name - Cell name. |
| loc - Location in the grid. |
| quadrant - Clock quadrant |
| pin_map - A dict with mapping of cell pins to switchbox pins. |
| """ |
| ClockCell = namedtuple("ClockCell", "type name loc quadrant pin_map") |
| |
| # ============================================================================= |
| |
| |
| class ConnectionType(Enum): |
| """ |
| Connection endpoint type |
| """ |
| UNSPEC = 0 # Unspecified |
| SWITCHBOX = 1 # Connection to a pin of a switchbox |
| TILE = 2 # Connection to a pin of a tile |
| CLOCK = 3 # Connection to a global clock network cell modelled using |
| # routing resources only. |
| |
| |
| # A connection endpoint location. Specifies location, pin name and connection |
| # type. |
| ConnectionLoc = namedtuple("ConnectionLoc", "loc pin type") |
| |
| # A connection within the tilegrid |
| Connection = namedtuple("Connection", "src dst is_direct") |
| |
| # ============================================================================= |
| """ |
| A package pin. Holds information about what cells the pin cooresponds to and |
| where it is in the tilegrid. |
| |
| name - The pin name |
| alias - Alias |
| loc - Location in the physical FPGA gric |
| cell - Cell object that the package pin correspond to |
| """ |
| PackagePin = namedtuple("PackagePin", "name alias loc cell") |
| |
| # ============================================================================= |
| |
| # VPR segment |
| VprSegment = namedtuple("VprSegment", "name length r_metal c_metal") |
| |
| # VPR switch |
| VprSwitch = namedtuple("VprSwitch", "name type t_del r c_in c_out c_int") |