NoC Storage

NocStorage

This file defines the NocStorage class.

Overview

The NocStorage class represents the model of the embedded NoC in the FPGA device. The model describes the topology of the NoC, its placement on the FPGA and properties of the NoC components. The NocStorage consists of two main components, which are routers and links. The routers and links can be accessed to retrieve information about them using unique identifier (NocRouterId, NocLinkId). Each router and link modelled in the NoC has a unique ID.

Router

A router is component of the NoC and is defined by the NocRouter class. Routers are represent physical FPGA tiles and represent entry and exit points to and from the NoC.

Link

A link is a component of the NoC and is defined by the NocLink class. Links are connections between two routers. Links are used by routers to communicate with other routers in the NoC. They can be thought of as edges in a graph. Links have a source router where they exit from and sink router where they enter. It is important to note that the links are not bi-directional; the legal way to traverse a link is from the source router of the link to the sink router.

class NocStorage
#include <noc_storage.h>

Public Functions

NocStorage()
const std::vector<NocLinkId> &get_noc_router_connections(NocRouterId id) const

Gets a vector of outgoing links for a given router in the NoC. THe link vector cannot be modified.

Parameters:

id – A unique identifier that represents a router

Returns:

A vector of links. The links are represented by a unique identifier.

const vtr::vector<NocRouterId, NocRouter> &get_noc_routers(void) const

Get all the routers in the NoC. The routers themselves cannot be modified. This function should be used to when information on all routers is needed.

Returns:

A vector of routers.

int get_number_of_noc_routers(void) const
Returns:

An integer representing the total number of routers within the NoC.

const vtr::vector<NocLinkId, NocLink> &get_noc_links(void) const

Get all the links in the NoC. The links themselves cannot be modified. This function should be used when information on every link is needed.

Returns:

A vector of links.

vtr::vector<NocLinkId, NocLink> &get_mutable_noc_links(void)

Get all the links in the NoC. The links themselves can be modified. This function should be used when information on every link needs to be modified.

Returns:

A vector of links.

int get_number_of_noc_links(void) const
Returns:

An integer representing the total number of links within the NoC.

Get the maximum allowable bandwidth for a link within the NoC.

Returns:

a numeric value that represents the link bandwidth in bps

Get the latency of traversing through a link in the NoC.

Returns:

a numeric value that represents the link latency in seconds

double get_noc_router_latency(void) const

Get the latency of traversing through a router in the NoC.

Returns:

a numeric value that represents the router latency in seconds

const NocRouter &get_single_noc_router(NocRouterId id) const

Given a unique router identifier, get the corresponding router within the NoC. The router cannot be modified, so the intended use of this function is to retrieve information about a specific router.

Parameters:

id – A unique router identifier.

Returns:

A router (NocRouter) that is identified by the given id.

NocRouter &get_single_mutable_noc_router(NocRouterId id)

Given a unique router identifier, get the corresponding router within the NoC. The router can be modified, so the intended use of this function is to retrieve a router to modify it.

Parameters:

id – A unique router identifier.

Returns:

A router (NocRouter) that is identified by the given id.

const NocLink &get_single_noc_link(NocLinkId id) const

Given a unique link identifier, get the corresponding link within the NoC. The link cannot be modified, so the intended use of this function is to retrieve information about a specific link.

Parameters:

id – A unique link identifier.

Returns:

A link (NocLink) that is identified by the given id.

Given source and sink router identifiers, this function finds a link connecting these routers and returns its identifier. If such a link does not exist, an invalid id is returned. The function is not optimized for performance as it has a complexity of O(N_links).

Parameters:
  • src_router – The unique router identifier for the source router.

  • dst_router – The unique router identifier for the destination router.

Returns:

A link identifier (NocLinkId) that connects the source router to the destination router. NocLinkId::INVALID() is such a link is not found.

NocLink &get_single_mutable_noc_link(NocLinkId id)

Given a unique link identifier, get the corresponding link within the NoC. The link can be modified, so the intended use of this function is tis to retrieve a link to modify it.

Parameters:

id – A unique link identifier.

Returns:

A link (NocLink) that is identified by the given id.

NocRouterId get_router_at_grid_location(const t_pl_loc &hard_router_location) const

Given a grid location of a hard router block on the FPGA device this function determines the id of the hard router block positioned on that grid location.

Parameters:

hard_router_location – A struct that contains the grid location of an arbitrary hard router block on the FPGA.

Returns:

NocRouterId The hard router block “id”

located at the given grid location.

void add_router(int id, int grid_position_x, int grid_position_y, int layer_poisition)

Creates a new router and adds it to the NoC. When the router is created, its corresponding internal id (NocRouterId) is also created and a conversion between the user supplied id to the internal id is setup. If “finish_building_noc()” was called then calling this function after will throw an error as the NoC cannot be modified after building the NoC.

Parameters:
  • id – The user supplied identification for the router.

  • grid_position_x – The horizontal position on the FPGA of the physical tile that this router represents.

  • grid_position_y – The vertical position on the FPGA of the physical tile that this router represents.

void add_link(NocRouterId source, NocRouterId sink)

Creates a new link and adds it to the NoC. The newly created links internal id (NocLinkId) is then added to the vector of outgoing links of its source router. If “finish_building_noc()” was called then calling this function after will throw an error as the NoC cannot be modified after building the NoC.

Parameters:
  • source – A unique identifier for the router that the new link exits from (outgoing from the router)

  • sink – A unique identifier for the router that the new link enters into (incoming to the router)

Set the maximum allowable bandwidth for a link within the NoC.

Set the latency of traversing through a link in the NoC.

void set_noc_router_latency(double router_latency)

Set the latency of traversing through a router in the NoC.

void set_device_grid_width(int grid_width)

Set the internal reference to the device grid width.

void set_device_grid_spec(int grid_width, int grid_height)
bool remove_link(NocRouterId src_router_id, NocRouterId sink_router_id)

The link is removed from the outgoing vector of links for the source router. The link is not removed from the vector of all links as this will require a re-indexing of all link ids. Instead, the link is set to being invalid by. The link is still removed since it will be considered invalid when used externally. THe link is identified by going through the vector outgoing links of the supplied source router, for each outgoing link the sink router is compared the supplied sink router and the link to remove is identified if there is a match. If the link doesn’t exist in the NoC then a warning message is printed and a boolean status is updated indicating that the link does not exist in the NoC.

Parameters:
  • src_router_id – The source router of the traffic flow to delete

  • sink_router_id – The sink router of the traffic flow to delete

Returns:

true The link was successfully removed

Returns:

false The link was not removed

void finished_building_noc(void)

Asserts an internal flag which represents that the NoC has been built. This means that no changes can be made to the NoC (routers and links cannot be added or removed). This function should be called after building the NoC. Guarantees that no future changes can be made.

void clear_noc(void)

Resets the NoC by clearing all internal datastructures. This includes deleting all routers and links. Also all internal IDs are removed (the is conversion table is cleared). It is recommended to run this function before building the NoC.

NocRouterId convert_router_id(int id) const

Given a user id of a router, this function converts the id to the equivalent internal NocRouterId. If there were no routers in the NoC with the given id an error is thrown.

Parameters:

id – The user supplied identification for the router.

Returns:

The equivalent internal NocRouterId.

The datastructure that stores the outgoing links to each router is an 2-D Vector. When processing the links, they can be outgoing from any router in the NoC. Therefore the column size of the 2-D vector needs to be the size of the number of routers in the NoC. The function below sets the column size to the number of routers in the NoC.

NocLinkId get_parallel_link(NocLinkId current_link) const

Two links are considered parallel when the source router of one link is the sink router of the second link and when the sink router of one link is the source router of the other link. Given a link, this functions finds a parallel link, if no link is found then an invalid link is returned.

Example:

----------                       ----------
/        /        link 1         /        /
/ router / --------------------->/ router /
/   a    / <---------------------/   b    /
/        /        link 2         /        /
/--------/                       /--------/
In the example above, link 1 and link 2 are parallel.

Parameters:

current_link – A unique identifier that represents a link

Returns:

NocLinkId An identifier that represents a link that is parallel to the input link.

int generate_router_key_from_grid_location(int grid_position_x, int grid_position_y, int layer_position) const

Generates a unique integer using the x and y coordinates of a hard router block that can be used to identify it. This should be used to generate the keys for the ‘grid_location_to_router_id’ datastructure.

The key will be generated as follows: key = y * device_grid.width() + x

Parameters:
  • grid_position_x – The horizontal position on the FPGA of the physical tile that this router represents.

  • grid_position_y – The vertical position on the FPGA of the phyical tile that this router represents.

  • layer_position – The layer number of the phyical tile that this router represents.

Returns:

int Represents a unique key that can be used to identify a hard router block.

void echo_noc(char *file_name) const

Writes out the NocStorage class information to a file. This includes the list of routers and their connections to other routers in the NoC.

Parameters:

file_name – The name of the file that contains the NoC model info.

Private Functions

NocStorage(const NocStorage&) = delete
void operator=(const NocStorage&) = delete

Private Members

vtr::vector<NocRouterId, NocRouter> router_storage

Contains all the routers in the NoC

Stores outgoing links for each router in the NoC. These links can be used by the router to communicate to other routers in the NoC.

Contains all the links in the NoC

std::unordered_map<int, NocRouterId> router_id_conversion_table

The user provides an ID for the router when describing the NoC in the architecture file. This ID system will be different than the NocRouterIds assigned to each router. The user ID system will be arbitrary but the internal ID system used here will start at 0 and are dense since it is used to index the routers. The datastructure below is a conversiont able that maps the user router IDs to the corresponding internal ones.

std::unordered_map<int, NocRouterId> grid_location_to_router_id

Associates the hard (physical) routers on the device to their grid location. During placement, when logical routers are moved to different hard routers, only the grid location of where the logical router was moved is known. Using this datastructure, the grid location can be used to identify the corresponding hard router block positioned at that grid location. The NocROuterId uniquely identifies hard router blocks and can be used to retrieve the hard router block information using the router_storage data structure above. This can also be used to access the connectivity graph datastructure above.

It is important to know the specific hard router block because without it we cannot determine the starting/end points of the traffic flows associated to the moved logical router. We need this so that we can re-route all traffic flows and evaluate the the placement cost of the moved logical router block.

The intended use is when trying to re-route a traffic flow. The current location of a logical router block can be used in conjunction with this datastructure to identify the corresponding hard router block.

bool built_noc

A flag that indicates whether the NoC has been built. If this flag is true, then the NoC cannot be modified, meaning that routers and links cannot be added or removed. The intended use of this flag is to set it after you complete building the NoC (adding routers and links). This flag can then acts as a check so that the NoC is not modified later on after building it.

Represents the maximum allowed bandwidth for the links in the NoC (in bps)

Represents the delay expected when going through a link (in seconds)

double noc_router_latency

Represents the expected delay when going through a router (in seconds))

int device_grid_width

Internal reference to the device grid width. This is necessary to compute a unique key for a given grid location which we can then use to get the corresponding physical (hard) router at the given grid location using ‘grid_location_to_router_id’.

int layer_num_grid_locs

Internal reference to the number of blocks at each layer (width * height). This is necessary to compute a unique key for a given grid location which we can then use to get the corresponding physical (hard) router at the given grid location using ‘grid_location_to_router_id’.