7
7
#include " vtr_log.h"
8
8
#include " arch_error.h"
9
9
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
+
10
32
/* *
11
33
* @brief Process the <topology> tag under <noc> tag.
12
34
*
@@ -60,22 +82,12 @@ static void process_mesh_topology(pugi::xml_node mesh_topology_tag,
60
82
* @param mesh_topology_tag An XML tag pointing to a <mesh> tag.
61
83
* @param loc_data Points to the location in the xml file where the parser is reading.
62
84
* @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.
68
86
*/
69
87
static void generate_noc_mesh (pugi::xml_node mesh_topology_tag,
70
88
const pugiutil::loc_data& loc_data,
71
89
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);
79
91
80
92
/* *
81
93
* @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,
236
248
// verify that only the acceptable attributes were supplied
237
249
pugiutil::expect_only_attributes (mesh_topology_tag, expected_router_attributes, loc_data);
238
250
251
+ t_mesh_region mesh_region;
252
+
239
253
// 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);
244
258
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);
248
262
249
263
// 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 ) {
251
265
archfpga_throw (loc_data.filename_c_str (), loc_data.line (mesh_topology_tag),
252
266
" The parameters for the mesh topology have to be positive values." );
253
267
}
254
268
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) {
256
270
VTR_LOGF_WARN (loc_data.filename_c_str (), loc_data.line (mesh_topology_tag),
257
271
" Optional 'startlayer' and 'endlayer' attributes were not set for the <mesh> tag. "
258
272
" 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 ;
261
275
}
262
276
263
277
// now create the mesh topology for the noc
264
278
// 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);
270
280
}
271
281
272
282
static void generate_noc_mesh (pugi::xml_node mesh_topology_tag,
273
283
const pugiutil::loc_data& loc_data,
274
284
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) {
282
286
// check that the mesh size of the router is not 0
283
- if (mesh_size == 0 ) {
287
+ if (mesh_region. mesh_size == 0 ) {
284
288
archfpga_throw (loc_data.filename_c_str (), loc_data.line (mesh_topology_tag),
285
289
" The NoC mesh size cannot be 0." );
286
290
}
@@ -307,32 +311,32 @@ static void generate_noc_mesh(pugi::xml_node mesh_topology_tag,
307
311
*
308
312
* THe reasoning for this is to reduce the number of calculated router positions.
309
313
*/
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 );
312
316
313
317
// 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 ) {
315
319
archfpga_throw (loc_data.filename_c_str (), loc_data.line (mesh_topology_tag),
316
320
" The NoC region is invalid." );
317
321
}
318
322
319
323
// create routers and their connections
320
324
// 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++) {
324
328
t_router temp_router;
325
329
326
330
// 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;
328
332
329
333
// calculate router position
330
334
/* The first and last router of each column or row will be located on the mesh region boundary,
331
335
* the remaining routers will be placed within the region and seperated from other routers
332
336
* using the distance calculated previously.
333
337
*/
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 ;
336
340
temp_router.device_layer_position = l;
337
341
338
342
// assign connections
@@ -344,31 +348,31 @@ static void generate_noc_mesh(pugi::xml_node mesh_topology_tag,
344
348
}
345
349
346
350
// check if there is a router to the top
347
- if (j <= mesh_size - 2 ) {
351
+ if (j <= mesh_region. mesh_size - 2 ) {
348
352
// 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 );
350
354
}
351
355
352
356
// check if there is a router to the right
353
- if (i <= mesh_size - 2 ) {
357
+ if (i <= mesh_region. mesh_size - 2 ) {
354
358
// add the router located to the right
355
359
temp_router.connection_list .push_back (temp_router.id + 1 );
356
360
}
357
361
358
362
// check if there is a router below
359
363
if (j >= 1 ) {
360
364
// 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 );
362
366
}
363
367
364
368
// 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 ));
367
371
}
368
372
369
373
// 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 ));
372
376
}
373
377
374
378
// add the router to the list
0 commit comments