Skip to content

Commit ff8e7cc

Browse files
authored
Merge pull request #2083 from verilog-to-routing/noc_traffic_flows_parser_final
Noc traffic flows parser final
2 parents 5472be8 + b1f1477 commit ff8e7cc

35 files changed

+2732
-77
lines changed

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4672,7 +4672,7 @@ static void processTopology(pugi::xml_node topology_tag, const pugiutil::loc_dat
46724672
/**
46734673
* Stores router information that includes the number of connections a router has within a given topology and also the number of times a router was declared in the arch file using the <router> tag.
46744674
* In the datastructure below, the router id is the key and the stored data is a pair, where the first element describes the number of router declarations and the second element describes the number of router connections.
4675-
* This is used only for erro checking.
4675+
* This is used only for error checking.
46764676
*/
46774677
std::map<int, std::pair<int, int>> routers_in_arch_info;
46784678

vpr/src/base/SetupVPR.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ static void SetupPowerOpts(const t_options& Options, t_power_opts* power_opts, t
665665
static void SetupNocOpts(const t_options& Options, t_noc_opts* NocOpts) {
666666
// assign the noc specific options from the command line
667667
NocOpts->noc = Options.noc;
668+
NocOpts->noc_flows_file = Options.noc_flows_file;
668669

669670
return;
670671
}

vpr/src/base/ShowSetup.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ static void ShowPlacerOpts(const t_placer_opts& PlacerOpts,
2020
const t_annealing_sched& AnnealSched);
2121
static void ShowRouterOpts(const t_router_opts& RouterOpts);
2222
static void ShowAnalysisOpts(const t_analysis_opts& AnalysisOpts);
23+
static void ShowNocOpts(const t_noc_opts& NocOpts);
2324

2425
static void ShowAnnealSched(const t_annealing_sched& AnnealSched);
2526

@@ -61,6 +62,9 @@ void ShowSetup(const t_vpr_setup& vpr_setup) {
6162
if (vpr_setup.AnalysisOpts.doAnalysis) {
6263
ShowAnalysisOpts(vpr_setup.AnalysisOpts);
6364
}
65+
if (vpr_setup.NocOpts.noc) {
66+
ShowNocOpts(vpr_setup.NocOpts);
67+
}
6468
}
6569

6670
void ClusteredNetlistStats::writeHuman(std::ostream& output) const {
@@ -764,3 +768,10 @@ static void ShowPackerOpts(const t_packer_opts& PackerOpts) {
764768
VTR_LOG("\n");
765769
VTR_LOG("\n");
766770
}
771+
772+
static void ShowNocOpts(const t_noc_opts& NocOpts) {
773+
VTR_LOG("NocOpts.noc_flows_file: %s\n", NocOpts.noc_flows_file.c_str());
774+
VTR_LOG("\n");
775+
776+
// add future options here (routing algorithm etc...)
777+
}

vpr/src/base/clustered_netlist.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,3 +306,17 @@ bool ClusteredNetlist::validate_net_sizes_impl(size_t num_nets) const {
306306
}
307307
return true;
308308
}
309+
310+
ClusterBlockId ClusteredNetlist::find_block_by_name_fragment(const std::string& name_pattern, const std::vector<ClusterBlockId>& cluster_block_candidates) const {
311+
ClusterBlockId blk_id = ClusterBlockId::INVALID();
312+
std::regex name_to_match(name_pattern);
313+
314+
for (auto compatible_block_id = cluster_block_candidates.begin(); compatible_block_id != cluster_block_candidates.end(); compatible_block_id++) {
315+
if (std::regex_match(Netlist::block_name(*compatible_block_id), name_to_match)) {
316+
blk_id = *compatible_block_id;
317+
break;
318+
}
319+
}
320+
321+
return blk_id;
322+
}

vpr/src/base/clustered_netlist.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,77 @@ class ClusteredNetlist : public Netlist<ClusterBlockId, ClusterPortId, ClusterPi
228228
///@brief Sets the flag in net_is_global_ = state
229229
void set_net_is_global(ClusterNetId net_id, bool state);
230230

231+
/**
232+
* @brief Given a name of a block and vector of possible cluster blocks
233+
* that are candidates to match the block name, go through
234+
* the vector of cluster blocks and return the id of the block
235+
* where the block name matches the provided name.
236+
*
237+
* Given a string pattern representing a block name and a vector of
238+
* poissble cluster blocks that are candidates to match to the block
239+
* name pattern, go through the vector of cluster blocks and return
240+
* the id of the block where the block name matches to the provided
241+
* input pattern.
242+
*
243+
*/
244+
245+
/**
246+
* @brief The intented use is to find the block id of a
247+
* hard block without knowing its name in the netlist. Instead
248+
* a pattern can be created that we know the block's name will
249+
* match to. Generally, we expect the pattern to be constructed
250+
* using the block's module name in the HDL design, since we can
251+
* expect the netlist name of the block to include the module
252+
* name within it.
253+
*
254+
* For example, suppose a RAM block was named in the netlist as
255+
* "top|alu|test_ram|out". The user instantiated the ram module
256+
* in the HDL design as "test_ram". So instead of going through
257+
* the netlist and finding the ram block's full name, this
258+
* function can be used by just providing the string pattern as
259+
* ".*test_ram.*". We know that the module name should be somewhere
260+
* within the string, so the pattern we provide says that the netlist
261+
* name of the block contains arbritary characters then the module
262+
* name and then some other arbritary characters after.
263+
* This pattern will then be used to match to the block in the
264+
* netlist. The matched cluster block id is returned, and if no
265+
* block matched to the input string then an invalid block id
266+
* is returned.
267+
*
268+
* The function
269+
* here additionally requires a vector of possible cluster blocks
270+
* that can match to the input pattern. This vector can be the
271+
* entire netlist or a subset. For example, if the intended use
272+
* is to find hard blocks, it is quite inefficient
273+
* to go through all the blocks to find a matching one. Instead, a
274+
* a filtered vector can be passed that is a subset of the entire
275+
* netlist and can only contain blocks of a certain logical block
276+
* type (blocks that can be placed on a specific hard block).
277+
* The idea here is that the filtered vector should be
278+
* considereably smaller that a vector of every block in the netlist
279+
* and this should help improve run time.
280+
*
281+
* This function runs in linear time (O(N)) as it goes over the
282+
* vector of 'cluster_block_candidates'. 'cluster_block_candidates'
283+
* could be the whole netlist or a subset as explained above.
284+
* Additionally, if there are multiple
285+
* blocks that match to the provided input pattern, then the
286+
* first block found is returned.
287+
*
288+
*
289+
* @param name_pattern A regex string pattern that can be used to match to
290+
* a clustered block name within the netlist.
291+
* @param cluster_block_candidates A vector of clustered block ids that
292+
* represent a subset of the clustered
293+
* netlist. The blocks in this vector
294+
* will be used to compare and match
295+
* to the input string pattern.
296+
* @return A cluster block id representing a unique cluster block that
297+
* matched to the input string pattern.
298+
*
299+
*/
300+
ClusterBlockId find_block_by_name_fragment(const std::string& name_pattern, const std::vector<ClusterBlockId>& cluster_block_candidates) const;
301+
231302
private: //Private Members
232303
/*
233304
* Netlist compression/optimization

vpr/src/base/echo_files.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ void alloc_and_load_echo_file_info() {
132132

133133
//NoC
134134
setEchoFileName(E_ECHO_NOC_MODEL, "noc_model.echo");
135+
setEchoFileName(E_ECHO_NOC_TRAFFIC_FLOWS, "noc_traffic_flows.echo");
135136
}
136137

137138
void free_echo_file_info() {

vpr/src/base/echo_files.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ enum e_echo_files {
6565

6666
//NoC
6767
E_ECHO_NOC_MODEL,
68+
E_ECHO_NOC_TRAFFIC_FLOWS,
6869

6970
E_ECHO_END_TOKEN
7071
};

vpr/src/base/netlist.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,43 @@ class Netlist {
727727
*/
728728
BlockId find_block(const std::string& name) const;
729729

730+
/**
731+
* @brief Finds a block where the block's name contains the
732+
* provided input name as a substring.
733+
* The intented use is to find the block id of a
734+
* hard block without knowing its name in the netlist. Instead
735+
* the block's module name in the HDL design can be used as it will
736+
* be a substring within its full name in the netlist.
737+
*
738+
* For example, suppose a RAM block was named in the netlist as
739+
* "top|alu|test_ram|out". The user instantiated the ram module
740+
* in the HDL design as "test_ram". So instead of going through
741+
* the netlist and finding the ram block's full name, this
742+
* function can be used by just providing the module name "test_ram"
743+
* and using this substring to match the blocks name in the netlist
744+
* and retrieving its block id. If no blocks matched to input pattern
745+
* then an invalid block id is returned.
746+
*
747+
* This function runs in linear time (O(N)) as it goes over all the
748+
* cluster blocks in the netlist. Additionally, if there are multiple
749+
* blocks that contain the provided input as a substring, then the
750+
* first block found is returned.
751+
*
752+
* NOTE: This function tries to find blocks by checking for
753+
* substrings.
754+
* The clustered netlist class defines another version of this
755+
* function that find blocks by checking for a pattern match,
756+
* meaning that the input is a pattern string and the pattern
757+
* is looked for ine each block name.
758+
*
759+
* @param name_substring A substring of a block name for which an ID needs
760+
* to be found.
761+
* @return A cluster block id representing a unique cluster block that
762+
* matched to the input string pattern.
763+
*
764+
*/
765+
BlockId find_block_by_name_fragment(const std::string& name_substring) const;
766+
730767
/**
731768
* @brief Returns the PortId of the specifed port if it exists or PortId::INVALID() if not
732769
*

vpr/src/base/netlist.tpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,24 @@ BlockId Netlist<BlockId, PortId, PinId, NetId>::find_block(const std::string& na
458458
}
459459
}
460460

461+
template<typename BlockId, typename PortId, typename PinId, typename NetId>
462+
BlockId Netlist<BlockId, PortId, PinId, NetId>::find_block_by_name_fragment(const std::string& name_substring) const {
463+
BlockId matching_blk_id = BlockId::INVALID();
464+
const std::string blk_name;
465+
466+
// go through all the blocks in the netlist
467+
for (auto blk_id = block_ids_.begin(); blk_id != block_ids_.end(); blk_id++) {
468+
// get the corresponding block name
469+
blk_name = &strings_[block_names_[*blk_id]];
470+
// check whether the current block name contains the input string within it
471+
if (blk_name.find(name_substring) != std::string::npos) {
472+
matching_blk_id = blk_id;
473+
break;
474+
}
475+
}
476+
return matching_blk_id;
477+
}
478+
461479
template<typename BlockId, typename PortId, typename PinId, typename NetId>
462480
PortId Netlist<BlockId, PortId, PinId, NetId>::find_port(const BlockId blk_id, const std::string& name) const {
463481
VTR_ASSERT_SAFE(valid_block_id(blk_id));

vpr/src/base/read_options.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2622,6 +2622,13 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
26222622
.default_value("off")
26232623
.show_in(argparse::ShowIn::HELP_ONLY);
26242624

2625+
noc_grp.add_argument<std::string>(args.noc_flows_file, "--noc_flows_file")
2626+
.help(
2627+
"XML file containing the list of traffic flows within the NoC (communication between routers)."
2628+
"This is required if the --noc option is turned on.")
2629+
.default_value("")
2630+
.show_in(argparse::ShowIn::HELP_ONLY);
2631+
26252632
return parser;
26262633
}
26272634

@@ -2803,7 +2810,7 @@ void set_conditional_defaults(t_options& args) {
28032810

28042811
bool verify_args(const t_options& args) {
28052812
/*
2806-
* Check for conflicting paramaters
2813+
* Check for conflicting paramaters or dependencies where one parameter set requires another parameter to be included
28072814
*/
28082815
if (args.read_rr_graph_file.provenance() == Provenance::SPECIFIED
28092816
&& args.RouteChanWidth.provenance() != Provenance::SPECIFIED) {
@@ -2826,5 +2833,19 @@ bool verify_args(const t_options& args) {
28262833
args.router_lookahead_type.argument_name().c_str());
28272834
}
28282835

2836+
/**
2837+
* @brief If the user provided the "--noc" command line option, then there
2838+
* must be a NoC in the FPGA and the netlist must include NoC routers.
2839+
* Therefore, the user must also provide a noc traffic flows file to
2840+
* describe the communication within the NoC. We ensure that a noc traffic
2841+
* flows file is provided when the "--noc" option is used. If it is not
2842+
* provided, we throw an error.
2843+
*
2844+
*/
2845+
if (args.noc.provenance() == Provenance::SPECIFIED && args.noc_flows_file.provenance() != Provenance::SPECIFIED) {
2846+
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
2847+
"--noc_flows_file option must be specified if --noc is turned on.\n");
2848+
}
2849+
28292850
return true;
28302851
}

vpr/src/base/read_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ struct t_options {
140140

141141
/*NoC Options*/
142142
argparse::ArgValue<bool> noc;
143+
argparse::ArgValue<std::string> noc_flows_file;
143144

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

vpr/src/base/setup_noc.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
#include <climits>
32
#include <cmath>
43

vpr/src/base/setup_noc.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
#ifndef SETUP_NOC
22
#define SETUP_NOC
33

4-
/*
5-
* THis file contains functions and datatypes that help setup the NoC model datastructure from the user NoC description in the arch file.
6-
*
7-
* During VPR setup, the functions here should be used to setup the NoC.
8-
*
9-
*/
10-
114
/**
125
* @file
136
* @brief This is the setup_noc header file. The main purpose of

vpr/src/base/vpr_api.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "SetupGrid.h"
4040
#include "setup_clocks.h"
4141
#include "setup_noc.h"
42+
#include "read_xml_noc_traffic_flows_file.h"
4243
#include "stats.h"
4344
#include "read_options.h"
4445
#include "echo_files.h"
@@ -517,9 +518,11 @@ void vpr_setup_clock_networks(t_vpr_setup& vpr_setup, const t_arch& Arch) {
517518
*/
518519
void vpr_setup_noc(const t_vpr_setup& vpr_setup, const t_arch& arch) {
519520
// check if the user provided the option to model the noc
520-
if (vpr_setup.NocOpts.noc == true) {
521+
if (vpr_setup.NocOpts.noc) {
521522
// create the NoC model based on the user description from the arch file
522523
setup_noc(arch);
524+
// read and store the noc traffic flow information
525+
read_xml_noc_traffic_flows_file(vpr_setup.NocOpts.noc_flows_file.c_str());
523526

524527
#ifndef NO_GRAPHICS
525528
// setup the graphics

vpr/src/base/vpr_context.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "metadata_storage.h"
2929
#include "vpr_constraints.h"
3030
#include "noc_storage.h"
31+
#include "noc_traffic_flows.h"
3132

3233
/**
3334
* @brief A Context is collection of state relating to a particular part of VPR
@@ -465,6 +466,16 @@ struct NocContext : public Context {
465466
* The NoC model is created once from the architecture file description.
466467
*/
467468
NocStorage noc_model;
469+
470+
/**
471+
* @brief Stores all the communication happening between routers in the NoC
472+
*
473+
* Contains all of the traffic flows that ddescribe which pairs of logical routers are communicating and also some metrics and constraints on the data transfer between the two routers.
474+
*
475+
*
476+
* This is created from a user supplied .flows file.
477+
*/
478+
NocTrafficFlows noc_traffic_flows_storage;
468479
};
469480

470481
/**

vpr/src/base/vpr_types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1271,7 +1271,8 @@ struct t_analysis_opts {
12711271

12721272
// used to store NoC specific options, when supplied as an input by the user
12731273
struct t_noc_opts {
1274-
bool noc; ///<options to model the noc within the FPGA device
1274+
bool noc; ///<options to turn on hard NoC modeling & optimization
1275+
std::string noc_flows_file; ///<name of the file that contains all the traffic flow information in the NoC
12751276
};
12761277

12771278
/**

vpr/src/base/noc_data_types.h renamed to vpr/src/noc/noc_data_types.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44
#include "vtr_strong_id.h"
55

66
// data types used to index the routers and links within the noc
7-
87
struct noc_router_id_tag;
98
struct noc_link_id_tag;
109

1110
typedef vtr::StrongId<noc_router_id_tag, int> NocRouterId;
1211
typedef vtr::StrongId<noc_link_id_tag, int> NocLinkId;
1312

13+
// data type to index traffic flows within the noc
14+
struct noc_traffic_flow_id_tag;
15+
16+
typedef vtr::StrongId<noc_traffic_flow_id_tag, int> NocTrafficFlowId;
17+
1418
#endif
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)