Skip to content

Initial implementation of explicit ports. #1065

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion libs/libarchfpga/src/physical_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,12 @@ std::vector<int> t_physical_tile_type::get_clock_pins_indices() const {
int clock_pins_start_idx = 0;
int clock_pins_stop_idx = 0;

for (int capacity_num = 0; capacity_num < this->capacity; capacity_num++) {
int num_capacity = 1;
if (capacity_type == e_capacity_type::DUPLICATE) {
num_capacity = this->capacity;
}

for (int capacity_num = 0; capacity_num < num_capacity; capacity_num++) {
// Ranges are picked on the basis that pins are ordered: inputs, outputs, then clock pins
// This is because ProcessPb_type assigns pb_type port indices in that order and
// SetupPinLocationsAndPinClasses assigns t_logical_block_type_ptr pin indices in the order of port indices
Expand Down
15 changes: 12 additions & 3 deletions libs/libarchfpga/src/physical_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,12 @@ enum class e_sb_type {

};

enum class e_capacity_type {
DUPLICATE, // Capacity duplicates ports.
EXPLICIT // Capacity increases the number of logical tiles, but does not
// modify the physical ports.
};

constexpr int NO_SWITCH = -1;
constexpr int DEFAULT_SWITCH = -2;

Expand Down Expand Up @@ -577,6 +583,7 @@ struct t_physical_tile_type {
int num_clock_pins = 0;

int capacity = 0;
e_capacity_type capacity_type = e_capacity_type::DUPLICATE;

int width = 0;
int height = 0;
Expand Down Expand Up @@ -625,18 +632,20 @@ struct t_physical_tile_type {
* vtr::bimap container.
*/
struct t_logical_pin {
int z_index = -1;
int pin = -1;

t_logical_pin(int value) {
t_logical_pin(int z_index_value, int value) {
z_index = z_index_value;
pin = value;
}

bool operator==(const t_logical_pin o) const {
return pin == o.pin;
return z_index == o.z_index && pin == o.pin;
}

bool operator<(const t_logical_pin o) const {
return pin < o.pin;
return std::make_pair(z_index, pin) < std::make_pair(o.z_index, o.pin);
}
};

Expand Down
244 changes: 186 additions & 58 deletions libs/libarchfpga/src/read_xml_arch_file.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion vpr/src/base/ShowSetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void printClusteredNetlistStats() {
num_blocks_type[logical_block->index]++;
if (is_io_type(physical_tile)) {
for (j = 0; j < logical_block->pb_type->num_pins; j++) {
int physical_pin = get_physical_pin(physical_tile, logical_block, j);
int physical_pin = get_physical_pin(physical_tile, /*z_index=*/0, logical_block, j);
auto pin_class = physical_tile->pin_class[physical_pin];
auto class_inf = physical_tile->class_inf[pin_class];

Expand Down
2 changes: 1 addition & 1 deletion vpr/src/base/check_netlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static int check_connections_to_global_clb_pins(ClusterNetId net_id, int verbosi
auto physical_type = pick_best_physical_type(logical_type);

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

if (physical_type->is_ignored_pin[pin_index] != net_is_ignored
&& !is_io_type(physical_type)) {
Expand Down
4 changes: 2 additions & 2 deletions vpr/src/base/read_netlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist) {
block_type = clb_nlist.block_type(blk_id);
auto tile_type = pick_best_physical_type(block_type);
for (j = 0; j < block_type->pb_type->num_pins; j++) {
int physical_pin = get_physical_pin(tile_type, block_type, j);
int physical_pin = get_physical_pin(tile_type, /*z_index=*/0, block_type, j);

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

if (tile_type->is_ignored_pin[physical_pin] != is_ignored_net) {
VTR_LOG_WARN(
Expand Down
93 changes: 76 additions & 17 deletions vpr/src/base/read_route.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "rr_graph.h"
#include "vtr_assert.h"
#include "vtr_util.h"
#include "vtr_time.h"
#include "tatum/echo_writer.hpp"
#include "vtr_log.h"
#include "check_route.h"
Expand All @@ -40,22 +41,24 @@
#include "echo_files.h"
#include "route_common.h"
#include "read_route.h"
#include "rr_graph2.h"

/*************Functions local to this module*************/
static void process_route(std::ifstream& fp, const char* filename, int& lineno);
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno);
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno);
static void process_route(std::ifstream& fp, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block);
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block);
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);
static void process_global_blocks(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno);
static void format_coordinates(int& x, int& y, std::string coord, ClusterNetId net, const char* filename, const int lineno);
static void format_pin_info(std::string& pb_name, std::string& port_name, int& pb_pin_num, std::string input);
static void build_cluster_block_map(std::unordered_map<int, ClusterBlockId>* node_to_block);
static std::string format_name(std::string name);

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

// Build lookup from SOURCE/SINK node to ClusterBlockId.
std::unordered_map<int, ClusterBlockId> node_to_block;
build_cluster_block_map(&node_to_block);

/* Read in every net */
process_route(fp, route_file, lineno);
process_route(fp, route_file, lineno, node_to_block);

fp.close();

Expand All @@ -126,7 +133,7 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v
return is_feasible;
}

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

tokens.clear();
}

static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno) {
static void build_cluster_block_map(std::unordered_map<int, ClusterBlockId>* node_to_block) {
auto& cluster_ctx = g_vpr_ctx.clustering();
auto& place_ctx = g_vpr_ctx.placement();
auto& device_ctx = g_vpr_ctx.device();

vtr::ScopedStartFinishTimer timer("Building ClusterBlockId lookup");

for (auto net_id : cluster_ctx.clb_nlist.nets()) {
int pin_count = 0;
for (auto pin_id : cluster_ctx.clb_nlist.net_pins(net_id)) {
auto block_id = cluster_ctx.clb_nlist.pin_block(pin_id);

const auto* logical_tile = cluster_ctx.clb_nlist.block_type(block_id);
const auto* physical_tile = physical_tile_type(block_id);
VTR_ASSERT(block_id);
int i = place_ctx.block_locs[block_id].loc.x;
int j = place_ctx.block_locs[block_id].loc.y;

int logical_pin_index = cluster_ctx.clb_nlist.pin_logical_index(pin_id);
int physical_pin_index = get_physical_pin(
physical_tile, place_ctx.block_locs[block_id].loc.z,
logical_tile, logical_pin_index);
int physical_pin_class = physical_tile->pin_class[physical_pin_index];
int class_inode = get_rr_node_index(device_ctx.rr_node_indices,
i, j, (pin_count == 0 ? SOURCE : SINK), /* First pin is driver */
physical_pin_class);

auto result = node_to_block->insert(std::make_pair(class_inode, block_id));
if (!result.second && result.first->second != block_id) {
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
"Clustered netlist has inconsistent rr node mapping, class rr node %d has two block ids %zu and %zu?",
class_inode, (size_t)block_id, result.first->second);
}
pin_count++;
}
}

VTR_LOG("ClusterBlockId lookup has %zu entries\n", node_to_block->size());
}

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) {
/* Check if the net is global or not, and process appropriately */
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
auto& cluster_ctx = g_vpr_ctx.clustering();

if (input_tokens.size() > 3 && input_tokens[3] == "global"
&& input_tokens[4] == "net" && input_tokens[5] == "connecting:") {
Expand Down Expand Up @@ -183,19 +230,18 @@ static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name,
name.c_str(), size_t(inet), cluster_ctx.clb_nlist.net_name(inet).c_str());
}

process_nodes(fp, inet, filename, lineno);
process_nodes(fp, inet, filename, lineno, node_to_block);
}
input_tokens.clear();
return;
}

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

auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
auto& device_ctx = g_vpr_ctx.mutable_device();
auto& cluster_ctx = g_vpr_ctx.clustering();
auto& device_ctx = g_vpr_ctx.device();
auto& route_ctx = g_vpr_ctx.mutable_routing();
auto& place_ctx = g_vpr_ctx.placement();

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

Expand Down Expand Up @@ -285,9 +331,22 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
if (tokens[6 + offset] != "Switch:") {
/*This is an opin or ipin, process its pin nums*/
if (!is_io_type(device_ctx.grid[x][y].type) && (tokens[2] == "IPIN" || tokens[2] == "OPIN")) {
// Convert this IPIN/OPIN back to class.
auto rr_type = device_ctx.rr_nodes[inode].type();
VTR_ASSERT(rr_type == IPIN || rr_type == OPIN);
int pin_num = device_ctx.rr_nodes[inode].ptc_num();
int height_offset = device_ctx.grid[x][y].height_offset;
ClusterBlockId iblock = place_ctx.grid_blocks[x][y - height_offset].blocks[0];
int iclass = device_ctx.grid[x][y].type->pin_class[pin_num];
int class_inode = get_rr_node_index(device_ctx.rr_node_indices,
x, y, (rr_type == OPIN ? SOURCE : SINK), iclass);

auto itr = node_to_block.find(class_inode);
if (itr == node_to_block.end()) {
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
"Class RR node %d does not have an associated ClusterBlockId?", class_inode);
}

ClusterBlockId iblock = itr->second;
VTR_ASSERT(iblock);
t_pb_graph_pin* pb_pin = get_pb_graph_node_pin_from_block_pin(iblock, pin_num);
t_pb_type* pb_type = pb_pin->parent_node->pb_type;

Expand Down Expand Up @@ -334,7 +393,7 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
/*This function goes through all the blocks in a global net and verify it with the
* clustered netlist and the placement */
static void process_global_blocks(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno) {
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
auto& cluster_ctx = g_vpr_ctx.clustering();
auto& place_ctx = g_vpr_ctx.placement();

std::string block, bnum_str;
Expand Down
1 change: 1 addition & 0 deletions vpr/src/base/vpr_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ struct RoutingContext : public Context {
vtr::vector<ClusterNetId, std::unordered_set<int>> trace_nodes;

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

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

Expand Down
2 changes: 1 addition & 1 deletion vpr/src/draw/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2666,7 +2666,7 @@ void draw_highlight_blocks_color(t_logical_block_type_ptr type, ClusterBlockId b
continue;

auto physical_tile = physical_tile_type(blk_id);
int physical_pin = get_physical_pin(physical_tile, type, k);
int physical_pin = get_physical_pin(physical_tile, /*z_index=*/0, type, k);

iclass = physical_tile->pin_class[physical_pin];

Expand Down
2 changes: 1 addition & 1 deletion vpr/src/pack/output_clustering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static void print_stats() {
auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id);
auto physical_tile = pick_best_physical_type(logical_block);
for (ipin = 0; ipin < logical_block->pb_type->num_pins; ipin++) {
int physical_pin = get_physical_pin(physical_tile, logical_block, ipin);
int physical_pin = get_physical_pin(physical_tile, /*z_index=*/0, logical_block, ipin);
auto pin_class = physical_tile->pin_class[physical_pin];
auto pin_class_inf = physical_tile->class_inf[pin_class];

Expand Down
4 changes: 2 additions & 2 deletions vpr/src/place/place_macro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ static void find_all_the_macro(int* num_of_macro, std::vector<ClusterBlockId>& p

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

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

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