@@ -178,9 +178,15 @@ struct RR_Graph_Builder {
178
178
std::unordered_map<std::tuple<int /* timing_model*/ , bool /* buffered*/ >, int /* idx*/ , hash_tuple::hash<std::tuple<int , bool >>> pips_models_;
179
179
std::unordered_map<std::tuple<int /* node_id*/ , int /* node_id*/ >, std::tuple<int /* switch_id*/ , int /* tile_id */ , std::tuple<int /* name*/ , int /* wire0*/ , int /* wire1*/ , bool /* forward*/ >>, hash_tuple::hash<std::tuple<int , int >>> pips_;
180
180
181
- std::map<std::tuple<int , int >, int > wire_to_node_;
181
+ std::unordered_map<std::tuple<int , int >,
182
+ int ,
183
+ hash_tuple::hash<std::tuple<int ,int >>> wire_to_node_;
182
184
std::unordered_map<int , std::set<location>> node_to_locs_;
183
- std::map<std::tuple<int , int > /* <node, tile_id>*/ , int /* segment type*/ > node_tile_to_segment_;
185
+ std::unordered_map<std::tuple<int , int > /* <node, tile_id>*/ ,
186
+ int /* segment type*/ ,
187
+ hash_tuple::hash<std::tuple<int ,int >>> node_tile_to_segment_;
188
+ std::unordered_map<int , std::pair<float , float >> node_to_RC_;
189
+ int total_node_count_;
184
190
185
191
/*
186
192
* Offsets for FPGA Interchange node processing
@@ -246,6 +252,8 @@ struct RR_Graph_Builder {
246
252
}
247
253
248
254
std::string str (int idx) {
255
+ if (idx == -1 )
256
+ return std::string (" constant_block" );
249
257
return std::string (ar_.getStrList ()[idx].cStr ());
250
258
}
251
259
@@ -379,10 +387,10 @@ struct RR_Graph_Builder {
379
387
device_ctx_.rr_switch_inf .reserve (seen.size () + 1 );
380
388
int id = 2 ;
381
389
make_room_in_vector (&device_ctx_.rr_switch_inf , 0 );
382
- fill_switch (device_ctx_.rr_switch_inf [0 ], 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
390
+ fill_switch (device_ctx_.rr_switch_inf [RRSwitchId ( 0 ) ], 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
383
391
vtr::strdup (" short" ), SwitchType::SHORT);
384
392
make_room_in_vector (&device_ctx_.rr_switch_inf , 1 );
385
- fill_switch (device_ctx_.rr_switch_inf [1 ], 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
393
+ fill_switch (device_ctx_.rr_switch_inf [RRSwitchId ( 1 ) ], 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
386
394
vtr::strdup (" generic" ), SwitchType::MUX);
387
395
const auto & pip_models = ar_.getPipTimings ();
388
396
float R, Cin, Cout, Cint, Tdel;
@@ -423,7 +431,7 @@ struct RR_Graph_Builder {
423
431
type = buffered ? SwitchType::MUX : SwitchType::PASS_GATE;
424
432
mux_trans_size = buffered ? 1 : 0 ;
425
433
426
- fill_switch (device_ctx_.rr_switch_inf [id ], R, Cin, Cout, Cint, Tdel,
434
+ fill_switch (device_ctx_.rr_switch_inf [RRSwitchId (id) ], R, Cin, Cout, Cint, Tdel,
427
435
mux_trans_size, 0 , vtr::strdup (switch_name.c_str ()), type);
428
436
429
437
id++;
@@ -434,32 +442,121 @@ struct RR_Graph_Builder {
434
442
* Create mapping form tile_id to its location
435
443
*/
436
444
void create_tile_id_to_loc () {
445
+ int max_height = 0 ;
437
446
for (const auto & tile : ar_.getTileList ()) {
438
447
tile_to_loc_[tile.getName ()] = location (tile.getCol () + 1 , tile.getRow () + 1 );
448
+ max_height = std::max (max_height, (int )(tile.getRow () +1 ));
439
449
loc_to_tile_[location (tile.getCol () + 1 , tile.getRow () + 1 )] = tile.getName ();
440
450
}
451
+ /* tile with name -1 is assosiated with constant source tile */
452
+ tile_to_loc_[-1 ] = location (1 , max_height + 1 );
453
+ loc_to_tile_[location (1 , max_height + 1 )] = -1 ;
441
454
}
442
455
443
456
/*
444
457
* Create uniq id for each FPGA Interchange node.
445
458
* Create mapping from wire to node id and from node id to its locations
446
459
* These ids are used later for site pins and pip conections (rr_edges)
447
460
*/
461
+ void process_const_nodes () {
462
+ for (const auto & tile : ar_.getTileList ()) {
463
+ int tile_id = tile.getName ();
464
+ auto tile_type = ar_.getTileTypeList ()[tile.getType ()];
465
+ auto wires = tile_type.getWires ();
466
+ for (const auto & constant : tile_type.getConstants ()){
467
+ int const_id = constant.getConstant () == Device::ConstantType::VCC ? 1 : 0 ;
468
+ for (const auto wire_id : constant.getWires ()) {
469
+ wire_to_node_[std::make_tuple (tile_id, wires[wire_id])] = const_id;
470
+ node_to_locs_[const_id].insert (tile_to_loc_[tile_id]);
471
+ if (wire_name_to_seg_idx_.find (str (wires[wire_id])) == wire_name_to_seg_idx_.end ())
472
+ wire_name_to_seg_idx_[str (wires[wire_id])] = -1 ;
473
+ node_tile_to_segment_[std::make_tuple (const_id, tile_id)] = wire_name_to_seg_idx_[str (wires[wire_id])];
474
+ }
475
+ }
476
+ }
477
+ for (const auto & node_source : ar_.getConstants ().getNodeSources ()) {
478
+ int tile_id = node_source.getTile ();
479
+ int wire_id = node_source.getWire ();
480
+ int const_id = node_source.getConstant () == Device::ConstantType::VCC ? 1 : 0 ;
481
+ wire_to_node_[std::make_tuple (tile_id, wire_id)] = const_id;
482
+ node_to_locs_[const_id].insert (tile_to_loc_[tile_id]);
483
+ if (wire_name_to_seg_idx_.find (str (wire_id)) == wire_name_to_seg_idx_.end ())
484
+ wire_name_to_seg_idx_[str (wire_id)] = -1 ;
485
+ node_tile_to_segment_[std::make_tuple (const_id, tile_id)] = wire_name_to_seg_idx_[str (wire_id)];
486
+ }
487
+ for (int i = 0 ; i < 2 ; ++i) {
488
+ wire_to_node_[std::make_tuple (-1 , i)] = i;
489
+ node_to_locs_[i].insert (tile_to_loc_[-1 ]);
490
+ node_tile_to_segment_[std::make_tuple (i, -1 )] = -1 ;
491
+ }
492
+ }
493
+
448
494
void create_uniq_node_ids () {
449
- int id = 0 ;
495
+ /*
496
+ Process constant sources
497
+ */
498
+ process_const_nodes ();
499
+ /*
500
+ Process nodes
501
+ */
502
+ int id = 2 ;
503
+ bool constant_node;
504
+ int node_id;
450
505
for (const auto & node : ar_.getNodes ()) {
506
+ constant_node = false ;
507
+ /*
508
+ Nodes connected to constant sources should be combined into single constant node
509
+ */
451
510
for (const auto & wire_id_ : node.getWires ()) {
452
511
const auto & wire = ar_.getWires ()[wire_id_];
453
512
int tile_id = wire.getTile ();
454
513
int wire_id = wire.getWire ();
455
- wire_to_node_[std::make_tuple (tile_id, wire_id)] = id;
456
- node_to_locs_[id].insert (tile_to_loc_[tile_id]);
514
+ if (wire_to_node_.find (std::make_tuple (tile_id, wire_id)) != wire_to_node_.end () &&
515
+ wire_to_node_[std::make_tuple (tile_id, wire_id)] < 2 ) {
516
+ constant_node = true ;
517
+ node_id = wire_to_node_[std::make_tuple (tile_id, wire_id)];
518
+ }
519
+ }
520
+ if (!constant_node){
521
+ node_id = id++;
522
+ }
523
+ float capacitance = 0.0 , resistance = 0.0 ; // Some random data
524
+ if (node_to_RC_.find (node_id) == node_to_RC_.end ()) {
525
+ node_to_RC_[node_id] = std::pair<float , float >(0 , 0 );
526
+ capacitance = 0.000000001 ; resistance = 5.7 ;
527
+ }
528
+ if (ar_.hasNodeTimings ()) {
529
+ auto model = ar_.getNodeTimings ()[node.getNodeTiming ()];
530
+ capacitance = get_corner_value (model.getCapacitance (), " slow" , " typ" );
531
+ resistance = get_corner_value (model.getResistance (), " slow" , " typ" );
532
+ }
533
+ node_to_RC_[node_id].first += resistance;
534
+ node_to_RC_[node_id].second += capacitance;
535
+ #ifdef DEBUG
536
+ if (constant_node) {
537
+ const auto & wires = ar_.getWires ();
538
+ std::tuple<int , int > base_wire_ (wires[node.getWires ()[0 ]].getTile (), wires[node.getWires ()[0 ]].getWire ());
539
+ VTR_LOG (" Constant_node: %s\n " , wire_to_node_[base_wire_] == 1 ? " VCC\0 " : " GND\0 " );
540
+ for (const auto & wire_id_ : node.getWires ()) {
541
+ const auto & wire = ar_.getWires ()[wire_id_];
542
+ int tile_id = wire.getTile ();
543
+ int wire_id = wire.getWire ();
544
+ VTR_LOG (" tile:%s wire:%s\n " , str (tile_id).c_str (), str (wire_id).c_str ());
545
+ }
546
+ }
547
+ #endif
548
+ for (const auto & wire_id_ : node.getWires ()) {
549
+ const auto & wire = ar_.getWires ()[wire_id_];
550
+ int tile_id = wire.getTile ();
551
+ int wire_id = wire.getWire ();
552
+ wire_to_node_[std::make_tuple (tile_id, wire_id)] = node_id;
553
+ node_to_locs_[node_id].insert (tile_to_loc_[tile_id]);
457
554
if (wire_name_to_seg_idx_.find (str (wire_id)) == wire_name_to_seg_idx_.end ())
458
555
wire_name_to_seg_idx_[str (wire_id)] = -1 ;
459
- node_tile_to_segment_[std::make_tuple (id , tile_id)] = wire_name_to_seg_idx_[str (wire_id)];
556
+ node_tile_to_segment_[std::make_tuple (node_id , tile_id)] = wire_name_to_seg_idx_[str (wire_id)];
460
557
}
461
- id++;
462
558
}
559
+ total_node_count_ = id;
463
560
}
464
561
465
562
/*
@@ -473,8 +570,6 @@ struct RR_Graph_Builder {
473
570
const auto & tile_type = ar_.getTileTypeList ()[tile.getType ()];
474
571
475
572
for (const auto & pip : tile_type.getPips ()) {
476
- if (pip.isPseudoCells ())
477
- continue ;
478
573
int wire0_name, wire1_name;
479
574
int node0, node1;
480
575
int switch_id;
@@ -487,6 +582,9 @@ struct RR_Graph_Builder {
487
582
continue ;
488
583
node0 = wire_to_node_[std::make_tuple (tile_id, wire0_name)];
489
584
node1 = wire_to_node_[std::make_tuple (tile_id, wire1_name)];
585
+ // Allow for pseudopips that connect from/to VCC/GND
586
+ if (pip.isPseudoCells () && (node0 > 1 && node1> 1 ))
587
+ continue ;
490
588
491
589
used_by_pip_.emplace (node0, loc);
492
590
used_by_pip_.emplace (node1, loc);
@@ -903,6 +1001,7 @@ struct RR_Graph_Builder {
903
1001
}
904
1002
905
1003
void process_set (std::unordered_set<intermediate_node*>& set,
1004
+ std::unordered_set<location, hash_tuple::hash<location>>& nodes_used,
906
1005
std::map<location, intermediate_node*>& existing_nodes,
907
1006
std::map<location, std::tuple<location, e_rr_type, int >>& local_redirect,
908
1007
float R,
@@ -920,6 +1019,7 @@ struct RR_Graph_Builder {
920
1019
auto key = std::make_tuple (add_vec (start->loc , offset), chan_type);
921
1020
idx = virtual_chan_loc_map_[key].size ();
922
1021
do {
1022
+ nodes_used.insert (end->loc );
923
1023
len++;
924
1024
local_redirect.emplace (end->loc , std::make_tuple (add_vec (start->loc , offset), chan_type, idx));
925
1025
if (!end->links [side])
@@ -962,6 +1062,7 @@ struct RR_Graph_Builder {
962
1062
float R,
963
1063
float C) {
964
1064
std::unordered_set<intermediate_node*> chanxs, chanys;
1065
+ std::unordered_set<location, hash_tuple::hash<location>> nodes_in_chanxs, nodes_in_chanys;
965
1066
bool chanx_start, chany_start, single_node;
966
1067
for (auto const & i : existing_nodes) {
967
1068
single_node = true ;
@@ -973,11 +1074,15 @@ struct RR_Graph_Builder {
973
1074
chanx_start = pip_uses_node_loc (node_id, left_node->loc ) || left_node->links [TOP_EDGE] || left_node->links [BOTTOM_EDGE];
974
1075
} else {
975
1076
chanx_start = i.second ->has_pins || single_node;
1077
+ if (i.second ->links [RIGHT_EDGE])
1078
+ nodes_in_chanxs.insert (i.first );
976
1079
}
977
1080
if (i.second ->links [TOP_EDGE]) {
978
1081
intermediate_node* top_node = existing_nodes[add_vec (i.second ->loc , offsets[TOP_EDGE])];
979
1082
chany_start = pip_uses_node_loc (node_id, top_node->loc ) || pin_uses_node_loc (node_id, top_node->loc );
980
1083
chany_start |= top_node->links [LEFT_EDGE] || top_node->links [RIGHT_EDGE];
1084
+ } else if (i.second ->links [BOTTOM_EDGE]) {
1085
+ nodes_in_chanys.insert (i.first );
981
1086
}
982
1087
if (chanx_start)
983
1088
chanxs.insert (i.second );
@@ -987,25 +1092,35 @@ struct RR_Graph_Builder {
987
1092
988
1093
std::map<location, std::tuple<location, e_rr_type, int >> local_redirect_x, local_redirect_y;
989
1094
990
- process_set (chanys, existing_nodes, local_redirect_y, R, C, location (0 , 0 ), BOTTOM_EDGE, CHANY);
991
- process_set (chanxs, existing_nodes, local_redirect_x, R, C, offsets[BOTTOM_EDGE], RIGHT_EDGE, CHANX);
1095
+ process_set (chanys, nodes_in_chanys, existing_nodes, local_redirect_y, R, C, location (0 , 0 ), BOTTOM_EDGE, CHANY);
1096
+ process_set (chanxs, nodes_in_chanxs, existing_nodes, local_redirect_x, R, C, offsets[BOTTOM_EDGE], RIGHT_EDGE, CHANX);
992
1097
connect_base_on_redirects (chanys, TOP_EDGE, local_redirect_y, local_redirect_y);
993
- connect_base_on_redirects (chanxs, LEFT_EDGE, local_redirect_x, local_redirect_y);
1098
+ // connect_base_on_redirects(chanxs, LEFT_EDGE, local_redirect_x, local_redirect_y);
994
1099
connect_base_on_redirects (chanxs, LEFT_EDGE, local_redirect_x, local_redirect_x);
995
- connect_base_on_redirects (chanys, TOP_EDGE, local_redirect_y, local_redirect_x);
1100
+ // connect_base_on_redirects(chanys, TOP_EDGE, local_redirect_y, local_redirect_x);
996
1101
997
1102
bool ry, rx;
1103
+ for (auto i : nodes_in_chanys) {
1104
+ location node = i;
1105
+ if (nodes_in_chanxs.find (i) != nodes_in_chanxs.end ()){
1106
+ ry = local_redirect_y.find (node) != local_redirect_y.end ();
1107
+ rx = local_redirect_x.find (node) != local_redirect_x.end ();
1108
+ location x,y;
1109
+ if (rx)
1110
+ x = node;
1111
+ else
1112
+ x = add_vec (node, offsets[RIGHT_EDGE]);
1113
+ if (ry)
1114
+ y = node;
1115
+ else
1116
+ y = add_vec (node, offsets[BOTTOM_EDGE]);
1117
+ add_short (y, x, local_redirect_y, local_redirect_x);
1118
+ }
1119
+ }
1120
+
998
1121
for (auto const node : existing_nodes) {
999
1122
ry = local_redirect_y.find (node.first ) != local_redirect_y.end ();
1000
1123
rx = local_redirect_x.find (node.first ) != local_redirect_x.end ();
1001
- if (node.second ->links [RIGHT_EDGE] && node.second ->links [BOTTOM_EDGE]) {
1002
- location bottom_node = add_vec (node.first , offsets[BOTTOM_EDGE]);
1003
- location right_node = add_vec (node.first , offsets[RIGHT_EDGE]);
1004
- add_short (bottom_node, right_node, local_redirect_y, local_redirect_x);
1005
- }
1006
- if (ry && rx) {
1007
- add_short (node.first , node.first , local_redirect_y, local_redirect_x);
1008
- }
1009
1124
if (rx) {
1010
1125
virtual_redirect_.emplace (std::make_tuple (node_id, node.first ), local_redirect_x[node.first ]);
1011
1126
} else if (ry) {
@@ -1037,10 +1152,7 @@ struct RR_Graph_Builder {
1037
1152
* Process FPGA Interchange nodes
1038
1153
*/
1039
1154
void process_nodes () {
1040
- auto wires = ar_.getWires ();
1041
- for (auto const & node : ar_.getNodes ()) {
1042
- std::tuple<int , int > base_wire_ (wires[node.getWires ()[0 ]].getTile (), wires[node.getWires ()[0 ]].getWire ());
1043
- int node_id = wire_to_node_[base_wire_];
1155
+ for (int node_id = 0 ; node_id < total_node_count_; ++node_id) {
1044
1156
int seg_id;
1045
1157
if (usefull_node_.find (node_id) == usefull_node_.end ()) {
1046
1158
continue ;
@@ -1060,12 +1172,8 @@ struct RR_Graph_Builder {
1060
1172
}
1061
1173
node_id_count_[node_id] = div ;
1062
1174
VTR_ASSERT (div > 0 );
1063
- float capacitance = 0.000000001 , resistance = 5.7 ; // Some random data
1064
- if (ar_.hasNodeTimings ()) {
1065
- auto model = ar_.getNodeTimings ()[node.getNodeTiming ()];
1066
- capacitance = get_corner_value (model.getCapacitance (), " slow" , " typ" ) / div ;
1067
- resistance = get_corner_value (model.getResistance (), " slow" , " typ" ) / div ;
1068
- }
1175
+ float resistance = node_to_RC_[node_id].first / div ;
1176
+ float capacitance = node_to_RC_[node_id].second / div ;
1069
1177
graph_reduction_stage2 (node_id, existing_nodes, resistance, capacitance);
1070
1178
delete_nodes (existing_nodes);
1071
1179
}
@@ -1147,6 +1255,16 @@ struct RR_Graph_Builder {
1147
1255
it = next_good_site (it + 1 , tile);
1148
1256
}
1149
1257
}
1258
+ /*
1259
+ Add constant ource
1260
+ */
1261
+ sink_source_loc_map_[-1 ].resize (2 );
1262
+ for ( auto i : {0 , 1 }) {
1263
+ location loc = tile_to_loc_[-1 ];
1264
+ used_by_pin_.insert (std::make_tuple (i, loc));
1265
+ usefull_node_.insert (i);
1266
+ sink_source_loc_map_[-1 ][i] = std::make_tuple (false , 0 , i);
1267
+ }
1150
1268
}
1151
1269
1152
1270
void sweep (location loc,
@@ -1382,8 +1500,12 @@ struct RR_Graph_Builder {
1382
1500
sink_src = mux_id;
1383
1501
src = input ? track_id : pin_id;
1384
1502
1385
- device_ctx_.rr_graph_builder .emplace_back_edge (RRNodeId (src), RRNodeId (sink_src), 0 );
1386
- device_ctx_.rr_graph_builder .emplace_back_edge (RRNodeId (sink_src), RRNodeId (sink), sink == track_id ? 1 : 0 );
1503
+ device_ctx_.rr_graph_builder .emplace_back_edge (RRNodeId (src),
1504
+ RRNodeId (sink_src),
1505
+ src == track_id ? 1 :0 );
1506
+ device_ctx_.rr_graph_builder .emplace_back_edge (RRNodeId (sink_src),
1507
+ RRNodeId (sink),
1508
+ sink == track_id ? 1 : 0 );
1387
1509
}
1388
1510
}
1389
1511
}
0 commit comments