Skip to content

Commit d5192c1

Browse files
authored
Merge branch 'master' into yosys_plugins_docs
2 parents d900c7a + b913727 commit d5192c1

22 files changed

+1407
-9
lines changed

vpr/src/base/SetupVPR.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@ static void SetupNocOpts(const t_options& Options, t_noc_opts* NocOpts) {
668668
// assign the noc specific options from the command line
669669
NocOpts->noc = Options.noc;
670670
NocOpts->noc_flows_file = Options.noc_flows_file;
671+
NocOpts->noc_routing_algorithm = Options.noc_routing_algorithm;
671672

672673
return;
673674
}

vpr/src/base/ShowSetup.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,6 @@ static void ShowPackerOpts(const t_packer_opts& PackerOpts) {
771771

772772
static void ShowNocOpts(const t_noc_opts& NocOpts) {
773773
VTR_LOG("NocOpts.noc_flows_file: %s\n", NocOpts.noc_flows_file.c_str());
774+
VTR_LOG("NocOpts.noc_routing_algorithm: %s\n", NocOpts.noc_routing_algorithm.c_str());
774775
VTR_LOG("\n");
775-
776-
// add future options here (routing algorithm etc...)
777776
}

vpr/src/base/read_options.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2635,6 +2635,15 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
26352635
.default_value("")
26362636
.show_in(argparse::ShowIn::HELP_ONLY);
26372637

2638+
noc_grp.add_argument<std::string>(args.noc_routing_algorithm, "--noc_routing_algorithm")
2639+
.help(
2640+
"Controls the algorithm used by the NoC to route packets.\n"
2641+
"* xy_routing: Uses the direction oriented routing algorithm. This is recommended to be used with mesh NoC topologies.\n"
2642+
"* bfs_routing: Uses the breadth first search algorithm. The objective is to find a route that uses a minimum number of links.\n"
2643+
"This can be used with any NoC topology\n")
2644+
.default_value("bfs_routing")
2645+
.show_in(argparse::ShowIn::HELP_ONLY);
2646+
26382647
return parser;
26392648
}
26402649

vpr/src/base/read_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ struct t_options {
142142
/*NoC Options*/
143143
argparse::ArgValue<bool> noc;
144144
argparse::ArgValue<std::string> noc_flows_file;
145+
argparse::ArgValue<std::string> noc_routing_algorithm;
145146

146147
/* Timing-driven placement options only */
147148
argparse::ArgValue<float> PlaceTimingTradeoff;

vpr/src/base/vpr_api.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "setup_clocks.h"
4141
#include "setup_noc.h"
4242
#include "read_xml_noc_traffic_flows_file.h"
43+
#include "noc_routing_algorithm_creator.h"
4344
#include "stats.h"
4445
#include "read_options.h"
4546
#include "echo_files.h"
@@ -527,6 +528,8 @@ void vpr_setup_noc(const t_vpr_setup& vpr_setup, const t_arch& arch) {
527528
setup_noc(arch);
528529
// read and store the noc traffic flow information
529530
read_xml_noc_traffic_flows_file(vpr_setup.NocOpts.noc_flows_file.c_str());
531+
// create the NoC routing algorithm based on the user input
532+
vpr_setup_noc_routing_algorithm(vpr_setup.NocOpts.noc_routing_algorithm);
530533

531534
#ifndef NO_GRAPHICS
532535
// setup the graphics
@@ -538,6 +541,23 @@ void vpr_setup_noc(const t_vpr_setup& vpr_setup, const t_arch& arch) {
538541
}
539542
}
540543

544+
/**
545+
* @brief Constructs a NoC routing algorithm that is identified by a user
546+
* provided string. Then the newly created routing algorithm is stored
547+
* inside the global NoC context.
548+
*
549+
* @param noc_routing_algorithm_name A user provided string that identifies a
550+
* NoC routing algorithm
551+
*/
552+
void vpr_setup_noc_routing_algorithm(std::string noc_routing_algorithm_name) {
553+
// Need to be abke to modify the NoC context, since we will be adding the
554+
// newly created routing algorithm to it
555+
auto& noc_ctx = g_vpr_ctx.mutable_noc();
556+
557+
noc_ctx.noc_flows_router = NocRoutingAlgorithmCreator().create_routing_algorithm(noc_routing_algorithm_name);
558+
return;
559+
}
560+
541561
bool vpr_pack_flow(t_vpr_setup& vpr_setup, const t_arch& arch) {
542562
auto& packer_opts = vpr_setup.PackerOpts;
543563

@@ -1134,6 +1154,13 @@ static void free_routing() {
11341154
routing_ctx.net_status.clear();
11351155
routing_ctx.route_bb.clear();
11361156
}
1157+
/**
1158+
* @brief handles the deletion of NoC related datastructures.
1159+
*/
1160+
static void free_noc() {
1161+
auto& noc_ctx = g_vpr_ctx.mutable_noc();
1162+
delete noc_ctx.noc_flows_router;
1163+
}
11371164

11381165
void vpr_free_vpr_data_structures(t_arch& Arch,
11391166
t_vpr_setup& vpr_setup) {
@@ -1145,6 +1172,7 @@ void vpr_free_vpr_data_structures(t_arch& Arch,
11451172
free_placement();
11461173
free_routing();
11471174
free_atoms();
1175+
free_noc();
11481176
}
11491177

11501178
void vpr_free_all(t_arch& Arch,

vpr/src/base/vpr_api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ void vpr_close_graphics(const t_vpr_setup& vpr_setup);
128128
void vpr_setup_clock_networks(t_vpr_setup& vpr_setup, const t_arch& Arch);
129129

130130
void vpr_setup_noc(const t_vpr_setup& vpr_setup, const t_arch& arch);
131+
void vpr_setup_noc_routing_algorithm(std::string noc_routing_algorithm_name);
131132

132133
void vpr_free_vpr_data_structures(t_arch& Arch, t_vpr_setup& vpr_setup);
133134
void vpr_free_all(t_arch& Arch, t_vpr_setup& vpr_setup);

vpr/src/base/vpr_context.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "vpr_constraints.h"
3030
#include "noc_storage.h"
3131
#include "noc_traffic_flows.h"
32+
#include "noc_routing.h"
3233

3334
/**
3435
* @brief A Context is collection of state relating to a particular part of VPR
@@ -462,7 +463,7 @@ struct NocContext : public Context {
462463
*
463464
* Contains all the routers and links that make up the NoC. The routers contain
464465
* information regarding the physical tile positions they represent. The links
465-
* define the connections between every router (ropology) and also metrics that describe its
466+
* define the connections between every router (topology) and also metrics that describe its
466467
* "usage".
467468
*
468469
*
@@ -479,6 +480,15 @@ struct NocContext : public Context {
479480
* This is created from a user supplied .flows file.
480481
*/
481482
NocTrafficFlows noc_traffic_flows_storage;
483+
484+
/**
485+
* @brief Contains the packet routing algorithm used by the NoC.
486+
*
487+
* This should be used to route traffic flows within the NoC.
488+
*
489+
* This is created from a user supplied command line option "--noc_routing_algorithm"
490+
*/
491+
NocRouting* noc_flows_router;
482492
};
483493

484494
/**

vpr/src/base/vpr_types.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,8 +1260,9 @@ struct t_analysis_opts {
12601260

12611261
// used to store NoC specific options, when supplied as an input by the user
12621262
struct t_noc_opts {
1263-
bool noc; ///<options to turn on hard NoC modeling & optimization
1264-
std::string noc_flows_file; ///<name of the file that contains all the traffic flow information in the NoC
1263+
bool noc; ///<options to turn on hard NoC modeling & optimization
1264+
std::string noc_flows_file; ///<name of the file that contains all the traffic flow information in the NoC
1265+
std::string noc_routing_algorithm; ///<controls the routing algorithm used to route packets within the NoC
12651266
};
12661267

12671268
/**

vpr/src/noc/bfs_routing.cpp

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#
2+
3+
#include "bfs_routing.h"
4+
5+
BFSRouting::~BFSRouting() {}
6+
7+
void BFSRouting::route_flow(NocRouterId src_router_id, NocRouterId sink_router_id, std::vector<NocLinkId>& flow_route, const NocStorage& noc_model) {
8+
const NocRouter src_router = noc_model.get_single_noc_router(src_router_id);
9+
const NocRouter sink_router = noc_model.get_single_noc_router(sink_router_id);
10+
11+
// destroy any previously stored route
12+
flow_route.clear();
13+
14+
/**
15+
* Keeps track of which routers have been reached already
16+
* while traversing the NoC. This variable will help prevent
17+
* the algorithm from getting stuck visiting routers that
18+
* jave already been visited.
19+
*
20+
*/
21+
std::unordered_set<NocRouterId> visited_routers;
22+
23+
/*
24+
* As the routing goes through the NoC, each router visited has a
25+
* corresponding link that was used to reach the router. This
26+
* datastructure stores the link that was used to visit each router in
27+
* the NoC.
28+
* Once the destination router has been found. This datastructure can be used to
29+
* trace the path back to the source router.
30+
*/
31+
std::unordered_map<NocRouterId, NocLinkId> router_parent_link;
32+
33+
std::queue<NocRouterId> routers_to_process;
34+
35+
// indicates whether the routing algorithm found the destination router. If the destination
36+
// router was not found then this means no route exists between the source and destination router.
37+
bool found_sink_router = false;
38+
39+
// Start by processing the source router of the flow
40+
routers_to_process.push(src_router_id);
41+
visited_routers.insert(src_router_id);
42+
43+
//handle case where the source and sink router of the flow are the same
44+
if (src_router_id == sink_router_id) {
45+
found_sink_router = true;
46+
}
47+
48+
// Explore the NoC from the starting router and try to find a path to the destination router
49+
// We finish searching when there are no more routers to process or we found the destination router
50+
while (!routers_to_process.empty() && !found_sink_router) {
51+
// get the next router to process
52+
NocRouterId processing_router = routers_to_process.front();
53+
routers_to_process.pop();
54+
55+
// get the links leaving the router currently being processed(these represent possible paths to explore in the NoC)
56+
const std::vector<NocLinkId> outgoing_links = noc_model.get_noc_router_connections(processing_router);
57+
58+
// go through the outgoing links of the current router and process the sink routers connected to these links
59+
for (auto link : outgoing_links) {
60+
// get the router connected to the current outgoing link
61+
NocRouterId connected_router = noc_model.get_single_noc_link(link).get_sink_router();
62+
63+
// check if we already explored the router we are visiting
64+
if (visited_routers.find(connected_router) == visited_routers.end()) {
65+
// if we are here then this is the first time visiting this router //
66+
// mark this router as visited and add send the router to be processed
67+
visited_routers.insert(connected_router);
68+
routers_to_process.push(connected_router);
69+
70+
// set the parent link of this router (link used to visit the router) as the current outgoing link
71+
router_parent_link.insert(std::pair<NocRouterId, NocLinkId>(connected_router, link));
72+
73+
// check if the router visited is the destination router
74+
if (connected_router == sink_router_id) {
75+
// mark that the destination router has been found
76+
found_sink_router = true;
77+
// no need to process any more routers
78+
break;
79+
}
80+
}
81+
}
82+
}
83+
84+
// check if the above search found a valid path from the source to the destination
85+
// router.
86+
if (found_sink_router) {
87+
// a legal path was found, so construct it
88+
generate_route(sink_router_id, flow_route, noc_model, router_parent_link);
89+
} else {
90+
// a path was not found so throw an error to the user
91+
VPR_FATAL_ERROR(VPR_ERROR_OTHER, "No route could be found from starting router with id:'%d' and the destination router with id:'%d' using the breadth-first search routing algorithm.", src_router.get_router_user_id(), sink_router.get_router_user_id());
92+
}
93+
94+
return;
95+
}
96+
97+
void BFSRouting::generate_route(NocRouterId start_router_id, std::vector<NocLinkId>& flow_route, const NocStorage& noc_model, const std::unordered_map<NocRouterId, NocLinkId>& router_parent_link) {
98+
// The intermediate router being visited while tracing the path back from the destination router to the starting router in the flow.
99+
// Initially this is set to the router at the end of the path (destination router)
100+
NocRouterId curr_intermediate_router = start_router_id;
101+
102+
// get a reference to the beginning of the vector that stores the found route of the flow
103+
// need this since each link we find in the path will be added to the beginning of the vector
104+
auto route_beginning = flow_route.begin();
105+
106+
// get the parent link of the start router
107+
std::unordered_map<NocRouterId, NocLinkId>::const_iterator curr_intermediate_router_parent_link = router_parent_link.find(curr_intermediate_router);
108+
109+
// keep tracking baackwards from each router in the path until a router doesn't have a parent link (this means we reached the starting router in the flow)
110+
while (curr_intermediate_router_parent_link != router_parent_link.end()) {
111+
// add the parent link to the path. Since we are tracing backwards we need to store the links in fron of the last link.
112+
flow_route.emplace(route_beginning, curr_intermediate_router_parent_link->second);
113+
114+
// update the reference to the beginning of the route
115+
route_beginning = flow_route.begin();
116+
117+
// now move to the next intermediate router in the path. This will be the source router of the parent link
118+
curr_intermediate_router = noc_model.get_single_noc_link(curr_intermediate_router_parent_link->second).get_source_router();
119+
// now get the parent of the router we moved to
120+
curr_intermediate_router_parent_link = router_parent_link.find(curr_intermediate_router);
121+
}
122+
123+
return;
124+
}

vpr/src/noc/bfs_routing.h

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#ifndef BFS_ROUTING
2+
#define BFS_ROUTING
3+
4+
/**
5+
* @file
6+
* @brief This file defines the BFSRouting class.
7+
*
8+
* Overview
9+
* ========
10+
* The BFSRouting class performs packet routing between physical routers in the
11+
* FPGA. This class is based on the BFS algorithm.
12+
*
13+
* The BFS algorithm is used to explore the NoC from the starting router in the
14+
* traffic flow. Once the destination router is found a path from the source to
15+
* the destination router is generated. The main advantage of this algorithm is
16+
* that the found path from the source to the destination router uses the
17+
* minimum number of links required within the NoC.
18+
*
19+
*/
20+
21+
#include <vector>
22+
#include <unordered_map>
23+
#include <queue>
24+
25+
#include "noc_routing.h"
26+
27+
class BFSRouting : public NocRouting {
28+
public:
29+
~BFSRouting() override;
30+
31+
/**
32+
* @brief Finds a route that goes from the starting router in a
33+
* traffic flow to the destination router. Uses the BFS
34+
* algorithm to determine the route. A route consists of a series
35+
* of links that should be traversed when travelling between two routers
36+
* within the NoC.
37+
*
38+
* @param src_router_id The source router of a traffic flow. Identifies
39+
* the starting point of the route within the NoC. This represents a
40+
* physical router on the FPGA.
41+
* @param sink_router_id The destination router of a traffic flow.
42+
* Identifies the ending point of the route within the NoC.This represents a
43+
* physical router on the FPGA.
44+
* @param flow_route Stores the path returned by this fuction
45+
* as a series of NoC links found by
46+
* a NoC routing algorithm between two routers in a traffic flow.
47+
* The function will clear any
48+
* previously stored path and re-insert the new found path between the
49+
* two routers.
50+
* @param noc_model A model of the NoC. This is used to traverse the
51+
* NoC and find a route between the two routers.
52+
*/
53+
void route_flow(NocRouterId src_router_id, NocRouterId sink_router_id, std::vector<NocLinkId>& flow_route, const NocStorage& noc_model) override;
54+
55+
// internally used helper functions
56+
private:
57+
/**
58+
* @brief Traces the path taken by the BFS routing algorithm from the destination router to the starting router.
59+
* Starting with the destination router, the parent link (link taken to get to this router) is found and is added
60+
* to the path. Then the algorithm moves to the source router of the parent link. Then it repeats the previous process
61+
* of finding the parent link, adding it to the path and moving to the source router. This is repeated until the
62+
* starting router is reached.
63+
*
64+
* @param start_router_id The router to use as a starting point
65+
* when tracing back the route from the destination router.
66+
* to the the starting router. Generally this
67+
* would be the sink router of the flow.
68+
* @param flow_route Stores the path as a series of NoC links found by
69+
* a NoC routing algorithm between two routers in a traffic flow.
70+
* The function will clear any
71+
* previously stored path and re-insert the new found path between the
72+
* two routers.
73+
* @param noc_model A model of the NoC. This is used to traverse the
74+
* NoC and find a route between the two routers.
75+
* @param router_parent_link Contains the parent link associated to each
76+
* router in the NoC (parent link is the link used to visit the router during
77+
* the BFS routing algorithm).
78+
*/
79+
void generate_route(NocRouterId sink_router_id, std::vector<NocLinkId>& flow_route, const NocStorage& noc_model, const std::unordered_map<NocRouterId, NocLinkId>& router_parent_link);
80+
};
81+
82+
#endif

vpr/src/noc/noc_link.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ double NocLink::get_bandwidth_usage(void) const {
2222
}
2323

2424
//setters
25+
void NocLink::set_source_router(NocRouterId source) {
26+
source_router = source;
27+
return;
28+
}
29+
30+
void NocLink::set_sink_router(NocRouterId sink) {
31+
sink_router = sink;
32+
return;
33+
}
34+
2535
void NocLink::set_bandwidth_usage(double new_bandwidth_usage) {
2636
bandwidth_usage = new_bandwidth_usage;
2737
}

0 commit comments

Comments
 (0)