diff --git a/openfpga/src/base/openfpga_link_arch.cpp b/openfpga/src/base/openfpga_link_arch.cpp index 5c0d6c582..34c98ee8d 100644 --- a/openfpga/src/base/openfpga_link_arch.cpp +++ b/openfpga/src/base/openfpga_link_arch.cpp @@ -123,7 +123,8 @@ void link_arch(OpenfpgaContext& openfpga_ctx, /* Build tile direct annotation */ openfpga_ctx.mutable_tile_direct() = build_device_tile_direct(g_vpr_ctx.device(), - openfpga_ctx.arch().arch_direct); + openfpga_ctx.arch().arch_direct, + cmd_context.option_enable(cmd, opt_verbose)); /* Annotate placement results */ annotate_mapped_blocks(g_vpr_ctx.device(), diff --git a/openfpga/src/fabric/build_top_module_directs.cpp b/openfpga/src/fabric/build_top_module_directs.cpp index 63d4a1882..314b5f2e8 100644 --- a/openfpga/src/fabric/build_top_module_directs.cpp +++ b/openfpga/src/fabric/build_top_module_directs.cpp @@ -95,6 +95,9 @@ void add_module_nets_tile_direct_connection(ModuleManager& module_manager, size_t src_pin_height = grids[src_clb_coord.x()][src_clb_coord.y()].type->pin_height_offset[src_tile_pin]; std::string src_port_name = generate_grid_port_name(src_clb_coord, src_pin_width, src_pin_height, src_pin_grid_side, src_tile_pin, false); ModulePortId src_port_id = module_manager.find_module_port(src_grid_module, src_port_name); + if (true != module_manager.valid_module_port_id(src_grid_module, src_port_id)) { + VTR_LOG("Fail to find port '%s'\n", src_port_name.c_str()); + } VTR_ASSERT(true == module_manager.valid_module_port_id(src_grid_module, src_port_id)); VTR_ASSERT(1 == module_manager.module_port(src_grid_module, src_port_id).get_width()); diff --git a/openfpga/src/tile_direct/build_tile_direct.cpp b/openfpga/src/tile_direct/build_tile_direct.cpp index 2166b7a16..5e33bc502 100644 --- a/openfpga/src/tile_direct/build_tile_direct.cpp +++ b/openfpga/src/tile_direct/build_tile_direct.cpp @@ -39,6 +39,24 @@ std::string parse_direct_tile_name(const std::string& direct_tile_inf) { return tokens[0]; } +/*************************************************************************************** + * Parse the pin name and port MSB/LSB from the direct definition + * The definition string should be in the following format: + * .[:] + ***************************************************************************************/ +static +std::string parse_direct_port(const std::string& direct_tile_inf) { + StringToken tokenizer(direct_tile_inf); + std::vector tokens = tokenizer.split('.'); + /* We should have only 2 elements and the first is tile name */ + if (2 != tokens.size()) { + VTR_LOG_ERROR("Invalid definition on direct tile '%s'!\n\tExpect .[:].\n", + direct_tile_inf.c_str()); + } + + return tokens[1]; +} + /*************************************************************************************** * Check if a pin is located on a given side of physical tile * If the given side is NUM_SIDES, we will search all the sides @@ -364,15 +382,16 @@ static void build_inner_column_row_tile_direct(TileDirect& tile_direct, const t_direct_inf& vpr_direct, const DeviceContext& device_ctx, - const ArchDirectId& arch_direct_id) { + const ArchDirectId& arch_direct_id, + const bool& verbose) { /* Get the source tile and pin information */ std::string from_tile_name = parse_direct_tile_name(std::string(vpr_direct.from_pin)); - PortParser from_tile_port_parser(std::string(vpr_direct.from_pin)); + PortParser from_tile_port_parser(parse_direct_port(std::string(vpr_direct.from_pin))); const BasicPort& from_tile_port = from_tile_port_parser.port(); /* Get the sink tile and pin information */ std::string to_tile_name = parse_direct_tile_name(std::string(vpr_direct.to_pin)); - PortParser to_tile_port_parser(std::string(vpr_direct.to_pin)); + PortParser to_tile_port_parser(parse_direct_port(std::string(vpr_direct.to_pin))); const BasicPort& to_tile_port = to_tile_port_parser.port(); /* Walk through the device fabric and find the grid that fit the source */ @@ -387,51 +406,80 @@ void build_inner_column_row_tile_direct(TileDirect& tile_direct, if (from_tile_name != std::string(device_ctx.grid[x][y].type->name)) { continue; } + + /* Search all the sides, the from pin may locate any side! + * Note: the vpr_direct.from_side is NUM_SIDES, which is unintialized + * This should be reported to VPR!!! + */ + for (const e_side& from_side : {TOP, RIGHT, BOTTOM, LEFT}) { - /* Try to find the pin in this tile */ - std::vector from_pins = find_physical_tile_pin_id(device_ctx.grid[x][y].type, - device_ctx.grid[x][y].width_offset, - device_ctx.grid[x][y].height_offset, - from_tile_port, - vpr_direct.from_side); - /* If nothing found, we can continue */ - if (0 == from_pins.size()) { - continue; - } - - /* We should try to the sink grid for inner-column/row direct connections */ - vtr::Point from_grid_coord(x, y); - vtr::Point to_grid_coord(x + vpr_direct.x_offset, y + vpr_direct.y_offset); - if (false == is_grid_coordinate_exist_in_device(device_ctx.grid, to_grid_coord)) { - continue; - } + /* Try to find the pin in this tile */ + std::vector from_pins = find_physical_tile_pin_id(device_ctx.grid[x][y].type, + device_ctx.grid[x][y].width_offset, + device_ctx.grid[x][y].height_offset, + from_tile_port, + from_side); + /* If nothing found, we can continue */ + if (0 == from_pins.size()) { + continue; + } + + /* We should try to the sink grid for inner-column/row direct connections */ + vtr::Point from_grid_coord(x, y); + vtr::Point to_grid_coord(x + vpr_direct.x_offset, y + vpr_direct.y_offset); + if (false == is_grid_coordinate_exist_in_device(device_ctx.grid, to_grid_coord)) { + continue; + } - /* Bypass the grid that does not fit the from_tile name */ - if (to_tile_name != std::string(device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].type->name)) { - continue; - } - /* Try to find the pin in this tile */ - std::vector to_pins = find_physical_tile_pin_id(device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].type, - device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].width_offset, - device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].height_offset, - to_tile_port, - vpr_direct.to_side); - /* If nothing found, we can continue */ - if (0 == to_pins.size()) { - continue; - } + /* Bypass the grid that does not fit the from_tile name */ + if (to_tile_name != std::string(device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].type->name)) { + continue; + } - /* If from port and to port do not match in sizes, error out */ - if (from_pins.size() != to_pins.size()) { - report_direct_from_port_and_to_port_mismatch(vpr_direct, from_tile_port, to_tile_port); - exit(1); - } + /* Search all the sides, the to pin may locate any side! + * Note: the vpr_direct.to_side is NUM_SIDES, which is unintialized + * This should be reported to VPR!!! + */ + for (const e_side& to_side : {TOP, RIGHT, BOTTOM, LEFT}) { - /* Now add the tile direct */ - for (size_t ipin = 0; ipin < from_pins.size(); ++ipin) { - TileDirectId tile_direct_id = tile_direct.add_direct(from_grid_coord, vpr_direct.from_side, from_pins[ipin], - to_grid_coord, vpr_direct.to_side, to_pins[ipin]); - tile_direct.set_arch_direct_id(tile_direct_id, arch_direct_id); + /* Try to find the pin in this tile */ + std::vector to_pins = find_physical_tile_pin_id(device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].type, + device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].width_offset, + device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].height_offset, + to_tile_port, + to_side); + /* If nothing found, we can continue */ + if (0 == to_pins.size()) { + continue; + } + + /* If from port and to port do not match in sizes, error out */ + if (from_pins.size() != to_pins.size()) { + report_direct_from_port_and_to_port_mismatch(vpr_direct, from_tile_port, to_tile_port); + exit(1); + } + + /* Now add the tile direct */ + for (size_t ipin = 0; ipin < from_pins.size(); ++ipin) { + VTR_LOGV(verbose, + "Built a inner-column/row tile-to-tile direct from %s[%lu][%lu].%s[%lu] at side '%s' to %s[%lu][%lu].%s[%lu] at side '%s'\n", + from_tile_name.c_str(), x, y, + from_tile_port.get_name().c_str(), from_pins[ipin], + SIDE_STRING[from_side], + to_tile_name.c_str(), + to_grid_coord.x(), to_grid_coord.y(), + to_tile_port.get_name().c_str(), to_pins[ipin], + SIDE_STRING[to_side] + ); + TileDirectId tile_direct_id = tile_direct.add_direct(from_grid_coord, + from_side, + from_pins[ipin], + to_grid_coord, + to_side, + to_pins[ipin]); + tile_direct.set_arch_direct_id(tile_direct_id, arch_direct_id); + } + } } } } @@ -475,16 +523,17 @@ void build_inter_column_row_tile_direct(TileDirect& tile_direct, const t_direct_inf& vpr_direct, const DeviceContext& device_ctx, const ArchDirect& arch_direct, - const ArchDirectId& arch_direct_id) { + const ArchDirectId& arch_direct_id, + const bool& verbose) { /* Get the source tile and pin information */ std::string from_tile_name = parse_direct_tile_name(std::string(vpr_direct.from_pin)); - PortParser from_tile_port_parser(std::string(vpr_direct.from_pin)); + PortParser from_tile_port_parser(parse_direct_port(std::string(vpr_direct.from_pin))); const BasicPort& from_tile_port = from_tile_port_parser.port(); /* Get the sink tile and pin information */ std::string to_tile_name = parse_direct_tile_name(std::string(vpr_direct.to_pin)); - PortParser to_tile_port_parser(std::string(vpr_direct.to_pin)); + PortParser to_tile_port_parser(parse_direct_port(std::string(vpr_direct.to_pin))); const BasicPort& to_tile_port = to_tile_port_parser.port(); /* Go through the direct connection list, see if we need intra-column/row connection here */ @@ -525,47 +574,77 @@ void build_inter_column_row_tile_direct(TileDirect& tile_direct, if (false == is_grid_coordinate_exist_in_device(device_ctx.grid, from_grid_coord)) { continue; } + + /* Search all the sides, the from pin may locate any side! + * Note: the vpr_direct.from_side is NUM_SIDES, which is unintialized + * This should be reported to VPR!!! + */ + for (const e_side& from_side : {TOP, RIGHT, BOTTOM, LEFT}) { - /* Try to find the pin in this tile */ - std::vector from_pins = find_physical_tile_pin_id(device_ctx.grid[from_grid_coord.x()][from_grid_coord.y()].type, - device_ctx.grid[from_grid_coord.x()][from_grid_coord.y()].width_offset, - device_ctx.grid[from_grid_coord.x()][from_grid_coord.y()].height_offset, - from_tile_port, - vpr_direct.from_side); - /* If nothing found, we can continue */ - if (0 == from_pins.size()) { - continue; - } + /* Try to find the pin in this tile */ + std::vector from_pins = find_physical_tile_pin_id(device_ctx.grid[from_grid_coord.x()][from_grid_coord.y()].type, + device_ctx.grid[from_grid_coord.x()][from_grid_coord.y()].width_offset, + device_ctx.grid[from_grid_coord.x()][from_grid_coord.y()].height_offset, + from_tile_port, + from_side); + /* If nothing found, we can continue */ + if (0 == from_pins.size()) { + continue; + } - /* For a valid coordinate, we can find the coordinate of the destination clb */ - vtr::Point to_grid_coord = find_inter_direct_destination_coordinate(device_ctx.grid, from_grid_coord, to_tile_name, arch_direct, arch_direct_id); - /* If destination clb is valid, we should add something */ - if (false == is_grid_coordinate_exist_in_device(device_ctx.grid, to_grid_coord)) { - continue; - } + /* For a valid coordinate, we can find the coordinate of the destination clb */ + vtr::Point to_grid_coord = find_inter_direct_destination_coordinate(device_ctx.grid, from_grid_coord, to_tile_name, arch_direct, arch_direct_id); + /* If destination clb is valid, we should add something */ + if (false == is_grid_coordinate_exist_in_device(device_ctx.grid, to_grid_coord)) { + continue; + } - /* Try to find the pin in this tile */ - std::vector to_pins = find_physical_tile_pin_id(device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].type, - device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].width_offset, - device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].height_offset, - to_tile_port, - vpr_direct.to_side); - /* If nothing found, we can continue */ - if (0 == to_pins.size()) { - continue; - } + /* Search all the sides, the to pin may locate any side! + * Note: the vpr_direct.to_side is NUM_SIDES, which is unintialized + * This should be reported to VPR!!! + */ + for (const e_side& to_side : {TOP, RIGHT, BOTTOM, LEFT}) { - /* If from port and to port do not match in sizes, error out */ - if (from_pins.size() != to_pins.size()) { - report_direct_from_port_and_to_port_mismatch(vpr_direct, from_tile_port, to_tile_port); - exit(1); - } + /* Try to find the pin in this tile */ + std::vector to_pins = find_physical_tile_pin_id(device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].type, + device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].width_offset, + device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].height_offset, + to_tile_port, + to_side); + /* If nothing found, we can continue */ + if (0 == to_pins.size()) { + continue; + } - /* Now add the tile direct */ - for (size_t ipin = 0; ipin < from_pins.size(); ++ipin) { - TileDirectId tile_direct_id = tile_direct.add_direct(from_grid_coord, vpr_direct.from_side, from_pins[ipin], - to_grid_coord, vpr_direct.to_side, to_pins[ipin]); - tile_direct.set_arch_direct_id(tile_direct_id, arch_direct_id); + /* If from port and to port do not match in sizes, error out */ + if (from_pins.size() != to_pins.size()) { + report_direct_from_port_and_to_port_mismatch(vpr_direct, from_tile_port, to_tile_port); + exit(1); + } + + /* Now add the tile direct */ + for (size_t ipin = 0; ipin < from_pins.size(); ++ipin) { + VTR_LOGV(verbose, + "Built a inter-column/row tile-to-tile direct from %s[%lu][%lu].%s[%lu] at side '%s' to %s[%lu][%lu].%s[%lu] at side '%s'\n", + from_tile_name.c_str(), + from_grid_coord.x(), from_grid_coord.y(), + from_tile_port.get_name().c_str(), from_pins[ipin], + SIDE_STRING[from_side], + to_tile_name.c_str(), + to_grid_coord.x(), to_grid_coord.y(), + to_tile_port.get_name().c_str(), to_pins[ipin], + SIDE_STRING[to_side] + ); + + TileDirectId tile_direct_id = tile_direct.add_direct(from_grid_coord, + from_side, + from_pins[ipin], + to_grid_coord, + to_side, + to_pins[ipin]); + tile_direct.set_arch_direct_id(tile_direct_id, arch_direct_id); + } + } } } return; /* Go to next direct type */ @@ -599,46 +678,76 @@ void build_inter_column_row_tile_direct(TileDirect& tile_direct, continue; } - /* Try to find the pin in this tile */ - std::vector from_pins = find_physical_tile_pin_id(device_ctx.grid[from_grid_coord.x()][from_grid_coord.y()].type, - device_ctx.grid[from_grid_coord.x()][from_grid_coord.y()].width_offset, - device_ctx.grid[from_grid_coord.x()][from_grid_coord.y()].height_offset, - from_tile_port, - vpr_direct.from_side); - /* If nothing found, we can continue */ - if (0 == from_pins.size()) { - continue; - } + /* Search all the sides, the from pin may locate any side! + * Note: the vpr_direct.from_side is NUM_SIDES, which is unintialized + * This should be reported to VPR!!! + */ + for (const e_side& from_side : {TOP, RIGHT, BOTTOM, LEFT}) { + + /* Try to find the pin in this tile */ + std::vector from_pins = find_physical_tile_pin_id(device_ctx.grid[from_grid_coord.x()][from_grid_coord.y()].type, + device_ctx.grid[from_grid_coord.x()][from_grid_coord.y()].width_offset, + device_ctx.grid[from_grid_coord.x()][from_grid_coord.y()].height_offset, + from_tile_port, + from_side); + /* If nothing found, we can continue */ + if (0 == from_pins.size()) { + continue; + } - /* For a valid coordinate, we can find the coordinate of the destination clb */ - vtr::Point to_grid_coord = find_inter_direct_destination_coordinate(device_ctx.grid, from_grid_coord, to_tile_name, arch_direct, arch_direct_id); - /* If destination clb is valid, we should add something */ - if (false == is_grid_coordinate_exist_in_device(device_ctx.grid, to_grid_coord)) { - continue; - } + /* For a valid coordinate, we can find the coordinate of the destination clb */ + vtr::Point to_grid_coord = find_inter_direct_destination_coordinate(device_ctx.grid, from_grid_coord, to_tile_name, arch_direct, arch_direct_id); + /* If destination clb is valid, we should add something */ + if (false == is_grid_coordinate_exist_in_device(device_ctx.grid, to_grid_coord)) { + continue; + } - /* Try to find the pin in this tile */ - std::vector to_pins = find_physical_tile_pin_id(device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].type, - device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].width_offset, - device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].height_offset, - to_tile_port, - vpr_direct.to_side); - /* If nothing found, we can continue */ - if (0 == to_pins.size()) { - continue; - } + /* Search all the sides, the to pin may locate any side! + * Note: the vpr_direct.to_side is NUM_SIDES, which is unintialized + * This should be reported to VPR!!! + */ + for (const e_side& to_side : {TOP, RIGHT, BOTTOM, LEFT}) { - /* If from port and to port do not match in sizes, error out */ - if (from_pins.size() != to_pins.size()) { - report_direct_from_port_and_to_port_mismatch(vpr_direct, from_tile_port, to_tile_port); - exit(1); - } + /* Try to find the pin in this tile */ + std::vector to_pins = find_physical_tile_pin_id(device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].type, + device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].width_offset, + device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].height_offset, + to_tile_port, + to_side); + /* If nothing found, we can continue */ + if (0 == to_pins.size()) { + continue; + } - /* Now add the tile direct */ - for (size_t ipin = 0; ipin < from_pins.size(); ++ipin) { - TileDirectId tile_direct_id = tile_direct.add_direct(from_grid_coord, vpr_direct.from_side, from_pins[ipin], - to_grid_coord, vpr_direct.to_side, to_pins[ipin]); - tile_direct.set_arch_direct_id(tile_direct_id, arch_direct_id); + /* If from port and to port do not match in sizes, error out */ + if (from_pins.size() != to_pins.size()) { + report_direct_from_port_and_to_port_mismatch(vpr_direct, from_tile_port, to_tile_port); + exit(1); + } + + /* Now add the tile direct */ + for (size_t ipin = 0; ipin < from_pins.size(); ++ipin) { + VTR_LOGV(verbose, + "Built a inter-column/row tile-to-tile direct from %s[%lu][%lu].%s[%lu] at side '%s' to %s[%lu][%lu].%s[%lu] at side '%s'\n", + from_tile_name.c_str(), + from_grid_coord.x(), from_grid_coord.y(), + from_tile_port.get_name().c_str(), from_pins[ipin], + SIDE_STRING[from_side], + to_tile_name.c_str(), + to_grid_coord.x(), to_grid_coord.y(), + to_tile_port.get_name().c_str(), to_pins[ipin], + SIDE_STRING[to_side] + ); + + TileDirectId tile_direct_id = tile_direct.add_direct(from_grid_coord, + from_side, + from_pins[ipin], + to_grid_coord, + to_side, + to_pins[ipin]); + tile_direct.set_arch_direct_id(tile_direct_id, arch_direct_id); + } + } } } } @@ -648,7 +757,8 @@ void build_inter_column_row_tile_direct(TileDirect& tile_direct, * between tiles (programmable blocks) ***************************************************************************************/ TileDirect build_device_tile_direct(const DeviceContext& device_ctx, - const ArchDirect& arch_direct) { + const ArchDirect& arch_direct, + const bool& verbose) { vtr::ScopedStartFinishTimer timer("Build the annotation about direct connection between tiles"); TileDirect tile_direct; @@ -665,13 +775,15 @@ TileDirect build_device_tile_direct(const DeviceContext& device_ctx, build_inner_column_row_tile_direct(tile_direct, device_ctx.arch->Directs[idirect], device_ctx, - arch_direct_id); + arch_direct_id, + verbose); /* Build from OpenFPGA arch definition */ build_inter_column_row_tile_direct(tile_direct, device_ctx.arch->Directs[idirect], device_ctx, arch_direct, - arch_direct_id); + arch_direct_id, + verbose); } VTR_LOG("Built %lu tile-to-tile direct connections\n", diff --git a/openfpga/src/tile_direct/build_tile_direct.h b/openfpga/src/tile_direct/build_tile_direct.h index 78ca2f6b0..ed9e0c3bc 100644 --- a/openfpga/src/tile_direct/build_tile_direct.h +++ b/openfpga/src/tile_direct/build_tile_direct.h @@ -17,7 +17,8 @@ namespace openfpga { TileDirect build_device_tile_direct(const DeviceContext& device_ctx, - const ArchDirect& arch_direct); + const ArchDirect& arch_direct, + const bool& verbose); } /* end namespace openfpga */