Skip to content

Commit 582300b

Browse files
litghostacomodi
authored andcommitted
Implement explicit ports.
Signed-off-by: Keith Rothman <[email protected]>
1 parent 4901679 commit 582300b

File tree

14 files changed

+373
-135
lines changed

14 files changed

+373
-135
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/physical_types.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,12 @@ enum class e_sb_type {
524524

525525
};
526526

527+
enum class e_capacity_type {
528+
DUPLICATE, // Capacity duplicates ports.
529+
EXPLICIT // Capacity increases the number of logical tiles, but does not
530+
// modify the physical ports.
531+
};
532+
527533
constexpr int NO_SWITCH = -1;
528534
constexpr int DEFAULT_SWITCH = -2;
529535

@@ -578,6 +584,7 @@ struct t_physical_tile_type {
578584
int num_clock_pins = 0;
579585

580586
int capacity = 0;
587+
e_capacity_type capacity_type = e_capacity_type::DUPLICATE;
581588

582589
int width = 0;
583590
int height = 0;
@@ -635,18 +642,20 @@ struct t_physical_tile_type {
635642
* vtr::bimap container.
636643
*/
637644
struct t_logical_pin {
645+
int z_index = -1;
638646
int pin = -1;
639647

640-
t_logical_pin(int value) {
648+
t_logical_pin(int z_index_value, int value) {
649+
z_index = z_index_value;
641650
pin = value;
642651
}
643652

644653
bool operator==(const t_logical_pin o) const {
645-
return pin == o.pin;
654+
return z_index == o.z_index && pin == o.pin;
646655
}
647656

648657
bool operator<(const t_logical_pin o) const {
649-
return pin < o.pin;
658+
return std::make_pair(z_index, pin) < std::make_pair(o.z_index, o.pin);
650659
}
651660
};
652661

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 186 additions & 58 deletions
Large diffs are not rendered by default.

vpr/src/base/ShowSetup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void printClusteredNetlistStats() {
7979
num_blocks_type[logical_block->index]++;
8080
if (is_io_type(physical_tile)) {
8181
for (j = 0; j < logical_block->pb_type->num_pins; j++) {
82-
int physical_pin = get_physical_pin(physical_tile, logical_block, j);
82+
int physical_pin = get_physical_pin(physical_tile, /*z_index=*/0, logical_block, j);
8383
auto pin_class = physical_tile->pin_class[physical_pin];
8484
auto class_inf = physical_tile->class_inf[pin_class];
8585

vpr/src/base/check_netlist.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static int check_connections_to_global_clb_pins(ClusterNetId net_id, int verbosi
9898
auto physical_type = pick_best_physical_type(logical_type);
9999

100100
int log_index = cluster_ctx.clb_nlist.pin_logical_index(pin_id);
101-
int pin_index = get_physical_pin(physical_type, logical_type, log_index);
101+
int pin_index = get_physical_pin(physical_type, /*z_index=*/0, logical_type, log_index);
102102

103103
if (physical_type->is_ignored_pin[pin_index] != net_is_ignored
104104
&& !is_io_type(physical_type)) {

vpr/src/base/read_netlist.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist) {
956956
block_type = clb_nlist.block_type(blk_id);
957957
auto tile_type = pick_best_physical_type(block_type);
958958
for (j = 0; j < block_type->pb_type->num_pins; j++) {
959-
int physical_pin = get_physical_pin(tile_type, block_type, j);
959+
int physical_pin = get_physical_pin(tile_type, /*z_index=*/0, block_type, j);
960960

961961
//Iterate through each pin of the block, and see if there is a net allocated/used for it
962962
clb_net_id = clb_nlist.block_net(blk_id, j);
@@ -1006,7 +1006,7 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist) {
10061006
block_type = clb_nlist.block_type(clb_nlist.pin_block(pin_id));
10071007
auto tile_type = pick_best_physical_type(block_type);
10081008
int logical_pin = clb_nlist.pin_logical_index(pin_id);
1009-
int physical_pin = get_physical_pin(tile_type, block_type, logical_pin);
1009+
int physical_pin = get_physical_pin(tile_type, /*z_index=*/0, block_type, logical_pin);
10101010

10111011
if (tile_type->is_ignored_pin[physical_pin] != is_ignored_net) {
10121012
VTR_LOG_WARN(

vpr/src/base/read_route.cpp

Lines changed: 76 additions & 17 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,22 +41,24 @@
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*************/
45-
static void process_route(std::ifstream& fp, const char* filename, int& lineno);
46-
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno);
47-
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno);
47+
static void process_route(std::ifstream& fp, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block);
48+
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block);
49+
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block);
4850
static void process_global_blocks(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno);
4951
static void format_coordinates(int& x, int& y, std::string coord, ClusterNetId net, const char* filename, const int lineno);
5052
static void format_pin_info(std::string& pb_name, std::string& port_name, int& pb_pin_num, std::string input);
53+
static void build_cluster_block_map(std::unordered_map<int, ClusterBlockId>* node_to_block);
5154
static std::string format_name(std::string name);
5255

5356
/*************Global Functions****************************/
5457
bool read_route(const char* route_file, const t_router_opts& router_opts, bool verify_file_digests) {
5558
/* Reads in the routing file to fill in the trace.head and t_clb_opins_used data structure.
5659
* Perform a series of verification tests to ensure the netlist, placement, and routing
5760
* files match */
58-
auto& device_ctx = g_vpr_ctx.mutable_device();
61+
auto& device_ctx = g_vpr_ctx.device();
5962
auto& place_ctx = g_vpr_ctx.placement();
6063
/* Begin parsing the file */
6164
VTR_LOG("Begin loading FPGA routing file.\n");
@@ -103,8 +106,12 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v
103106
header[2].c_str(), header[4].c_str(), device_ctx.grid.width(), device_ctx.grid.height());
104107
}
105108

109+
// Build lookup from SOURCE/SINK node to ClusterBlockId.
110+
std::unordered_map<int, ClusterBlockId> node_to_block;
111+
build_cluster_block_map(&node_to_block);
112+
106113
/* Read in every net */
107-
process_route(fp, route_file, lineno);
114+
process_route(fp, route_file, lineno, node_to_block);
108115

109116
fp.close();
110117

@@ -130,7 +137,7 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v
130137
return is_feasible;
131138
}
132139

133-
static void process_route(std::ifstream& fp, const char* filename, int& lineno) {
140+
static void process_route(std::ifstream& fp, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block) {
134141
/*Walks through every net and add the routing appropriately*/
135142
std::string input;
136143
std::vector<std::string> tokens;
@@ -144,16 +151,56 @@ static void process_route(std::ifstream& fp, const char* filename, int& lineno)
144151
continue; //Skip commented lines
145152
} else if (tokens[0] == "Net") {
146153
ClusterNetId inet(atoi(tokens[1].c_str()));
147-
process_nets(fp, inet, tokens[2], tokens, filename, lineno);
154+
process_nets(fp, inet, tokens[2], tokens, filename, lineno, node_to_block);
148155
}
149156
}
150157

151158
tokens.clear();
152159
}
153160

154-
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno) {
161+
static void build_cluster_block_map(std::unordered_map<int, ClusterBlockId>* node_to_block) {
162+
auto& cluster_ctx = g_vpr_ctx.clustering();
163+
auto& place_ctx = g_vpr_ctx.placement();
164+
auto& device_ctx = g_vpr_ctx.device();
165+
166+
vtr::ScopedStartFinishTimer timer("Building ClusterBlockId lookup");
167+
168+
for (auto net_id : cluster_ctx.clb_nlist.nets()) {
169+
int pin_count = 0;
170+
for (auto pin_id : cluster_ctx.clb_nlist.net_pins(net_id)) {
171+
auto block_id = cluster_ctx.clb_nlist.pin_block(pin_id);
172+
173+
const auto* logical_tile = cluster_ctx.clb_nlist.block_type(block_id);
174+
const auto* physical_tile = physical_tile_type(block_id);
175+
VTR_ASSERT(block_id);
176+
int i = place_ctx.block_locs[block_id].loc.x;
177+
int j = place_ctx.block_locs[block_id].loc.y;
178+
179+
int logical_pin_index = cluster_ctx.clb_nlist.pin_logical_index(pin_id);
180+
int physical_pin_index = get_physical_pin(
181+
physical_tile, place_ctx.block_locs[block_id].loc.z,
182+
logical_tile, logical_pin_index);
183+
int physical_pin_class = physical_tile->pin_class[physical_pin_index];
184+
int class_inode = get_rr_node_index(device_ctx.rr_node_indices,
185+
i, j, (pin_count == 0 ? SOURCE : SINK), /* First pin is driver */
186+
physical_pin_class);
187+
188+
auto result = node_to_block->insert(std::make_pair(class_inode, block_id));
189+
if (!result.second && result.first->second != block_id) {
190+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
191+
"Clustered netlist has inconsistent rr node mapping, class rr node %d has two block ids %zu and %zu?",
192+
class_inode, (size_t)block_id, result.first->second);
193+
}
194+
pin_count++;
195+
}
196+
}
197+
198+
VTR_LOG("ClusterBlockId lookup has %zu entries\n", node_to_block->size());
199+
}
200+
201+
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block) {
155202
/* Check if the net is global or not, and process appropriately */
156-
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
203+
auto& cluster_ctx = g_vpr_ctx.clustering();
157204

158205
if (input_tokens.size() > 3 && input_tokens[3] == "global"
159206
&& input_tokens[4] == "net" && input_tokens[5] == "connecting:") {
@@ -187,19 +234,18 @@ static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name,
187234
name.c_str(), size_t(inet), cluster_ctx.clb_nlist.net_name(inet).c_str());
188235
}
189236

190-
process_nodes(fp, inet, filename, lineno);
237+
process_nodes(fp, inet, filename, lineno, node_to_block);
191238
}
192239
input_tokens.clear();
193240
return;
194241
}
195242

196-
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno) {
243+
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block) {
197244
/* Not a global net. Goes through every node and add it into trace.head*/
198245

199-
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
200-
auto& device_ctx = g_vpr_ctx.mutable_device();
246+
auto& cluster_ctx = g_vpr_ctx.clustering();
247+
auto& device_ctx = g_vpr_ctx.device();
201248
auto& route_ctx = g_vpr_ctx.mutable_routing();
202-
auto& place_ctx = g_vpr_ctx.placement();
203249

204250
t_trace* tptr = route_ctx.trace[inet].head;
205251

@@ -289,9 +335,22 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
289335
if (tokens[6 + offset] != "Switch:") {
290336
/*This is an opin or ipin, process its pin nums*/
291337
if (!is_io_type(device_ctx.grid[x][y].type) && (tokens[2] == "IPIN" || tokens[2] == "OPIN")) {
338+
// Convert this IPIN/OPIN back to class.
339+
auto rr_type = device_ctx.rr_nodes[inode].type();
340+
VTR_ASSERT(rr_type == IPIN || rr_type == OPIN);
292341
int pin_num = device_ctx.rr_nodes[inode].ptc_num();
293-
int height_offset = device_ctx.grid[x][y].height_offset;
294-
ClusterBlockId iblock = place_ctx.grid_blocks[x][y - height_offset].blocks[0];
342+
int iclass = device_ctx.grid[x][y].type->pin_class[pin_num];
343+
int class_inode = get_rr_node_index(device_ctx.rr_node_indices,
344+
x, y, (rr_type == OPIN ? SOURCE : SINK), iclass);
345+
346+
auto itr = node_to_block.find(class_inode);
347+
if (itr == node_to_block.end()) {
348+
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
349+
"Class RR node %d does not have an associated ClusterBlockId?", class_inode);
350+
}
351+
352+
ClusterBlockId iblock = itr->second;
353+
VTR_ASSERT(iblock);
295354
t_pb_graph_pin* pb_pin = get_pb_graph_node_pin_from_block_pin(iblock, pin_num);
296355
t_pb_type* pb_type = pb_pin->parent_node->pb_type;
297356

@@ -338,7 +397,7 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
338397
/*This function goes through all the blocks in a global net and verify it with the
339398
* clustered netlist and the placement */
340399
static void process_global_blocks(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno) {
341-
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
400+
auto& cluster_ctx = g_vpr_ctx.clustering();
342401
auto& place_ctx = g_vpr_ctx.placement();
343402

344403
std::string block, bnum_str;

vpr/src/base/vpr_context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ struct RoutingContext : public Context {
281281

282282
vtr::vector<ClusterNetId, std::vector<int>> net_rr_terminals; /* [0..num_nets-1][0..num_pins-1] */
283283
vtr::vector<ClusterNetId, uint8_t> is_clock_net; /* [0..num_nets-1] */
284+
std::unordered_map<int, ClusterBlockId> rr_net_map;
284285

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

vpr/src/draw/draw.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2664,7 +2664,7 @@ void draw_highlight_blocks_color(t_logical_block_type_ptr type, ClusterBlockId b
26642664
continue;
26652665

26662666
auto physical_tile = physical_tile_type(blk_id);
2667-
int physical_pin = get_physical_pin(physical_tile, type, k);
2667+
int physical_pin = get_physical_pin(physical_tile, /*z_index=*/0, type, k);
26682668

26692669
iclass = physical_tile->pin_class[physical_pin];
26702670

vpr/src/pack/output_clustering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static void print_stats() {
6262
auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id);
6363
auto physical_tile = pick_best_physical_type(logical_block);
6464
for (ipin = 0; ipin < logical_block->pb_type->num_pins; ipin++) {
65-
int physical_pin = get_physical_pin(physical_tile, logical_block, ipin);
65+
int physical_pin = get_physical_pin(physical_tile, /*z_index=*/0, logical_block, ipin);
6666
auto pin_class = physical_tile->pin_class[physical_pin];
6767
auto pin_class_inf = physical_tile->class_inf[pin_class];
6868

vpr/src/place/place_macro.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ static void find_all_the_macro(int* num_of_macro, std::vector<ClusterBlockId>& p
8282

8383
num_blk_pins = cluster_ctx.clb_nlist.block_type(blk_id)->pb_type->num_pins;
8484
for (to_iblk_pin = 0; to_iblk_pin < num_blk_pins; to_iblk_pin++) {
85-
int to_physical_pin = get_physical_pin(physical_tile, logical_block, to_iblk_pin);
85+
int to_physical_pin = get_physical_pin(physical_tile, /*z_index=*/0, logical_block, to_iblk_pin);
8686

8787
to_net_id = cluster_ctx.clb_nlist.block_net(blk_id, to_iblk_pin);
8888
to_idirect = f_idirect_from_blk_pin[physical_tile->index][to_physical_pin];
@@ -102,7 +102,7 @@ static void find_all_the_macro(int* num_of_macro, std::vector<ClusterBlockId>& p
102102
|| (is_constant_clb_net(to_net_id)
103103
&& !net_is_driven_by_direct(to_net_id)))) {
104104
for (from_iblk_pin = 0; from_iblk_pin < num_blk_pins; from_iblk_pin++) {
105-
int from_physical_pin = get_physical_pin(physical_tile, logical_block, from_iblk_pin);
105+
int from_physical_pin = get_physical_pin(physical_tile, /*z_index=*/0, logical_block, from_iblk_pin);
106106

107107
from_net_id = cluster_ctx.clb_nlist.block_net(blk_id, from_iblk_pin);
108108
from_idirect = f_idirect_from_blk_pin[physical_tile->index][from_physical_pin];

0 commit comments

Comments
 (0)