| VPR routing graph | |
| ################# | |
| Database Contents | |
| ================= | |
| This section will describe the prjxray database contents with respect to the routing graph. | |
| Grid | |
| ---- | |
| * Project X-Ray documents one or more **parts**. | |
| * Within a **part** is a **grid**. | |
| * The **grid** is documented in ``tilegrid.json`` and can be accessed via the prjxray API via the | |
| ``prjxray.db.Database.grid`` method. | |
| * Each location within the **grid** is a **tile**, which has a **tile type** and **grid coordinate**. | |
| * Each instance of a **tile type** has the same **sites**, **tile wires**, and **pips**. | |
| A tile type may have zero or more **sites**, zero or more **tile wires** and zero or more **pips**. | |
| **Pips** are programmable interconnect points, and connect two **tile wires** together in a programmatic fashion. | |
| A **tile** may also have a **bits** definition if the output bitstream configures this tile. | |
| A **bits** definition consists of a **block type**, a **base address**, the number of **frames** in the **base address | |
| column**, a **word offset**, and a number of **words**. | |
| Routing fabric | |
| -------------- | |
| Connection schemes | |
| ^^^^^^^^^^^^^^^^^^ | |
| +------------------+------------------+ | |
| | From | To | | |
| +==================+==================+ | |
| | Local Tile Wire | PIP | | |
| +------------------+------------------+ | |
| | Local Tile Wire | Site Pin | | |
| +------------------+------------------+ | |
| | Local Tile Wire | Remote Tile Wire | | |
| +------------------+------------------+ | |
| | Remote Tile Wire | Local Tile Wire | | |
| +------------------+------------------+ | |
| | Site Pin | Local Tile Wire | | |
| +------------------+------------------+ | |
| | PIP | Local Tile Wire | | |
| +------------------+------------------+ | |
| Tile wire | |
| ^^^^^^^^^ | |
| +-----------------+-----------------------------------------------------------+ | |
| | Property | Valid choices | | |
| +=================+===========================================================+ | |
| | connections | - one or more PIPs, and | | |
| | | - one or more Remote Tile Wires, and | | |
| | | - only 1 site pin | | |
| +-----------------+-----------------------------------------------------------+ | |
| PIP | |
| ^^^ | |
| +-----------------+-----------------------------------------------------------+ | |
| | Property | Valid choices | | |
| +=================+===========================================================+ | |
| | src_wire | Local Tile Wire | | |
| +-----------------+-----------------------------------------------------------+ | |
| | dst_wire | Local Tile Wire | | |
| +-----------------+-----------------------------------------------------------+ | |
| | is_directional | True or False | | |
| +-----------------+-----------------------------------------------------------+ | |
| .. figure:: ../../_static/images/prjxray/rrgraph-wire.svg | |
| A 7-Series part contains nodes, which consist of **tile wires**. | |
| **Tile wires** are sourced either from a **site pin** or a **pip** or a **tile wire** from another tile within the grid. | |
| **Tile wires** sink to either a **site pin** or a **pip** or a **tile wire** in another tile within the grid. | |
| **Tile wires** have not been observed to have a source and sink that are both **site pins**. | |
| **Tile wires** that source or sink within a tile are documented in the **tile type** definition, which is found in the | |
| ``tile_type_<tile type>.json`` files. | |
| The **tile type** definition has a list of the **tile wires** within the tile, a list of **pips** and a list of **sites**. | |
| If the **tile wires** source or sink within the tile, then the **tile wire** will appear in either a **pip** or a | |
| **site** definition. | |
| Tile type definitions can be retrieved via ``db.Database.get_tile_type`` method. | |
| All **pip** definitions have a **src_wire** and **dst_wire** keys, indicating what **tile wire** is connected to each | |
| end of the pip. | |
| .. note:: | |
| A bidirectional pip will have the is_directional key set to "0", but use **src_wire** and **dst_wire** as if it was a | |
| unidirectional pip. | |
| Each **site** definition will have a **site_type** and dictionary of **site_pins**, along with site naming information. | |
| The **site_pins** dictionary maps the **site_pin** of the **site_type** to the **tile_wires** within the tile. | |
| The direction of **site_pin** can be found in the **site_type** definition, ``site_type_<site type>.json`` file. | |
| Site type definitions can be retrieved via ``db.Database.get_site_type`` method. | |
| The **tile wires** combined with the tile's **pip** list and the **site_pins** definition for each site completes the | |
| routing description for the tile. | |
| However there needs to be a relationship between **tile wires** from **tiles** to each other. | |
| This is defined in the ``tileconn.json`` file, provides a list of which **tile wires** are connected between **tiles**. | |
| The ``tileconn.json`` relates tile types via their grid coordinates. | |
| Example: | |
| ^^^^^^^^ | |
| .. code-block:: JSON | |
| { | |
| "grid_deltas": [ | |
| 0, | |
| 1 | |
| ], | |
| "tile_types": [ | |
| "CLBLL_L", | |
| "CLBLL_L" | |
| ], | |
| "wire_pairs": [ | |
| [ | |
| "CLBLL_LL_CIN", | |
| "CLBLL_LL_COUT_N" | |
| ], | |
| [ | |
| "CLBLL_L_CIN", | |
| "CLBLL_L_COUT_N" | |
| ] | |
| ] | |
| }, | |
| This reads as "a ``CLBLL_L`` that is at (x+0, y+1) from another ``CLBLL_L``, | |
| - Connect ``CLBLL_L(x, y+1).CLBLL_LL_COUT_N`` to ``CLBLL_L(x, y).CLBLL_LL_CIN`` | |
| - Connect ``CLBLL_L(x, y+1).CLBLL_L_COUT_N`` to ``CLBLL_L(x, y).CLBLL_L_CIN`` | |
| The **tile wire** connections can be retrieved via ``db.Database.get_connections``. | |
| The **tile wire** connections from ``tileconn.json``, and the **pips** and **site pins** from each | |
| ``tile_type_<tile type>.json`` provides a complete routing graph description for a **part** between **sites**. | |
| Routing within sites is done via pb_type architectural XML, and is not documented as part of prjxray at this time. | |
| VPR routing description | |
| ======================= | |
| The previous section documented the contents of the prjxray database. | |
| Prior to describing the process of converting that database into VPR, a short discussion of the VPR routing data | |
| structures is required. | |
| At the most basic level, VPR's routing graph is made of **nodes** and **edges**. | |
| **Edges** are either configurable or static connections between **nodes**. | |
| Static connections are always present. | |
| Configurable connections are selected during routing. | |
| All **edges** must have a **switch**. | |
| A **switch** is used to describe timing information along the edge, and it determines if the switch is configurable or | |
| not. | |
| The two most common types of **switches** are SHORT (electrical short) and MUX. | |
| SHORT is used to join two **nodes** in the routing graph, both logically and for timing purposes. | |
| SHORT's are not configurable. | |
| MUX is roughly equivalent to a **pip**. | |
| It is configurable and is used by the router. | |
| For the purposes of timing, the timing on **nodes** on each side of the pip are seperate. | |
| A PASS_GATE is a **switch** that does not do this isolation. | |
| The detiled description about **switch** types can be found in `VTR documentation <http://docs.verilogtorouting.org/en/latest/arch/reference/#arch-switches>`__. | |
| .. figure:: ../../_static/images/prjxray/vpr-rrgraph-types.svg | |
| So **edges** connect **nodes** together, but what are the **nodes** themselves? | |
| **Nodes** are either a source/sink (e.g. a **site pin**) or are routing fabric. | |
| VPR models each source or sink as 2 or more nodes. | |
| The **site pin** is a SINK or SOURCE. | |
| To accommodate the idea that a **site pin** might have multiple routing paths, the SINK or SOURCE then is connected to a | |
| IPIN or OPIN respectively. | |
| Then IPIN's/OPIN's are connected to other nodes. | |
| So by default, all IPIN's connect to exactly one SINK, and all SOURCE's connect to exactly one OPIN. | |
| There are two routing fabric node types, CHANX and CHANY. | |
| CHANX are wires that traverse in the x-direction and CHANY are wires that traverse in the y-direction. | |
| Channels lies between tiles (see `this image <http://docs.verilogtorouting.org/en/latest/_images/fpga_coordinate_system.png>`__ | |
| from the `VPR routing graph description documentation <http://docs.verilogtorouting.org/en/latest/vpr/file_formats/>`__). | |
| Channels cannot extended to the first or last column in the grid. | |
| IPIN's and OPIN's have a direction that they point in relative to the tile they belong too. | |
| They can be on the north, east, west, south, or some combination. | |
| For example, in the image above, a pin at (1, 2) on the east side could connect to CHANY nodes at (1,2). | |
| Creating a 7-series routing graph for VPR | |
| ========================================= | |
| In order to create a routing graph for VPR, several new things must be defined: | |
| * How to map the routing **tile wires** into VPR channels or other constructs? | |
| :ghsrc:`prjxray_form_channels.py <xc7/utils/prjxray_form_channels.py>` | |
| * Which side of the tile should **site pins** be assigned to connect to other tiles (in the case of direct connections | |
| like carry chains) and to VPR channels? | |
| :ghsrc:`prjxray_assign_tile_pin_direction.py <xc7/utils/prjxray_assign_tile_pin_direction.py>` | |
| After the preparation work, output can be generated for VPR. | |
| Three types of output are generated: | |
| * Tile pb_types XML's that connect site pb_types **site pins** to **tile wires** | |
| :ghsrc:`prjxray_tile_import.py <xc7/utils/prjxray_tile_import.py>` | |
| * Architecture XML that is the grid and has direct inter-tile connections | |
| :ghsrc:`prjxray_arch_import.py <xc7/utils/prjxray_arch_import.py>` | |
| * Final routing graph XML | |
| :ghsrc:`prjxray_routing_import.py <xc7/utils/prjxray_routing_import.py>` | |
| Click on the figure below to zoom-in: | |
| .. thumbnail:: ../../_static/images/prjxray/import-flow.png | |
| This diagram shows the importing flow for Project X-Ray. | |
| Tile wire classification | |
| ------------------------ | |
| Before channels can be formed, **tile wires** need to be bucketed into | |
| their purpose. | |
| Step (1) - Group tile wires into “nodes” | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| The first step is to first re-form nodes that contain all the directly connected **tiles wires**. | |
| These nodes are *not* VPR **nodes**, they are simply the collection of **tile wires** that are already a net | |
| (electrically equivalent). | |
| Step (2) - Classify “nodes” | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| Each node then needs to be classified. | |
| The simplest classification is a channel wire, which means that **pips** route on and off of the node. | |
| However there are other important classifications. | |
| For example, the carry chain connection between two CLBLL_L tiles should be modelled as a tile direct connection, | |
| rather than routing onto a channel and back off. | |
| The is classified as a "edge with mux". | |
| The classification is broken down into the following categories: | |
| * CHANNEL - **Pips** route on and off of this node. | |
| * EDGE_WITH_MUX - Two **tile wires** connected by a **pip**. | |
| * The first **tile wire** sources at a **site pin**, and the second **tile wire** sinks at a **site pin**. | |
| * This captures direct inter-tile connections like carry chain wires, BRAM data cascade wires, etc. | |
| * NULL - A node that has either no source or no sink. | |
| This wires typically occur near the edge of the grid. | |
| * EDGES_TO_CHANNEL - A node that sources and sinks from a **site pin** and connects via a **pip** to a CHANNEL | |
| .. figure:: ../../_static/images/prjxray/import-wire-class.svg | |
| There is another classification EDGE_WITH_SHORT, which is a direct connection between two **site pins**. | |
| This does not appear to occur in 7-series parts. | |
| The reason this classification is important is that each node that is a CHANNEL must be mapped into one or more CHANX or | |
| CHANY **nodes**. | |
| EDGE_WITH_MUX nodes must be converted into root level architecture direct connections, and will be **edges** between two | |
| **site pin** nodes. | |
| EDGES_TO_CHANNEL will be become **edges** in the routing between **site pins nodes** and CHANX/CHANY **nodes**. | |
| Channel formation | |
| ----------------- | |
| All nodes that were classified as CHANNEL type need to assigned CHANX and CHANY dimensions. | |
| This is done via :ghsrc:`make_tracks <utils/lib/rr_graph/tracks.py>`. | |
| make_tracks takes a point bag containing all of the source and sink grid locations for a particular channel. | |
| It returns straight lines such that all sources and sink grid locations can route on to or off of the channel. | |
| Point Bag to CHANX / CHANY decomposition | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| .. figure:: ../../_static/images/prjxray/vtr-rrgraph.png | |
| :width: 100% | |
| .. note:: | |
| Currently this logic does not optimize for the lowest required track count, instead aiming to be correct first. | |
| Pin assignment | |
| -------------- | |
| Because the pin directions are shared among tile types via the root pb_type that matches the tile, pin directions must | |
| be assigned taking into account the wire type attached to each **site pin** within the tile. | |
| For example, EDGE_WITH_MUX pins must be facing each other. | |
| EDGES_TO_CHANNEL pins must face a direction that contains their channel, per the tracks defined during channel formation. | |
| Once pins are assigned, during tile generation, the pin assignments are used to ensure that pins can be connected into | |
| the routing graph as expected. | |
| Tile pb_type and root architecture XML | |
| -------------------------------------- | |
| The tile type pb_type XML files are emitted using the information from **tile type**, and the pin direction assignment. | |
| The root architecture XML is emitted using the tile **grid**, the direct inter-tile connections from node classification. | |
| Routing import | |
| -------------- | |
| Routing import starts with the virtual routing graph from the architecture XML. | |
| This routing graph will have correct **nodes** for IPIN, OPIN, SOURCE, and SINK types. | |
| However the CHANX and CHANY **nodes**, and the **edges** to and from the CHANX and CHANY **nodes** will be incorrect. | |
| So the first step is to copy the portions of the virtual routing graph that are correct (block types, grid definition, | |
| **nodes** and **edges** belong to IPIN, OPIN, SOURCE, SINK). | |
| Then channels are emitted to accommodate the tracks made during channel formation. | |
| Each track in channel formation is a new **node** of type CHANX or CHANY. | |
| If a node is a CHANNEL with multiple tracks, then a SHORT **edge** is emitted to connect the CHANX's and CHANY's | |
| together, making VPR treat them as electrically common. | |
| Each **pip** in the **grid** is then matched with **src** and **sink** **nodes**, if possible. | |
| When **pips** are added to the routing graph, they also have FASM metadata to enable the **pip** in the bitstream. | |
| .. note:: | |
| As of 2020-03-26 - Not all pips will be emitted. | |
| The current reasons are: | |
| * Don’t currently support PIPs which connect the same src and destinations with the same switch. | |
| On the ROI and synthetic tiles | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| To avoid requiring support for IOB and clock networks for initial bringup activities, an ROI harness is used. | |
| The ROI harness brings some input/output signals to specific **tile wires** within the routing graph, including a clock | |
| source. | |
| During root architecture and routing import, synthetic tiles are generated that present the ROI harness sink or source, | |
| and have either an IPAD or OPAD. | |
| These tiles are purely synthetic, and are only used to describe the source or sink location within the routing graph to | |
| VPR of the ROI harness signals. | |
| Several modifications to the standard flow are required to support the ROI and synthetics. | |
| First, **nodes** that contain **tile wires** are restricted to being either "input only" or "output only" depending on | |
| whether the synthetic tile is a clock, in pad or out pad. | |
| On "input only", all **pip** that would sink to that **node** are skipped. | |
| On "output only", all **pip** that would source from that **node** are skipped. | |
| Then a new synthetic **edge** is added connected a synthetic IPAD or OPAD tile to the relevant **node**. | |
| VPR can then route to or from this **node** just as if it was a actually IPAD or OPAD. |