Skip to content

Commit 2e54c5c

Browse files
committed
Finish initial implementation of explicit port definitions.
Signed-off-by: Keith Rothman <[email protected]>
1 parent c13e09f commit 2e54c5c

File tree

6 files changed

+113
-26
lines changed

6 files changed

+113
-26
lines changed

libs/libarchfpga/src/physical_types.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,12 @@ std::vector<int> t_physical_tile_type::get_clock_pins_indices() const {
110110
int clock_pins_start_idx = 0;
111111
int clock_pins_stop_idx = 0;
112112

113-
for (int capacity_num = 0; capacity_num < this->capacity; capacity_num++) {
113+
int num_capacity = 1;
114+
if (capacity_type == e_capacity_type::DUPLICATE) {
115+
num_capacity = this->capacity;
116+
}
117+
118+
for (int capacity_num = 0; capacity_num < num_capacity; capacity_num++) {
114119
// Ranges are picked on the basis that pins are ordered: inputs, outputs, then clock pins
115120
// This is because ProcessPb_type assigns pb_type port indices in that order and
116121
// SetupPinLocationsAndPinClasses assigns t_logical_block_type_ptr pin indices in the order of port indices

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,6 @@ static std::pair<int, std::pair<int, int>> ProcessPinString(pugi::xml_node Locat
912912

913913
token_index++;
914914
token = tokens[token_index];
915-
916915
}
917916

918917
if (token.type != TOKEN_DOT) {

vpr/src/base/read_route.cpp

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "rr_graph.h"
2424
#include "vtr_assert.h"
2525
#include "vtr_util.h"
26+
#include "vtr_time.h"
2627
#include "tatum/echo_writer.hpp"
2728
#include "vtr_log.h"
2829
#include "check_route.h"
@@ -40,6 +41,7 @@
4041
#include "echo_files.h"
4142
#include "route_common.h"
4243
#include "read_route.h"
44+
#include "rr_graph2.h"
4345

4446
/*************Functions local to this module*************/
4547
static void process_route(std::ifstream& fp, const char* filename, int& lineno);
@@ -192,7 +194,7 @@ static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name,
192194
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno) {
193195
/* Not a global net. Goes through every node and add it into trace.head*/
194196

195-
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
197+
auto& cluster_ctx = g_vpr_ctx.clustering();
196198
auto& device_ctx = g_vpr_ctx.mutable_device();
197199
auto& route_ctx = g_vpr_ctx.mutable_routing();
198200
auto& place_ctx = g_vpr_ctx.placement();
@@ -206,6 +208,45 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
206208
std::string input;
207209
std::vector<std::string> tokens;
208210

211+
// Build lookup from SOURCE/SINK node to ClusterBlockId.
212+
std::unordered_map<int, ClusterBlockId> node_to_block;
213+
214+
{
215+
vtr::ScopedStartFinishTimer timer("Building ClusterBlockId lookup");
216+
217+
for (auto net_id : cluster_ctx.clb_nlist.nets()) {
218+
int pin_count = 0;
219+
for (auto pin_id : cluster_ctx.clb_nlist.net_pins(net_id)) {
220+
auto block_id = cluster_ctx.clb_nlist.pin_block(pin_id);
221+
222+
const auto* logical_tile = cluster_ctx.clb_nlist.block_type(block_id);
223+
const auto* physical_tile = physical_tile_type(block_id);
224+
VTR_ASSERT(block_id);
225+
int i = place_ctx.block_locs[block_id].loc.x;
226+
int j = place_ctx.block_locs[block_id].loc.y;
227+
228+
int logical_pin_index = cluster_ctx.clb_nlist.pin_logical_index(pin_id);
229+
int physical_pin_index = get_physical_pin(
230+
physical_tile, place_ctx.block_locs[block_id].loc.z,
231+
logical_tile, logical_pin_index);
232+
int physical_pin_class = physical_tile->pin_class[physical_pin_index];
233+
int class_inode = get_rr_node_index(device_ctx.rr_node_indices,
234+
i, j, (pin_count == 0 ? SOURCE : SINK), /* First pin is driver */
235+
physical_pin_class);
236+
237+
auto result = node_to_block.insert(std::make_pair(class_inode, block_id));
238+
if (!result.second && result.first->second != block_id) {
239+
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
240+
"Clustered netlist has inconsistent rr node mapping, class rr node %d has two block ids %zu and %zu?",
241+
class_inode, (size_t)block_id, result.first->second);
242+
}
243+
pin_count++;
244+
}
245+
}
246+
247+
VTR_LOG("ClusterBlockId lookup has %zu entries\n", node_to_block.size());
248+
}
249+
209250
/*Walk through every line that begins with Node:*/
210251
while (std::getline(fp, input)) {
211252
++lineno;
@@ -285,9 +326,22 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
285326
if (tokens[6 + offset] != "Switch:") {
286327
/*This is an opin or ipin, process its pin nums*/
287328
if (!is_io_type(device_ctx.grid[x][y].type) && (tokens[2] == "IPIN" || tokens[2] == "OPIN")) {
329+
// Convert this IPIN/OPIN back to class.
330+
auto rr_type = device_ctx.rr_nodes[inode].type();
331+
VTR_ASSERT(rr_type == IPIN || rr_type == OPIN);
288332
int pin_num = device_ctx.rr_nodes[inode].ptc_num();
289-
int height_offset = device_ctx.grid[x][y].height_offset;
290-
ClusterBlockId iblock = place_ctx.grid_blocks[x][y - height_offset].blocks[0];
333+
int iclass = device_ctx.grid[x][y].type->pin_class[pin_num];
334+
int class_inode = get_rr_node_index(device_ctx.rr_node_indices,
335+
x, y, (rr_type == OPIN ? SOURCE : SINK), iclass);
336+
337+
auto itr = node_to_block.find(class_inode);
338+
if (itr == node_to_block.end()) {
339+
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
340+
"Class RR node %d does not have an associated ClusterBlockId?", class_inode);
341+
}
342+
343+
ClusterBlockId iblock = itr->second;
344+
VTR_ASSERT(iblock);
291345
t_pb_graph_pin* pb_pin = get_pb_graph_node_pin_from_block_pin(iblock, pin_num);
292346
t_pb_type* pb_type = pb_pin->parent_node->pb_type;
293347

vpr/src/base/vpr_context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ struct RoutingContext : public Context {
282282
vtr::vector<ClusterNetId, std::unordered_set<int>> trace_nodes;
283283

284284
vtr::vector<ClusterNetId, std::vector<int>> net_rr_terminals; /* [0..num_nets-1][0..num_pins-1] */
285+
std::unordered_map<int, ClusterBlockId> rr_net_map;
285286

286287
vtr::vector<ClusterBlockId, std::vector<int>> rr_blk_source; /* [0..num_blocks-1][0..num_class-1] */
287288

vpr/src/route/route_common.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ static t_trace_branch traceback_branch(int node, std::unordered_set<int>& main_b
9696
static std::pair<t_trace*, t_trace*> add_trace_non_configurable(t_trace* head, t_trace* tail, int node, std::unordered_set<int>& visited);
9797
static std::pair<t_trace*, t_trace*> add_trace_non_configurable_recurr(int node, std::unordered_set<int>& visited, int depth = 0);
9898

99-
static vtr::vector<ClusterNetId, std::vector<int>> load_net_rr_terminals(const t_rr_node_indices& L_rr_node_indices);
99+
static vtr::vector<ClusterNetId, std::vector<int>> load_net_rr_terminals(const t_rr_node_indices& L_rr_node_indices,
100+
std::unordered_map<int, ClusterBlockId>* rr_net_map);
100101
static vtr::vector<ClusterBlockId, std::vector<int>> load_rr_clb_sources(const t_rr_node_indices& L_rr_node_indices);
101102

102103
static t_clb_opins_used alloc_and_load_clb_opins_used_locally();
@@ -496,7 +497,7 @@ void init_route_structs(int bb_factor) {
496497
init_heap(device_ctx.grid);
497498

498499
//Various look-ups
499-
route_ctx.net_rr_terminals = load_net_rr_terminals(device_ctx.rr_node_indices);
500+
route_ctx.net_rr_terminals = load_net_rr_terminals(device_ctx.rr_node_indices, &route_ctx.rr_net_map);
500501
route_ctx.route_bb = load_route_bb(bb_factor);
501502
route_ctx.rr_blk_source = load_rr_clb_sources(device_ctx.rr_node_indices);
502503
route_ctx.clb_opins_used_locally = alloc_and_load_clb_opins_used_locally();
@@ -1031,7 +1032,11 @@ void reset_rr_node_route_structs() {
10311032
/* Allocates and loads the route_ctx.net_rr_terminals data structure. For each net it stores the rr_node *
10321033
* index of the SOURCE of the net and all the SINKs of the net [clb_nlist.nets()][clb_nlist.net_pins()]. *
10331034
* Entry [inet][pnum] stores the rr index corresponding to the SOURCE (opin) or SINK (ipin) of the pin. */
1034-
static vtr::vector<ClusterNetId, std::vector<int>> load_net_rr_terminals(const t_rr_node_indices& L_rr_node_indices) {
1035+
static vtr::vector<ClusterNetId, std::vector<int>> load_net_rr_terminals(
1036+
const t_rr_node_indices& L_rr_node_indices,
1037+
std::unordered_map<int, ClusterBlockId>* rr_net_map) {
1038+
VTR_ASSERT(rr_net_map != nullptr);
1039+
rr_net_map->clear();
10351040
vtr::vector<ClusterNetId, std::vector<int>> net_rr_terminals;
10361041

10371042
auto& cluster_ctx = g_vpr_ctx.clustering();
@@ -1061,6 +1066,16 @@ static vtr::vector<ClusterNetId, std::vector<int>> load_net_rr_terminals(const t
10611066
int inode = get_rr_node_index(L_rr_node_indices, i, j, (pin_count == 0 ? SOURCE : SINK), /* First pin is driver */
10621067
iclass);
10631068
net_rr_terminals[net_id][pin_count] = inode;
1069+
1070+
auto result = rr_net_map->insert(std::make_pair(inode, block_id));
1071+
// If the map already contains an entry for inode, make sure it
1072+
// is consistent with the existing entry.
1073+
if (!result.second && block_id != result.first->second) {
1074+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
1075+
"Clustered netlist has inconsistent rr node mapping, class rr node %d has two block ids %zu and %zu?",
1076+
inode, (size_t)block_id, (size_t)result.first->second);
1077+
}
1078+
10641079
pin_count++;
10651080
}
10661081
}
@@ -1513,11 +1528,18 @@ void print_route(FILE* fp, const vtr::vector<ClusterNetId, t_traceback>& traceba
15131528
fprintf(fp, "%d ", device_ctx.rr_nodes[inode].ptc_num());
15141529

15151530
if (!is_io_type(device_ctx.grid[ilow][jlow].type) && (rr_type == IPIN || rr_type == OPIN)) {
1531+
// Go from IPIN/OPIN to SOURCE/SINK
1532+
auto* type = device_ctx.grid[ilow][jlow].type;
15161533
int pin_num = device_ctx.rr_nodes[inode].ptc_num();
1517-
int xoffset = device_ctx.grid[ilow][jlow].width_offset;
1518-
int yoffset = device_ctx.grid[ilow][jlow].height_offset;
1519-
ClusterBlockId iblock = place_ctx.grid_blocks[ilow - xoffset][jlow - yoffset].blocks[0];
1520-
VTR_ASSERT(iblock);
1534+
int iclass = type->pin_class[pin_num];
1535+
int class_inode = get_rr_node_index(device_ctx.rr_node_indices,
1536+
ilow, jlow, (rr_type == OPIN ? SOURCE : SINK), iclass);
1537+
1538+
// Use the rr_net_map to go from class inode back to ClusterBlockId.
1539+
auto itr = route_ctx.rr_net_map.find(class_inode);
1540+
VTR_ASSERT(itr != route_ctx.rr_net_map.end());
1541+
ClusterBlockId iblock = itr->second;
1542+
15211543
t_pb_graph_pin* pb_pin = get_pb_graph_node_pin_from_block_pin(iblock, pin_num);
15221544
t_pb_type* pb_type = pb_pin->parent_node->pb_type;
15231545
fprintf(fp, " %s.%s[%d] ", pb_type->name, pb_pin->port->name, pb_pin->pin_number);

vpr/src/util/vpr_utils.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -192,15 +192,21 @@ std::string block_type_pin_index_to_name(t_physical_tile_type_ptr type, int pin_
192192

193193
std::string pin_name = type->name;
194194

195-
if (type->capacity > 1) {
196-
int pins_per_inst = type->num_pins / type->capacity;
197-
int inst_num = pin_index / pins_per_inst;
198-
pin_index %= pins_per_inst;
195+
if (type->capacity_type == e_capacity_type::DUPLICATE) {
196+
if (type->capacity > 1) {
197+
int pins_per_inst = type->num_pins / type->capacity;
198+
int inst_num = pin_index / pins_per_inst;
199+
pin_index %= pins_per_inst;
199200

200-
pin_name += "[" + std::to_string(inst_num) + "]";
201-
}
201+
pin_name += "[" + std::to_string(inst_num) + "]";
202+
}
202203

203-
pin_name += ".";
204+
pin_name += ".";
205+
} else {
206+
VTR_ASSERT(type->capacity_type == e_capacity_type::EXPLICIT);
207+
VTR_ASSERT(pin_index < type->num_pins);
208+
pin_name += ".";
209+
}
204210

205211
int curr_index = 0;
206212
for (auto const& port : type->ports) {
@@ -2058,18 +2064,18 @@ void place_sync_external_block_connections(ClusterBlockId iblk) {
20582064
auto physical_tile = physical_tile_type(iblk);
20592065
auto logical_block = clb_nlist.block_type(iblk);
20602066

2061-
VTR_ASSERT(physical_tile->num_pins % physical_tile->capacity == 0);
20622067
for (auto pin : clb_nlist.block_pins(iblk)) {
20632068
int logical_pin_index = clb_nlist.pin_logical_index(pin);
2064-
int new_physical_pin_index = get_physical_pin(
2069+
2070+
int new_physical_pin = get_physical_pin(
20652071
physical_tile, place_ctx.block_locs[iblk].loc.z,
20662072
logical_block, logical_pin_index);
2067-
2068-
auto result = place_ctx.physical_pins.find(pin);
2069-
if (result != place_ctx.physical_pins.end()) {
2070-
place_ctx.physical_pins[pin] = new_physical_pin_index;
2073+
auto iter = place_ctx.physical_pins.find(pin);
2074+
if (iter != place_ctx.physical_pins.end()) {
2075+
*iter = new_physical_pin;
20712076
} else {
2072-
place_ctx.physical_pins.insert(pin, new_physical_pin_index);
2077+
place_ctx.physical_pins.insert(
2078+
pin, new_physical_pin);
20732079
}
20742080
}
20752081
}

0 commit comments

Comments
 (0)