Skip to content

Commit 499899d

Browse files
add t_mesh_region structure
1 parent 2c954d1 commit 499899d

File tree

1 file changed

+57
-53
lines changed

1 file changed

+57
-53
lines changed

libs/libarchfpga/src/read_xml_arch_file_noc_tag.cpp

Lines changed: 57 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,28 @@
77
#include "vtr_log.h"
88
#include "arch_error.h"
99

10+
/**
11+
* @brief Describes a mesh topology as specified in the architecture file.
12+
* It is assumed that NoC routers are equally distanced in each axis.
13+
*/
14+
struct t_mesh_region {
15+
/// The location the bottom left NoC router on the X-axis.
16+
float start_x;
17+
/// The location the top right NoC router on the X-axis.
18+
float end_x;
19+
/// The location the bottom left NoC router on the Y-axis.
20+
float start_y;
21+
/// The location the top right NoC router on the Y-axis.
22+
float end_y;
23+
/// The layer from which the mesh start.
24+
int start_layer;
25+
/// The layer at which the mesh ends.
26+
int end_layer;
27+
/// The number of NoC routers in each row or column.
28+
int mesh_size;
29+
};
30+
31+
1032
/**
1133
* @brief Process the <topology> tag under <noc> tag.
1234
*
@@ -60,22 +82,12 @@ static void process_mesh_topology(pugi::xml_node mesh_topology_tag,
6082
* @param mesh_topology_tag An XML tag pointing to a <mesh> tag.
6183
* @param loc_data Points to the location in the xml file where the parser is reading.
6284
* @param noc_ref To be filled with NoC router locations and their connectivity.
63-
* @param mesh_region_start_x The location the bottom left NoC router on the X-axis.
64-
* @param mesh_region_end_x The location the top right NoC router on the X-axis.
65-
* @param mesh_region_start_y The location the bottom left NoC router on the Y-axis.
66-
* @param mesh_region_end_y The location the top right NoC router on the Y-axis.
67-
* @param mesh_size The number of NoC routers in each row or column.
85+
* @param mesh_region Specifies the number of NoC routers and their locations in a mesh.
6886
*/
6987
static void generate_noc_mesh(pugi::xml_node mesh_topology_tag,
7088
const pugiutil::loc_data& loc_data,
7189
t_noc_inf* noc_ref,
72-
float mesh_region_start_x,
73-
float mesh_region_end_x,
74-
float mesh_region_start_y,
75-
float mesh_region_end_y,
76-
int mesh_region_start_layer,
77-
int mesh_region_end_layer,
78-
int mesh_size);
90+
const t_mesh_region& mesh_region);
7991

8092
/**
8193
* @brief Verify each router in the noc by checking whether they satisfy the following conditions:
@@ -236,51 +248,43 @@ static void process_mesh_topology(pugi::xml_node mesh_topology_tag,
236248
// verify that only the acceptable attributes were supplied
237249
pugiutil::expect_only_attributes(mesh_topology_tag, expected_router_attributes, loc_data);
238250

251+
t_mesh_region mesh_region;
252+
239253
// go through the attributes and store their values
240-
float mesh_region_start_x = pugiutil::get_attribute(mesh_topology_tag, "startx", loc_data, pugiutil::REQUIRED).as_float(ATTRIBUTE_CONVERSION_FAILURE);
241-
float mesh_region_end_x = pugiutil::get_attribute(mesh_topology_tag, "endx", loc_data, pugiutil::REQUIRED).as_float(ATTRIBUTE_CONVERSION_FAILURE);
242-
float mesh_region_start_y = pugiutil::get_attribute(mesh_topology_tag, "starty", loc_data, pugiutil::REQUIRED).as_float(ATTRIBUTE_CONVERSION_FAILURE);
243-
float mesh_region_end_y = pugiutil::get_attribute(mesh_topology_tag, "endy", loc_data, pugiutil::REQUIRED).as_float(ATTRIBUTE_CONVERSION_FAILURE);
254+
mesh_region.start_x = pugiutil::get_attribute(mesh_topology_tag, "startx", loc_data, pugiutil::REQUIRED).as_float(ATTRIBUTE_CONVERSION_FAILURE);
255+
mesh_region.end_x = pugiutil::get_attribute(mesh_topology_tag, "endx", loc_data, pugiutil::REQUIRED).as_float(ATTRIBUTE_CONVERSION_FAILURE);
256+
mesh_region.start_y = pugiutil::get_attribute(mesh_topology_tag, "starty", loc_data, pugiutil::REQUIRED).as_float(ATTRIBUTE_CONVERSION_FAILURE);
257+
mesh_region.end_y = pugiutil::get_attribute(mesh_topology_tag, "endy", loc_data, pugiutil::REQUIRED).as_float(ATTRIBUTE_CONVERSION_FAILURE);
244258

245-
int mesh_region_start_layer = pugiutil::get_attribute(mesh_topology_tag, "startlayer", loc_data, pugiutil::OPTIONAL).as_int(ATTRIBUTE_CONVERSION_FAILURE);
246-
int mesh_region_end_layer = pugiutil::get_attribute(mesh_topology_tag, "endlayer", loc_data, pugiutil::OPTIONAL).as_int(ATTRIBUTE_CONVERSION_FAILURE);
247-
int mesh_size = pugiutil::get_attribute(mesh_topology_tag, "size", loc_data, pugiutil::REQUIRED).as_int(ATTRIBUTE_CONVERSION_FAILURE);
259+
mesh_region.start_layer = pugiutil::get_attribute(mesh_topology_tag, "startlayer", loc_data, pugiutil::OPTIONAL).as_int(ATTRIBUTE_CONVERSION_FAILURE);
260+
mesh_region.end_layer = pugiutil::get_attribute(mesh_topology_tag, "endlayer", loc_data, pugiutil::OPTIONAL).as_int(ATTRIBUTE_CONVERSION_FAILURE);
261+
mesh_region.mesh_size = pugiutil::get_attribute(mesh_topology_tag, "size", loc_data, pugiutil::REQUIRED).as_int(ATTRIBUTE_CONVERSION_FAILURE);
248262

249263
// verify that the attributes provided were legal
250-
if ((mesh_region_start_x < 0) || (mesh_region_end_x < 0) || (mesh_region_start_y < 0) || (mesh_region_end_y < 0) || (mesh_size < 0)) {
264+
if (mesh_region.start_x < 0 || mesh_region.end_x < 0 || mesh_region.start_y < 0 || mesh_region.end_y < 0 || mesh_region.mesh_size < 0) {
251265
archfpga_throw(loc_data.filename_c_str(), loc_data.line(mesh_topology_tag),
252266
"The parameters for the mesh topology have to be positive values.");
253267
}
254268

255-
if (mesh_region_start_layer == ATTRIBUTE_CONVERSION_FAILURE || mesh_region_end_layer == ATTRIBUTE_CONVERSION_FAILURE) {
269+
if (mesh_region.start_layer == ATTRIBUTE_CONVERSION_FAILURE || mesh_region.end_layer == ATTRIBUTE_CONVERSION_FAILURE) {
256270
VTR_LOGF_WARN(loc_data.filename_c_str(), loc_data.line(mesh_topology_tag),
257271
"Optional 'startlayer' and 'endlayer' attributes were not set for the <mesh> tag. "
258272
"The default value of zero is used for both of them.\n");
259-
mesh_region_start_layer = 0;
260-
mesh_region_end_layer = 0;
273+
mesh_region.start_layer = 0;
274+
mesh_region.end_layer = 0;
261275
}
262276

263277
// now create the mesh topology for the noc
264278
// create routers, make connections and determine positions
265-
generate_noc_mesh(mesh_topology_tag, loc_data, noc_ref,
266-
mesh_region_start_x, mesh_region_end_x,
267-
mesh_region_start_y, mesh_region_end_y,
268-
mesh_region_start_layer, mesh_region_end_layer,
269-
mesh_size);
279+
generate_noc_mesh(mesh_topology_tag, loc_data, noc_ref, mesh_region);
270280
}
271281

272282
static void generate_noc_mesh(pugi::xml_node mesh_topology_tag,
273283
const pugiutil::loc_data& loc_data,
274284
t_noc_inf* noc_ref,
275-
float mesh_region_start_x,
276-
float mesh_region_end_x,
277-
float mesh_region_start_y,
278-
float mesh_region_end_y,
279-
int mesh_region_start_layer,
280-
int mesh_region_end_layer,
281-
int mesh_size) {
285+
const t_mesh_region& mesh_region) {
282286
// check that the mesh size of the router is not 0
283-
if (mesh_size == 0) {
287+
if (mesh_region.mesh_size == 0) {
284288
archfpga_throw(loc_data.filename_c_str(), loc_data.line(mesh_topology_tag),
285289
"The NoC mesh size cannot be 0.");
286290
}
@@ -307,32 +311,32 @@ static void generate_noc_mesh(pugi::xml_node mesh_topology_tag,
307311
*
308312
* THe reasoning for this is to reduce the number of calculated router positions.
309313
*/
310-
float vertical_router_separation = (mesh_region_end_y - mesh_region_start_y) / (mesh_size - 1);
311-
float horizontal_router_separation = (mesh_region_end_x - mesh_region_start_x) / (mesh_size - 1);
314+
float vertical_router_separation = (mesh_region.end_y - mesh_region.start_y) / (mesh_region.mesh_size - 1);
315+
float horizontal_router_separation = (mesh_region.end_x - mesh_region.start_x) / (mesh_region.mesh_size - 1);
312316

313317
// improper region check
314-
if (vertical_router_separation <= 0 || horizontal_router_separation <= 0 || mesh_region_end_layer < mesh_region_start_layer) {
318+
if (vertical_router_separation <= 0 || horizontal_router_separation <= 0 || mesh_region.end_layer < mesh_region.start_layer) {
315319
archfpga_throw(loc_data.filename_c_str(), loc_data.line(mesh_topology_tag),
316320
"The NoC region is invalid.");
317321
}
318322

319323
// create routers and their connections
320324
// start with router id 0 (bottom left of the chip) to the maximum router id (top right of the chip)
321-
for (int l = mesh_region_start_layer; l <= mesh_region_end_layer; l++) {
322-
for (int j = 0; j < mesh_size; j++) {
323-
for (int i = 0; i < mesh_size; i++) {
325+
for (int l = mesh_region.start_layer; l <= mesh_region.end_layer; l++) {
326+
for (int j = 0; j < mesh_region.mesh_size; j++) {
327+
for (int i = 0; i < mesh_region.mesh_size; i++) {
324328
t_router temp_router;
325329

326330
// assign router id
327-
temp_router.id = (mesh_size * mesh_size * (l - mesh_region_start_layer)) + (mesh_size * j) + i;
331+
temp_router.id = (mesh_region.mesh_size * mesh_region.mesh_size * (l - mesh_region.start_layer)) + (mesh_region.mesh_size * j) + i;
328332

329333
// calculate router position
330334
/* The first and last router of each column or row will be located on the mesh region boundary,
331335
* the remaining routers will be placed within the region and seperated from other routers
332336
* using the distance calculated previously.
333337
*/
334-
temp_router.device_x_position = (i * horizontal_router_separation) + mesh_region_start_x;
335-
temp_router.device_y_position = (j * vertical_router_separation) + mesh_region_start_y;
338+
temp_router.device_x_position = (i * horizontal_router_separation) + mesh_region.start_x;
339+
temp_router.device_y_position = (j * vertical_router_separation) + mesh_region.start_y;
336340
temp_router.device_layer_position = l;
337341

338342
// assign connections
@@ -344,31 +348,31 @@ static void generate_noc_mesh(pugi::xml_node mesh_topology_tag,
344348
}
345349

346350
// check if there is a router to the top
347-
if (j <= mesh_size - 2) {
351+
if (j <= mesh_region.mesh_size - 2) {
348352
// add the top router as a connection
349-
temp_router.connection_list.push_back(temp_router.id + mesh_size);
353+
temp_router.connection_list.push_back(temp_router.id + mesh_region.mesh_size);
350354
}
351355

352356
// check if there is a router to the right
353-
if (i <= mesh_size - 2) {
357+
if (i <= mesh_region.mesh_size - 2) {
354358
// add the router located to the right
355359
temp_router.connection_list.push_back(temp_router.id + 1);
356360
}
357361

358362
// check if there is a router below
359363
if (j >= 1) {
360364
// add the bottom router as a connection
361-
temp_router.connection_list.push_back(temp_router.id - mesh_size);
365+
temp_router.connection_list.push_back(temp_router.id - mesh_region.mesh_size);
362366
}
363367

364368
// check if there is a router on the layer above
365-
if (l < mesh_region_end_layer) {
366-
temp_router.connection_list.push_back(temp_router.id + (mesh_size * mesh_size));
369+
if (l < mesh_region.end_layer) {
370+
temp_router.connection_list.push_back(temp_router.id + (mesh_region.mesh_size * mesh_region.mesh_size));
367371
}
368372

369373
// check if there is a router on the layer below
370-
if (l > mesh_region_start_layer) {
371-
temp_router.connection_list.push_back(temp_router.id - (mesh_size * mesh_size));
374+
if (l > mesh_region.start_layer) {
375+
temp_router.connection_list.push_back(temp_router.id - (mesh_region.mesh_size * mesh_region.mesh_size));
372376
}
373377

374378
// add the router to the list

0 commit comments

Comments
 (0)