@@ -68,8 +68,9 @@ static void process_mesh_topology(pugi::xml_node mesh_topology_tag,
68
68
static void generate_noc_mesh (pugi::xml_node mesh_topology_tag,
69
69
const pugiutil::loc_data& loc_data,
70
70
t_noc_inf* noc_ref,
71
- double mesh_region_start_x, double mesh_region_end_x,
72
- double mesh_region_start_y, double mesh_region_end_y,
71
+ float mesh_region_start_x, float mesh_region_end_x,
72
+ float mesh_region_start_y, float mesh_region_end_y,
73
+ int mesh_region_start_layer, int mesh_region_end_layer,
73
74
int mesh_size);
74
75
75
76
/* *
@@ -227,17 +228,19 @@ static void process_mesh_topology(pugi::xml_node mesh_topology_tag,
227
228
constexpr int ATTRIBUTE_CONVERSION_FAILURE = -1 ;
228
229
229
230
// a list of attributes that should be found for the mesh tag
230
- std::vector<std::string> expected_router_attributes = {" startx" , " endx" , " starty" , " endy" , " size" };
231
+ std::vector<std::string> expected_router_attributes = {" startx" , " endx" , " starty" , " endy" , " startlayer " , " endlayer " , " size" };
231
232
232
233
// verify that only the acceptable attributes were supplied
233
234
pugiutil::expect_only_attributes (mesh_topology_tag, expected_router_attributes, loc_data);
234
235
235
236
// go through the attributes and store their values
236
- double mesh_region_start_x = pugiutil::get_attribute (mesh_topology_tag, " startx" , loc_data, pugiutil::REQUIRED).as_double (ATTRIBUTE_CONVERSION_FAILURE);
237
- double mesh_region_end_x = pugiutil::get_attribute (mesh_topology_tag, " endx" , loc_data, pugiutil::REQUIRED).as_double (ATTRIBUTE_CONVERSION_FAILURE);
238
- double mesh_region_start_y = pugiutil::get_attribute (mesh_topology_tag, " starty" , loc_data, pugiutil::REQUIRED).as_double (ATTRIBUTE_CONVERSION_FAILURE);
239
- double mesh_region_end_y = pugiutil::get_attribute (mesh_topology_tag, " endy" , loc_data, pugiutil::REQUIRED).as_double (ATTRIBUTE_CONVERSION_FAILURE);
237
+ float mesh_region_start_x = pugiutil::get_attribute (mesh_topology_tag, " startx" , loc_data, pugiutil::REQUIRED).as_float (ATTRIBUTE_CONVERSION_FAILURE);
238
+ float mesh_region_end_x = pugiutil::get_attribute (mesh_topology_tag, " endx" , loc_data, pugiutil::REQUIRED).as_float (ATTRIBUTE_CONVERSION_FAILURE);
239
+ float mesh_region_start_y = pugiutil::get_attribute (mesh_topology_tag, " starty" , loc_data, pugiutil::REQUIRED).as_float (ATTRIBUTE_CONVERSION_FAILURE);
240
+ float mesh_region_end_y = pugiutil::get_attribute (mesh_topology_tag, " endy" , loc_data, pugiutil::REQUIRED).as_float (ATTRIBUTE_CONVERSION_FAILURE);
240
241
242
+ int mesh_region_start_layer = pugiutil::get_attribute (mesh_topology_tag, " startlayer" , loc_data, pugiutil::OPTIONAL).as_int (ATTRIBUTE_CONVERSION_FAILURE);
243
+ int mesh_region_end_layer = pugiutil::get_attribute (mesh_topology_tag, " endlayer" , loc_data, pugiutil::OPTIONAL).as_int (ATTRIBUTE_CONVERSION_FAILURE);
241
244
int mesh_size = pugiutil::get_attribute (mesh_topology_tag, " size" , loc_data, pugiutil::REQUIRED).as_int (ATTRIBUTE_CONVERSION_FAILURE);
242
245
243
246
// verify that the attributes provided were legal
@@ -246,16 +249,29 @@ static void process_mesh_topology(pugi::xml_node mesh_topology_tag,
246
249
" The parameters for the mesh topology have to be positive values." );
247
250
}
248
251
252
+ if (mesh_region_start_layer == ATTRIBUTE_CONVERSION_FAILURE || mesh_region_end_layer == ATTRIBUTE_CONVERSION_FAILURE) {
253
+ VTR_LOGF_WARN (loc_data.filename_c_str (), loc_data.line (mesh_topology_tag),
254
+ " Optional 'startlayer' and 'endlayer' attributes were not set for the <mesh> tag. "
255
+ " The default value of zero is used for both of them.\n " );
256
+ mesh_region_start_layer = 0 ;
257
+ mesh_region_end_layer = 0 ;
258
+ }
259
+
249
260
// now create the mesh topology for the noc
250
261
// create routers, make connections and determine positions
251
- generate_noc_mesh (mesh_topology_tag, loc_data, noc_ref, mesh_region_start_x, mesh_region_end_x, mesh_region_start_y, mesh_region_end_y, mesh_size);
262
+ generate_noc_mesh (mesh_topology_tag, loc_data, noc_ref,
263
+ mesh_region_start_x, mesh_region_end_x,
264
+ mesh_region_start_y, mesh_region_end_y,
265
+ mesh_region_start_layer, mesh_region_end_layer,
266
+ mesh_size);
252
267
}
253
268
254
269
static void generate_noc_mesh (pugi::xml_node mesh_topology_tag,
255
270
const pugiutil::loc_data& loc_data,
256
271
t_noc_inf* noc_ref,
257
- double mesh_region_start_x, double mesh_region_end_x,
258
- double mesh_region_start_y, double mesh_region_end_y,
272
+ float mesh_region_start_x, float mesh_region_end_x,
273
+ float mesh_region_start_y, float mesh_region_end_y,
274
+ int mesh_region_start_layer, int mesh_region_end_layer,
259
275
int mesh_size) {
260
276
// check that the mesh size of the router is not 0
261
277
if (mesh_size == 0 ) {
@@ -285,62 +301,74 @@ static void generate_noc_mesh(pugi::xml_node mesh_topology_tag,
285
301
*
286
302
* THe reasoning for this is to reduce the number of calculated router positions.
287
303
*/
288
- double vertical_router_separation = (mesh_region_end_y - mesh_region_start_y) / (mesh_size - 1 );
289
- double horizontal_router_separation = (mesh_region_end_x - mesh_region_start_x) / (mesh_size - 1 );
290
-
291
- t_router temp_router;
304
+ float vertical_router_separation = (mesh_region_end_y - mesh_region_start_y) / (mesh_size - 1 );
305
+ float horizontal_router_separation = (mesh_region_end_x - mesh_region_start_x) / (mesh_size - 1 );
292
306
293
307
// improper region check
294
- if ((vertical_router_separation <= 0 ) || (horizontal_router_separation <= 0 )) {
308
+ if (vertical_router_separation <= 0 || horizontal_router_separation <= 0 ||
309
+ mesh_region_end_layer < mesh_region_start_layer) {
295
310
archfpga_throw (loc_data.filename_c_str (), loc_data.line (mesh_topology_tag),
296
311
" The NoC region is invalid." );
297
312
}
298
313
299
314
// create routers and their connections
300
315
// start with router id 0 (bottom left of the chip) to the maximum router id (top right of the chip)
301
- for (int j = 0 ; j < mesh_size; j++) {
302
- for (int i = 0 ; i < mesh_size; i++) {
303
- // assign router id
304
- temp_router.id = (mesh_size * j) + i;
305
-
306
- // calculate router position
307
- /* The first and last router of each column or row will be located on the mesh region boundary,
308
- * the remaining routers will be placed within the region and seperated from other routers
309
- * using the distance calculated previously.
310
- */
311
- temp_router.device_x_position = (i * horizontal_router_separation) + mesh_region_start_x;
312
- temp_router.device_y_position = (j * vertical_router_separation) + mesh_region_start_y;
313
-
314
- // assign connections
315
- // check if there is a router to the left
316
- if ((i - 1 ) >= 0 ) {
317
- // add the left router as a connection
318
- temp_router.connection_list .push_back ((mesh_size * j) + i - 1 );
319
- }
316
+ for (int l = mesh_region_start_layer; l <= mesh_region_end_layer; l++) {
317
+ for (int j = 0 ; j < mesh_size; j++) {
318
+ for (int i = 0 ; i < mesh_size; i++) {
319
+ t_router temp_router;
320
+
321
+ // assign router id
322
+ temp_router.id = (mesh_size * mesh_size * (l - mesh_region_start_layer)) + (mesh_size * j) + i;
323
+
324
+ // calculate router position
325
+ /* The first and last router of each column or row will be located on the mesh region boundary,
326
+ * the remaining routers will be placed within the region and seperated from other routers
327
+ * using the distance calculated previously.
328
+ */
329
+ temp_router.device_x_position = (i * horizontal_router_separation) + mesh_region_start_x;
330
+ temp_router.device_y_position = (j * vertical_router_separation) + mesh_region_start_y;
331
+ temp_router.device_layer_position = l;
332
+
333
+ // assign connections
334
+
335
+ // check if there is a router to the left
336
+ if (i >= 1 ) {
337
+ // add the left router as a connection
338
+ temp_router.connection_list .push_back (temp_router.id - 1 );
339
+ }
320
340
321
- // check if there is a router to the top
322
- if ((j + 1 ) <= ( mesh_size - 1 ) ) {
323
- // add the top router as a connection
324
- temp_router.connection_list .push_back ((mesh_size * (j + 1 )) + i );
325
- }
341
+ // check if there is a router to the top
342
+ if (j <= mesh_size - 2 ) {
343
+ // add the top router as a connection
344
+ temp_router.connection_list .push_back (temp_router. id + mesh_size );
345
+ }
326
346
327
- // check if there is a router to the right
328
- if ((i + 1 ) <= ( mesh_size - 1 ) ) {
329
- // add the router located to the right
330
- temp_router.connection_list .push_back ((mesh_size * j) + i + 1 );
331
- }
347
+ // check if there is a router to the right
348
+ if (i <= mesh_size - 2 ) {
349
+ // add the router located to the right
350
+ temp_router.connection_list .push_back (temp_router. id + 1 );
351
+ }
332
352
333
- // check of there is a router below
334
- if ((j - 1 ) >= ( 0 ) ) {
335
- // add the bottom router as a connection
336
- temp_router.connection_list .push_back ((mesh_size * (j - 1 )) + i );
337
- }
353
+ // check if there is a router below
354
+ if (j >= 1 ) {
355
+ // add the bottom router as a connection
356
+ temp_router.connection_list .push_back (temp_router. id - mesh_size );
357
+ }
338
358
339
- // add the router to the list
340
- noc_ref->router_list .push_back (temp_router);
359
+ // check if there is a router on the layer above
360
+ if (l < mesh_region_end_layer) {
361
+ temp_router.connection_list .push_back (temp_router.id + (mesh_size * mesh_size));
362
+ }
341
363
342
- // clear the current router information for the next router
343
- temp_router.connection_list .clear ();
364
+ // check if there is a router on the layer below
365
+ if (l > mesh_region_start_layer) {
366
+ temp_router.connection_list .push_back (temp_router.id - (mesh_size * mesh_size));
367
+ }
368
+
369
+ // add the router to the list
370
+ noc_ref->router_list .push_back (temp_router);
371
+ }
344
372
}
345
373
}
346
374
}
0 commit comments