|  | 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. |