@@ -82,13 +82,18 @@ static void update_router_info_in_arch(int router_id,
82
82
std::map<int , std::pair<int , int >>& routers_in_arch_info);
83
83
84
84
85
+ static void process_noc_overrides (pugi::xml_node noc_overrides_tag,
86
+ const pugiutil::loc_data& loc_data,
87
+ t_noc_inf& noc_ref);
88
+
89
+
85
90
void process_noc_tag (pugi::xml_node noc_tag,
86
91
t_arch* arch,
87
92
const pugiutil::loc_data& loc_data) {
88
93
// a vector representing all the possible attributes within the noc tag
89
- std::vector<std::string> expected_noc_attributes = {" link_bandwidth" , " link_latency" , " router_latency" , " noc_router_tile_name" };
94
+ const std::vector<std::string> expected_noc_attributes = {" link_bandwidth" , " link_latency" , " router_latency" , " noc_router_tile_name" };
90
95
91
- std::vector<std::string> expected_noc_children_tags = {" mesh" , " topology" };
96
+ const std::vector<std::string> expected_noc_children_tags = {" mesh" , " topology" };
92
97
93
98
94
99
// identifier that lets us know when we could not properly convert a string conversion value
@@ -149,10 +154,10 @@ void process_noc_tag(pugi::xml_node noc_tag,
149
154
process_topology (noc_topology, loc_data, noc_ref);
150
155
}
151
156
152
- // pugi::xml_node noc_overrides = pugiutil::get_single_child(noc_tag, "overrides", loc_data, pugiutil::OPTIONAL);
153
- // if (noc_overrides) {
154
- //
155
- // }
157
+ pugi::xml_node noc_overrides = pugiutil::get_single_child (noc_tag, " overrides" , loc_data, pugiutil::OPTIONAL);
158
+ if (noc_overrides) {
159
+ process_noc_overrides (noc_overrides, loc_data, *noc_ref);
160
+ }
156
161
}
157
162
158
163
/*
@@ -505,3 +510,113 @@ static void update_router_info_in_arch(int router_id,
505
510
n_declarations++;
506
511
}
507
512
}
513
+
514
+ static void process_noc_overrides (pugi::xml_node noc_overrides_tag,
515
+ const pugiutil::loc_data& loc_data,
516
+ t_noc_inf& noc_ref) {
517
+ // an accepted list of attributes for the router tag
518
+ const std::vector<std::string> expected_router_attributes{" id" , " latency" };
519
+ // the list of expected values for link tag
520
+ const std::vector<std::string> expected_link_override_attributes{" src" , " dst" , " latency" , " bandwidth" };
521
+
522
+ for (pugi::xml_node override_tag : noc_overrides_tag.children ()) {
523
+ std::string_view override_name = override_tag.name ();
524
+
525
+ if (override_name == " router" ) {
526
+ // check that only the accepted router attributes are found in the tag
527
+ pugiutil::expect_only_attributes (override_tag, expected_router_attributes, loc_data);
528
+
529
+ // store the router information from the attributes
530
+ int id = pugiutil::get_attribute (noc_overrides_tag, " id" , loc_data, pugiutil::REQUIRED).as_int (-1 );
531
+
532
+ auto router_latency_override = pugiutil::get_attribute (override_tag, " latency" , loc_data, pugiutil::REQUIRED).as_string ();
533
+ double latency = std::atof (router_latency_override);
534
+
535
+ if (id < 0 || latency <= 0.0 ) {
536
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (override_tag),
537
+ " The latency override value (%g) for router with id:%d is not legal. "
538
+ " The router id must be non-negative and the latency must be positive." ,
539
+ latency, id);
540
+ }
541
+
542
+ auto it = std::find_if (noc_ref.router_list .begin (), noc_ref.router_list .end (), [id](const t_router& router) {
543
+ return router.id == id;
544
+ });
545
+
546
+ if (it == noc_ref.router_list .end ()) {
547
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (override_tag),
548
+ " The router with id:%d could not be found in the topology." ,
549
+ id);
550
+ }
551
+
552
+ auto [_, success] = noc_ref.router_latency_overrides .insert ({id, latency});
553
+ if (!success) {
554
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (override_tag),
555
+ " The latency of the router with id:%d wad overridden once before." ,
556
+ id);
557
+ }
558
+
559
+ } else if (override_name == " link" ) {
560
+ // check that only the accepted link attributes are found in the tag
561
+ pugiutil::expect_only_attributes (override_tag, expected_link_override_attributes, loc_data);
562
+
563
+ // store the router information from the attributes
564
+ int src = pugiutil::get_attribute (noc_overrides_tag, " src" , loc_data, pugiutil::REQUIRED).as_int (-1 );
565
+ int dst = pugiutil::get_attribute (noc_overrides_tag, " dst" , loc_data, pugiutil::REQUIRED).as_int (-1 );
566
+
567
+ if (src < 0 || dst < 0 ) {
568
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (override_tag),
569
+ " The source and destination router ids (%d, %d) must be non-negative." ,
570
+ src, dst);
571
+ }
572
+
573
+ auto it = std::find_if (noc_ref.router_list .begin (), noc_ref.router_list .end (), [src, dst](const t_router& router) {
574
+ return router.id == src &&
575
+ std::find (router.connection_list .begin (), router.connection_list .end (), dst) != router.connection_list .end ();
576
+ });
577
+
578
+ if (it == noc_ref.router_list .end ()) {
579
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (override_tag),
580
+ " There is no links from the router with id:%d to the router with id:%d." ,
581
+ src, dst);
582
+ }
583
+
584
+ auto link_latency_override = pugiutil::get_attribute (override_tag, " latency" , loc_data, pugiutil::REQUIRED).as_string (nullptr );
585
+ if (link_latency_override != nullptr ) {
586
+ double latency = std::atof (link_latency_override);
587
+ if (latency <= 0.0 ) {
588
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (override_tag),
589
+ " The override link latency value for link (%d, %d) must be positive:%g." ,
590
+ src, dst, latency);
591
+ }
592
+
593
+ auto [_, success] = noc_ref.link_latency_overrides .insert ({{src, dst}, latency});
594
+ if (!success) {
595
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (override_tag),
596
+ " The latency for link (%d, %d) was overridden once before." ,
597
+ src, dst);
598
+ }
599
+ }
600
+
601
+ auto link_bandwidth_override = pugiutil::get_attribute (override_tag, " bandwidth" , loc_data, pugiutil::REQUIRED).as_string (nullptr );
602
+ if (link_bandwidth_override != nullptr ) {
603
+ double bandwidth = std::atof (link_latency_override);
604
+ if (bandwidth <= 0.0 ) {
605
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (override_tag),
606
+ " The override link bandwidth value for link (%d, %d) must be positive:%g." ,
607
+ src, dst, bandwidth);
608
+ }
609
+
610
+ auto [_, success] = noc_ref.link_bandwidth_overrides .insert ({{src, dst}, bandwidth});
611
+ if (!success) {
612
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (override_tag),
613
+ " The bandwidth for link (%d, %d) was overridden once before." ,
614
+ src, dst);
615
+ }
616
+ }
617
+ } else {
618
+ bad_tag (override_tag, loc_data, noc_overrides_tag, {" router" , " link" });
619
+ }
620
+ }
621
+
622
+ }
0 commit comments