Skip to content

Commit 6778109

Browse files
add a unit test for link/router specific latency/bandwidth
1 parent 02c231d commit 6778109

File tree

3 files changed

+282
-1
lines changed

3 files changed

+282
-1
lines changed

vpr/src/noc/noc_storage.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,16 @@ NocRouterId NocStorage::convert_router_id(int id) const {
241241
return result->second;
242242
}
243243

244+
int NocStorage::convert_router_id(NocRouterId id) const {
245+
for (auto [user_id, router_id] : router_id_conversion_table) {
246+
if (router_id == id) {
247+
return user_id;
248+
}
249+
}
250+
251+
VPR_FATAL_ERROR(VPR_ERROR_OTHER, "Cannot convert router with id:%d. The router was not found within the NoC.", id);
252+
}
253+
244254
void NocStorage::make_room_for_noc_router_link_list() {
245255
VTR_ASSERT_MSG(!built_noc, "NoC already built, cannot modify further.");
246256
router_link_list.resize(router_storage.size());

vpr/src/noc/noc_storage.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,13 @@ class NocStorage {
461461
*/
462462
NocRouterId convert_router_id(int id) const;
463463

464+
/**
465+
* @brief Converts a NoCRouterID to the user router id.
466+
* @param id The internal NoCRouterId
467+
* @return The user provided router id;
468+
*/
469+
int convert_router_id(NocRouterId id) const;
470+
464471
/**
465472
* @brief The datastructure that stores the outgoing links to each
466473
* router is an 2-D Vector. When processing the links, they can be

vpr/test/test_setup_noc.cpp

Lines changed: 265 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -921,7 +921,7 @@ TEST_CASE("test_setup_noc", "[vpr_setup_noc]") {
921921

922922
REQUIRE_THROWS_WITH(setup_noc(arch), "The Provided NoC topology information in the architecture file has more number of routers than what is available in the FPGA device.");
923923
}
924-
SECTION("Test setup_noc when there are no physical NoC routers on the FPGA.") {
924+
SECTION("Test setup_noc when there are no physical NoC routers on the FPGA.") {
925925
// test device grid name
926926
std::string device_grid_name = "test";
927927

@@ -972,6 +972,270 @@ TEST_CASE("test_setup_noc", "[vpr_setup_noc]") {
972972

973973
REQUIRE_THROWS_WITH(setup_noc(arch), "No physical NoC routers were found on the FPGA device. Either the provided name for the physical router tile was incorrect or the FPGA device has no routers.");
974974
}
975+
SECTION("Test setup_noc when there are overrides for NoC-wide latency and bandwidth values.") {
976+
// test device grid name
977+
std::string device_grid_name = "test";
978+
979+
// creating a reference for the empty tile name and router name
980+
char empty_tile_name[6] = "empty";
981+
char router_tile_name[7] = "router";
982+
983+
// assign the name used when describing a router tile in the FPGA architecture description file
984+
arch.noc->noc_router_tile_name.assign(router_tile_name);
985+
986+
// device grid parameters
987+
int test_grid_width = 10;
988+
int test_grid_height = 10;
989+
990+
// create the test device grid (10x10)
991+
auto test_grid = vtr::NdMatrix<t_grid_tile, 3>({1, 10, 10});
992+
993+
// create an empty physical tile and assign its parameters
994+
t_physical_tile_type empty_tile;
995+
empty_tile.name = empty_tile_name;
996+
empty_tile.height = 1;
997+
empty_tile.width = 1;
998+
999+
// create a router tile and assign its parameters
1000+
// the router will take up 4 grid spaces and be named "router"
1001+
t_physical_tile_type router_tile;
1002+
router_tile.name = router_tile_name;
1003+
router_tile.height = 2;
1004+
router_tile.width = 2;
1005+
1006+
// (0, 0)
1007+
test_grid[0][0][0].type = &router_tile;
1008+
test_grid[0][0][0].height_offset = 0;
1009+
test_grid[0][0][0].width_offset = 0;
1010+
1011+
test_grid[0][1][0].type = &router_tile;
1012+
test_grid[0][1][0].height_offset = 0;
1013+
test_grid[0][1][0].width_offset = 1;
1014+
1015+
test_grid[0][0][1].type = &router_tile;
1016+
test_grid[0][0][1].height_offset = 1;
1017+
test_grid[0][0][1].width_offset = 0;
1018+
1019+
test_grid[0][1][1].type = &router_tile;
1020+
test_grid[0][1][1].height_offset = 1;
1021+
test_grid[0][1][1].width_offset = 1;
1022+
1023+
// (0, 4)
1024+
test_grid[0][0][4].type = &router_tile;
1025+
test_grid[0][0][4].height_offset = 0;
1026+
test_grid[0][0][4].width_offset = 0;
1027+
1028+
test_grid[0][1][4].type = &router_tile;
1029+
test_grid[0][1][4].height_offset = 0;
1030+
test_grid[0][1][4].width_offset = 1;
1031+
1032+
test_grid[0][0][5].type = &router_tile;
1033+
test_grid[0][0][5].height_offset = 1;
1034+
test_grid[0][0][5].width_offset = 0;
1035+
1036+
test_grid[0][1][5].type = &router_tile;
1037+
test_grid[0][1][5].height_offset = 1;
1038+
test_grid[0][1][5].width_offset = 1;
1039+
1040+
// (0, 8)
1041+
test_grid[0][0][8].type = &router_tile;
1042+
test_grid[0][0][8].height_offset = 0;
1043+
test_grid[0][0][8].width_offset = 0;
1044+
1045+
test_grid[0][1][8].type = &router_tile;
1046+
test_grid[0][1][8].height_offset = 0;
1047+
test_grid[0][1][8].width_offset = 1;
1048+
1049+
test_grid[0][0][9].type = &router_tile;
1050+
test_grid[0][0][9].height_offset = 1;
1051+
test_grid[0][0][9].width_offset = 0;
1052+
1053+
test_grid[0][1][9].type = &router_tile;
1054+
test_grid[0][1][9].height_offset = 1;
1055+
test_grid[0][1][9].width_offset = 1;
1056+
1057+
// (4, 0)
1058+
test_grid[0][4][0].type = &router_tile;
1059+
test_grid[0][4][0].height_offset = 0;
1060+
test_grid[0][4][0].width_offset = 0;
1061+
1062+
test_grid[0][5][0].type = &router_tile;
1063+
test_grid[0][5][0].height_offset = 0;
1064+
test_grid[0][5][0].width_offset = 1;
1065+
1066+
test_grid[0][4][1].type = &router_tile;
1067+
test_grid[0][4][1].height_offset = 1;
1068+
test_grid[0][4][1].width_offset = 0;
1069+
1070+
test_grid[0][5][1].type = &router_tile;
1071+
test_grid[0][5][1].height_offset = 1;
1072+
test_grid[0][5][1].width_offset = 1;
1073+
1074+
// (4, 4)
1075+
test_grid[0][4][4].type = &router_tile;
1076+
test_grid[0][4][4].height_offset = 0;
1077+
test_grid[0][4][4].width_offset = 0;
1078+
1079+
test_grid[0][5][4].type = &router_tile;
1080+
test_grid[0][5][4].height_offset = 0;
1081+
test_grid[0][5][4].width_offset = 1;
1082+
1083+
test_grid[0][4][5].type = &router_tile;
1084+
test_grid[0][4][5].height_offset = 1;
1085+
test_grid[0][4][5].width_offset = 0;
1086+
1087+
test_grid[0][5][5].type = &router_tile;
1088+
test_grid[0][5][5].height_offset = 1;
1089+
test_grid[0][5][5].width_offset = 1;
1090+
1091+
// (4, 8)
1092+
test_grid[0][4][8].type = &router_tile;
1093+
test_grid[0][4][8].height_offset = 0;
1094+
test_grid[0][4][8].width_offset = 0;
1095+
1096+
test_grid[0][5][8].type = &router_tile;
1097+
test_grid[0][5][8].height_offset = 0;
1098+
test_grid[0][5][8].width_offset = 1;
1099+
1100+
test_grid[0][4][9].type = &router_tile;
1101+
test_grid[0][4][9].height_offset = 1;
1102+
test_grid[0][4][9].width_offset = 0;
1103+
1104+
test_grid[0][5][9].type = &router_tile;
1105+
test_grid[0][5][9].height_offset = 1;
1106+
test_grid[0][5][9].width_offset = 1;
1107+
1108+
// (8, 0)
1109+
test_grid[0][8][0].type = &router_tile;
1110+
test_grid[0][8][0].height_offset = 0;
1111+
test_grid[0][8][0].width_offset = 0;
1112+
1113+
test_grid[0][9][0].type = &router_tile;
1114+
test_grid[0][9][0].height_offset = 0;
1115+
test_grid[0][9][0].width_offset = 1;
1116+
1117+
test_grid[0][8][1].type = &router_tile;
1118+
test_grid[0][8][1].height_offset = 1;
1119+
test_grid[0][8][1].width_offset = 0;
1120+
1121+
test_grid[0][9][1].type = &router_tile;
1122+
test_grid[0][9][1].height_offset = 1;
1123+
test_grid[0][9][1].width_offset = 1;
1124+
1125+
// (8, 4)
1126+
test_grid[0][8][4].type = &router_tile;
1127+
test_grid[0][8][4].height_offset = 0;
1128+
test_grid[0][8][4].width_offset = 0;
1129+
1130+
test_grid[0][9][4].type = &router_tile;
1131+
test_grid[0][9][4].height_offset = 0;
1132+
test_grid[0][9][4].width_offset = 1;
1133+
1134+
test_grid[0][8][5].type = &router_tile;
1135+
test_grid[0][8][5].height_offset = 1;
1136+
test_grid[0][8][5].width_offset = 0;
1137+
1138+
test_grid[0][9][5].type = &router_tile;
1139+
test_grid[0][9][5].height_offset = 1;
1140+
test_grid[0][9][5].width_offset = 1;
1141+
1142+
// (8, 8)
1143+
test_grid[0][8][8].type = &router_tile;
1144+
test_grid[0][8][8].height_offset = 0;
1145+
test_grid[0][8][8].width_offset = 0;
1146+
1147+
test_grid[0][9][8].type = &router_tile;
1148+
test_grid[0][9][8].height_offset = 0;
1149+
test_grid[0][9][8].width_offset = 1;
1150+
1151+
test_grid[0][8][9].type = &router_tile;
1152+
test_grid[0][8][9].height_offset = 1;
1153+
test_grid[0][8][9].width_offset = 0;
1154+
1155+
test_grid[0][9][9].type = &router_tile;
1156+
test_grid[0][9][9].height_offset = 1;
1157+
test_grid[0][9][9].width_offset = 1;
1158+
1159+
for (int i = 0; i < test_grid_width; i++) {
1160+
for (int j = 0; j < test_grid_height; j++) {
1161+
// make sure the current tyle is not a router
1162+
if (test_grid[0][i][j].type == nullptr) {
1163+
// assign the non-router tile as empty
1164+
test_grid[0][i][j].type = &empty_tile;
1165+
test_grid[0][i][j].width_offset = 0;
1166+
test_grid[0][i][j].height_offset = 0;
1167+
}
1168+
}
1169+
}
1170+
1171+
std::random_device device;
1172+
std::mt19937 rand_num_gen(device());
1173+
std::uniform_int_distribution<std::mt19937::result_type> dist(1, 9);
1174+
1175+
constexpr double LINK_LATENCY_OVERRIDE = 142.2;
1176+
constexpr double LINK_BANDWIDTH_OVERRIDE = 727.4;
1177+
constexpr double ROUTER_LATENCY_OVERRIDE = 151.6;
1178+
REQUIRE(LINK_LATENCY_OVERRIDE != noc_info.link_latency);
1179+
REQUIRE(LINK_BANDWIDTH_OVERRIDE != noc_info.link_bandwidth);
1180+
REQUIRE(ROUTER_LATENCY_OVERRIDE != noc_info.router_latency);
1181+
1182+
// add router latency overrides
1183+
for (int i = 0; i < 3; i++) {
1184+
int noc_router_user_id = dist(rand_num_gen);
1185+
noc_info.router_latency_overrides.insert({noc_router_user_id, ROUTER_LATENCY_OVERRIDE});
1186+
}
1187+
1188+
// add link latency overrides
1189+
for (int i = 0; i < 3; i++) {
1190+
int noc_router_user_id = dist(rand_num_gen);
1191+
size_t n_connections = noc_info.router_list[noc_router_user_id - 1].connection_list.size();
1192+
int selected_connection = dist(rand_num_gen) % n_connections;
1193+
int neighbor_router_user_id = noc_info.router_list[noc_router_user_id - 1].connection_list[selected_connection];
1194+
noc_info.link_latency_overrides.insert({{noc_router_user_id, neighbor_router_user_id}, LINK_LATENCY_OVERRIDE});
1195+
}
1196+
1197+
// add link bandwidth overrides
1198+
for (int i = 0; i < 3; i++) {
1199+
int noc_router_user_id = dist(rand_num_gen);
1200+
size_t n_connections = noc_info.router_list[noc_router_user_id - 1].connection_list.size();
1201+
int selected_connection = dist(rand_num_gen) % n_connections;
1202+
int neighbor_router_user_id = noc_info.router_list[noc_router_user_id - 1].connection_list[selected_connection];
1203+
noc_info.link_bandwidth_overrides.insert({{noc_router_user_id, neighbor_router_user_id}, LINK_BANDWIDTH_OVERRIDE});
1204+
}
1205+
1206+
device_ctx.grid = DeviceGrid(device_grid_name, test_grid);
1207+
1208+
REQUIRE_NOTHROW(setup_noc(arch));
1209+
1210+
const auto& noc_model = g_vpr_ctx.noc().noc_model;
1211+
1212+
// check NoC router latencies
1213+
for (const auto& noc_router : noc_model.get_noc_routers()) {
1214+
int router_user_id = noc_router.get_router_user_id();
1215+
auto it = noc_info.router_latency_overrides.find(router_user_id);
1216+
double expected_latency = (it != noc_info.router_latency_overrides.end()) ? it->second : noc_info.router_latency;
1217+
REQUIRE(expected_latency == noc_router.get_latency());
1218+
}
1219+
1220+
// check NoC link latencies and bandwidth
1221+
for (const auto& noc_link : noc_model.get_noc_links()) {
1222+
NocRouterId src_router_id = noc_link.get_source_router();
1223+
NocRouterId dst_router_id = noc_link.get_sink_router();
1224+
int src_user_id = noc_model.convert_router_id(src_router_id);
1225+
int dst_user_id = noc_model.convert_router_id(dst_router_id);
1226+
1227+
auto lat_it = noc_info.link_latency_overrides.find({src_user_id, dst_user_id});
1228+
double expected_latency = (lat_it != noc_info.link_latency_overrides.end()) ? lat_it->second : noc_info.link_latency;
1229+
REQUIRE(expected_latency == noc_link.get_latency());
1230+
1231+
auto bw_it = noc_info.link_bandwidth_overrides.find({src_user_id, dst_user_id});
1232+
double expected_bandwidth = (bw_it != noc_info.link_bandwidth_overrides.end()) ? bw_it->second : noc_info.link_bandwidth;
1233+
REQUIRE(expected_bandwidth == noc_link.get_bandwidth());
1234+
}
1235+
1236+
// remove noc storage
1237+
g_vpr_ctx.mutable_noc().noc_model.clear_noc();
1238+
}
9751239
}
9761240

9771241
} // namespace

0 commit comments

Comments
 (0)