added fabric bitstream generator and fixed critical bugs in top module graph

This commit is contained in:
tangxifan 2019-10-27 18:47:33 -06:00
parent f116351831
commit 2b06cfc3cf
15 changed files with 263 additions and 27 deletions

View File

@ -64,6 +64,29 @@ ConfigBlockId BitstreamManager::bit_parent_block(const ConfigBitId& bit_id) cons
return bit_parent_block_ids_[bit_id];
}
/* Find the child block in a bitstream manager with a given name */
ConfigBlockId BitstreamManager::find_child_block(const ConfigBlockId& block_id,
const std::string& child_block_name) const {
/* Ensure the input ids are valid */
VTR_ASSERT(true == valid_block_id(block_id));
std::vector<ConfigBlockId> candidates;
for (const ConfigBlockId& child : block_children(block_id)) {
if (0 == child_block_name.compare(block_name(child))) {
candidates.push_back(child);
}
}
/* We should have 0 or 1 candidate! */
VTR_ASSERT(0 == candidates.size() || 1 == candidates.size());
if (0 == candidates.size()) {
/* Not found, return an invalid value */
return ConfigBlockId::INVALID();
}
return candidates[0];
}
/******************************************************************************
* Public Mutators
******************************************************************************/

View File

@ -73,6 +73,9 @@ class BitstreamManager {
/* Find the parent block of a bit */
ConfigBlockId bit_parent_block(const ConfigBitId& bit_id) const;
/* Find the child block in a bitstream manager with a given name */
ConfigBlockId find_child_block(const ConfigBlockId& block_id, const std::string& child_block_name) const;
public: /* Public Mutators */
/* Add a new configuration bit to the bitstream manager */
ConfigBitId add_bit(const bool& bit_value);

View File

@ -31,6 +31,7 @@
#include "mux_library_builder.h"
#include "build_module_graph.h"
#include "build_device_bitstream.h"
#include "build_fabric_bitstream.h"
#include "bitstream_writer.h"
#include "spice_api.h"
@ -87,14 +88,20 @@ void vpr_fpga_x2p_tool_suites(t_vpr_setup vpr_setup,
/* Build bitstream database if needed */
BitstreamManager bitstream_manager;
std::vector<ConfigBitId> fabric_bitstream;
if ( (TRUE == vpr_setup.FPGA_SPICE_Opts.BitstreamGenOpts.gen_bitstream)
|| (TRUE == vpr_setup.FPGA_SPICE_Opts.SpiceOpts.do_spice)
|| (TRUE == vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.dump_syn_verilog)) {
/* Build fabric independent bitstream */
bitstream_manager = build_device_bitstream(vpr_setup, Arch, module_manager,
Arch.spice->circuit_lib, mux_lib,
device_size, grids,
rr_switches, rr_node, device_rr_gsb);
/* Build fabric dependent bitstream */
fabric_bitstream = build_fabric_dependent_bitstream(bitstream_manager, module_manager);
/* Write bitstream to files */
std::string bitstream_file_path;

View File

@ -760,6 +760,9 @@ std::string generate_grid_block_module_name(const std::string& prefix,
/*********************************************************************
* Generate the instance name for a configurable memory module in a Switch Block
* To keep a unique name in each module and also consider unique routing modules,
* please do NOT include any coordinates in the naming!!!
* Consider only relative coordinate, such as side!
********************************************************************/
std::string generate_sb_memory_instance_name(const std::string& prefix,
const e_side& sb_side,
@ -775,16 +778,18 @@ std::string generate_sb_memory_instance_name(const std::string& prefix,
/*********************************************************************
* Generate the instance name for a configurable memory module in a Connection Block
* To keep a unique name in each module and also consider unique routing modules,
* please do NOT include any coordinates in the naming!!!
* Consider only relative coordinate, such as side!
********************************************************************/
std::string generate_cb_memory_instance_name(const std::string& prefix,
const std::vector<std::vector<t_grid_tile>>& grids,
const vtr::Point<size_t>& coordinate,
const e_side& cb_side,
const size_t& pin_id,
const std::string& postfix) {
std::string instance_name(prefix);
instance_name += generate_grid_side_port_name(grids, coordinate, cb_side, pin_id);
instance_name += Side(cb_side).to_string();
instance_name += std::string("_ipin_") + std::to_string(pin_id);
instance_name += postfix;
return instance_name;
@ -793,12 +798,26 @@ std::string generate_cb_memory_instance_name(const std::string& prefix,
/*********************************************************************
* Generate the instance name for a configurable memory module in a
* physical block of a grid
* To guarentee a unique name for pb_graph pin,
* the instance name includes the index of parent node
* as well as the port name and pin index of this pin
*
* Exceptions:
* For OUTPUT ports, due to hierarchical module organization,
* their parent nodes will be uniquified
* So, we should not add any index here
********************************************************************/
std::string generate_pb_memory_instance_name(const std::string& prefix,
t_pb_graph_pin* pb_graph_pin,
const std::string& postfix) {
std::string instance_name(prefix);
instance_name += std::string(pb_graph_pin->parent_node->pb_type->name);
if (IN_PORT == pb_graph_pin->port->type) {
instance_name += std::string("_");
instance_name += std::to_string(pb_graph_pin->parent_node->placement_index);
}
instance_name += std::string("_");
instance_name += std::string(pb_graph_pin->port->name);
instance_name += std::string("_");

View File

@ -82,8 +82,6 @@ std::string generate_sb_memory_instance_name(const std::string& prefix,
const std::string& postfix);
std::string generate_cb_memory_instance_name(const std::string& prefix,
const std::vector<std::vector<t_grid_tile>>& grids,
const vtr::Point<size_t>& coordinate,
const e_side& cb_side,
const size_t& pin_id,
const std::string& postfix);

View File

@ -17,7 +17,7 @@
#include "build_device_bitstream.h"
/********************************************************************
* Top-level function to build a bistream from the FPGA device
* A top-level function to build a bistream from the FPGA device
* 1. It will organize the bitstream w.r.t. the hierarchy of module graphs
* describing the FPGA fabric
* 2. It will decode configuration bits from routing multiplexers used in
@ -56,7 +56,7 @@ BitstreamManager build_device_bitstream(const t_vpr_setup& vpr_setup,
#endif
/* Bistream builder formally starts*/
vpr_printf(TIO_MESSAGE_INFO, "\nStart building bitstream for FPGA fabric...\n");
vpr_printf(TIO_MESSAGE_INFO, "\nStart building fabric-independent bitstream for FPGA...\n");
/* Bitstream manager to be built */
BitstreamManager bitstream_manager;
@ -81,7 +81,7 @@ BitstreamManager build_device_bitstream(const t_vpr_setup& vpr_setup,
build_grid_bitstream(bitstream_manager, top_block, module_manager, circuit_lib, mux_lib, device_size, grids);
/* Create bitstream from routing architectures */
build_routing_bitstream(bitstream_manager, top_block, module_manager, circuit_lib, mux_lib, grids, rr_switches, L_rr_node, L_device_rr_gsb);
build_routing_bitstream(bitstream_manager, top_block, module_manager, circuit_lib, mux_lib, rr_switches, L_rr_node, L_device_rr_gsb);
/* End time count */
clock_t t_end = clock();
@ -93,3 +93,5 @@ BitstreamManager build_device_bitstream(const t_vpr_setup& vpr_setup,
return bitstream_manager;
}

View File

@ -0,0 +1,135 @@
/********************************************************************
* This file includes functions to build fabric dependent bitstream
*******************************************************************/
#include <time.h>
#include <string>
#include <algorithm>
#include "vtr_assert.h"
#include "util.h"
#include "fpga_x2p_naming.h"
#include "bitstream_manager_utils.h"
#include "build_fabric_bitstream.h"
/********************************************************************
* This function will walk through all the configurable children under a module
* in a recursive way, following a Depth-First Search (DFS) strategy
* For each configuration child, we use its instance name as a key to spot the
* configuration bits in bitstream manager.
* Note that it is guarentee that the instance name in module manager is
* consistent with the block names in bitstream manager
* We use this link to reorganize the bitstream in the sequence of memories as we stored
* in the configurable_children) and configurable_child_instances() of each module of module manager
*******************************************************************/
static
void rec_build_module_fabric_dependent_bitstream(const BitstreamManager& bitstream_manager,
const ConfigBlockId& parent_block,
const ModuleManager& module_manager,
const ModuleId& parent_module,
std::vector<ConfigBitId>& fabric_bitstream) {
/* Depth-first search: if we have any children in the parent_block,
* we dive to the next level first!
*/
if (0 < bitstream_manager.block_children(parent_block).size()) {
for (size_t child_id = 0; child_id < module_manager.configurable_children(parent_module).size(); ++child_id) {
ModuleId child_module = module_manager.configurable_children(parent_module)[child_id];
size_t child_instance = module_manager.configurable_child_instances(parent_module)[child_id];
/* Get the instance name and ensure it is not empty */
std::string instance_name = module_manager.instance_name(parent_module, child_module, child_instance);
/* Find the child block that matches the instance name! */
ConfigBlockId child_block = bitstream_manager.find_child_block(parent_block, instance_name);
/* We must have one valid block id! */
if (true != bitstream_manager.valid_block_id(child_block))
VTR_ASSERT(true == bitstream_manager.valid_block_id(child_block));
/* Go recursively */
rec_build_module_fabric_dependent_bitstream(bitstream_manager, child_block,
module_manager, child_module,
fabric_bitstream);
}
/* Ensure that there should be no configuration bits in the parent block */
VTR_ASSERT(0 == bitstream_manager.block_bits(parent_block).size());
}
/* Note that, reach here, it means that this is a leaf node.
* We add the configuration bits to the fabric_bitstream,
* And then, we can return
*/
for (const ConfigBitId& config_bit : bitstream_manager.block_bits(parent_block)) {
fabric_bitstream.push_back(config_bit);
}
}
/********************************************************************
* A top-level function re-organizes the bitstream for a specific
* FPGA fabric, where configuration bits are organized in the sequence
* that can be directly loaded to the FPGA configuration protocol.
* Support:
* 1. Configuration chain
* 2. Memory decoders
* This function does NOT modify the bitstream database
* Instead, it builds a vector of ids for configuration bits in bitstream manager
*
* This function can be called ONLY after the function build_device_bitstream()
* Note that this function does NOT decode bitstreams from circuit implementation
* It was done in the function build_device_bitstream()
*******************************************************************/
std::vector<ConfigBitId> build_fabric_dependent_bitstream(const BitstreamManager& bitstream_manager,
const ModuleManager& module_manager) {
std::vector<ConfigBitId> fabric_bitstream;
vpr_printf(TIO_MESSAGE_INFO, "\nBuilding fabric dependent bitstream...\n");
/* Start time count */
clock_t t_start = clock();
/* Get the top module name in module manager, which is our starting point */
std::string top_module_name = generate_fpga_top_module_name();
ModuleId top_module = module_manager.find_module(top_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(top_module));
/* Find the top block in bitstream manager, which has not parents */
std::vector<ConfigBlockId> top_block = find_bitstream_manager_top_blocks(bitstream_manager);
/* Make sure we have only 1 top block and its name matches the top module */
VTR_ASSERT(1 == top_block.size());
VTR_ASSERT(0 == top_module_name.compare(bitstream_manager.block_name(top_block[0])));
rec_build_module_fabric_dependent_bitstream(bitstream_manager, top_block[0],
module_manager, top_module,
fabric_bitstream);
/* Time-consuming sanity check: Uncomment these codes only for debugging!!!
* Check which configuration bits are not touched
*/
/*
for (const ConfigBitId& config_bit : bitstream_manager.bits()) {
std::vector<ConfigBitId>::iterator it = std::find(fabric_bitstream.begin(), fabric_bitstream.end(), config_bit);
if (it == fabric_bitstream.end()) {
std::vector<ConfigBlockId> block_hierarchy = find_bitstream_manager_block_hierarchy(bitstream_manager, bitstream_manager.bit_parent_block(config_bit));
std::string block_hierarchy_name;
for (const ConfigBlockId& temp_block : block_hierarchy) {
block_hierarchy_name += std::string("/") + bitstream_manager.block_name(temp_block);
}
vpr_printf(TIO_MESSAGE_INFO,
"bit (parent_block = %s) is not touched!\n",
block_hierarchy_name.c_str());
}
}
*/
/* Ensure our fabric bitstream is in the same size as device bistream */
VTR_ASSERT(bitstream_manager.bits().size() == fabric_bitstream.size());
/* End time count */
clock_t t_end = clock();
float run_time_sec = (float)(t_end - t_start) / CLOCKS_PER_SEC;
vpr_printf(TIO_MESSAGE_INFO,
"Building fabric dependent bitstream took %g seconds\n",
run_time_sec);
return fabric_bitstream;
}

View File

@ -0,0 +1,11 @@
#ifndef BUILD_FABRIC_BITSTREAM_H
#define BUILD_FABRIC_BITSTREAM_H
#include <vector>
#include "bitstream_manager.h"
#include "module_manager.h"
std::vector<ConfigBitId> build_fabric_dependent_bitstream(const BitstreamManager& bitstream_manager,
const ModuleManager& module_manager);
#endif

View File

@ -236,7 +236,6 @@ void build_connection_block_interc_bitstream(BitstreamManager& bitstream_manager
const ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const std::vector<std::vector<t_grid_tile>>& grids,
const std::vector<t_switch_inf>& rr_switches,
t_rr_node* L_rr_node,
const RRGSB& rr_gsb,
@ -248,8 +247,7 @@ void build_connection_block_interc_bitstream(BitstreamManager& bitstream_manager
/* No bitstream generation required by a special direct connection*/
} else if (1 < src_rr_node->fan_in) {
/* Create the block denoting the memory instances that drives this node in Switch Block */
vtr::Point<size_t> ipin_coord(src_rr_node->xlow, src_rr_node->ylow);
std::string mem_block_name = generate_cb_memory_instance_name(CONNECTION_BLOCK_MEM_INSTANCE_PREFIX, grids, ipin_coord, rr_gsb.get_ipin_node_grid_side(cb_ipin_side, ipin_index), src_rr_node->ptc_num, std::string(""));
std::string mem_block_name = generate_cb_memory_instance_name(CONNECTION_BLOCK_MEM_INSTANCE_PREFIX, rr_gsb.get_ipin_node_grid_side(cb_ipin_side, ipin_index), src_rr_node->ptc_num, std::string(""));
ConfigBlockId mux_mem_block = bitstream_manager.add_block(mem_block_name);
bitstream_manager.add_child_block(cb_configurable_block, mux_mem_block);
/* This is a routing multiplexer! Generate bitstream */
@ -276,7 +274,6 @@ void build_connection_block_bitstream(BitstreamManager& bitstream_manager,
const ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const std::vector<std::vector<t_grid_tile>>& grids,
const std::vector<t_switch_inf>& rr_switches,
t_rr_node* L_rr_node,
const RRGSB& rr_gsb,
@ -291,7 +288,7 @@ void build_connection_block_bitstream(BitstreamManager& bitstream_manager,
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(cb_ipin_side); ++inode) {
build_connection_block_interc_bitstream(bitstream_manager, cb_configurable_block,
module_manager, circuit_lib, mux_lib,
grids, rr_switches, L_rr_node,
rr_switches, L_rr_node,
rr_gsb,
cb_ipin_side, inode);
}
@ -307,7 +304,6 @@ void build_connection_block_bitstreams(BitstreamManager& bitstream_manager,
const ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const std::vector<std::vector<t_grid_tile>>& grids,
const std::vector<t_switch_inf>& rr_switches,
t_rr_node* L_rr_node,
const DeviceRRGSB& L_device_rr_gsb,
@ -333,7 +329,7 @@ void build_connection_block_bitstreams(BitstreamManager& bitstream_manager,
bitstream_manager.add_child_block(top_configurable_block, cb_configurable_block);
build_connection_block_bitstream(bitstream_manager, cb_configurable_block, module_manager,
circuit_lib, mux_lib, grids, rr_switches, L_rr_node,
circuit_lib, mux_lib, rr_switches, L_rr_node,
rr_gsb, cb_type);
}
}
@ -350,7 +346,6 @@ void build_routing_bitstream(BitstreamManager& bitstream_manager,
const ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const std::vector<std::vector<t_grid_tile>>& grids,
const std::vector<t_switch_inf>& rr_switches,
t_rr_node* L_rr_node,
const DeviceRRGSB& L_device_rr_gsb) {
@ -384,13 +379,13 @@ void build_routing_bitstream(BitstreamManager& bitstream_manager,
vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for X-directionConnection blocks ...\n");
build_connection_block_bitstreams(bitstream_manager, top_configurable_block, module_manager,
circuit_lib, mux_lib, grids, rr_switches, L_rr_node,
circuit_lib, mux_lib, rr_switches, L_rr_node,
L_device_rr_gsb, CHANX);
vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for Y-directionConnection blocks ...\n");
build_connection_block_bitstreams(bitstream_manager, top_configurable_block, module_manager,
circuit_lib, mux_lib, grids, rr_switches, L_rr_node,
circuit_lib, mux_lib, rr_switches, L_rr_node,
L_device_rr_gsb, CHANY);
}

View File

@ -17,7 +17,6 @@ void build_routing_bitstream(BitstreamManager& bitstream_manager,
const ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const std::vector<std::vector<t_grid_tile>>& grids,
const std::vector<t_switch_inf>& rr_switches,
t_rr_node* L_rr_node,
const DeviceRRGSB& L_device_rr_gsb);

View File

@ -3,6 +3,7 @@
* which are the leaf circuit model in the circuit library
*******************************************************************/
#include <vector>
#include <ctime>
#include "util.h"
#include "vtr_assert.h"
@ -240,10 +241,23 @@ void build_constant_generator_module(ModuleManager& module_manager,
* 2. GND
********************************************************************/
void build_constant_generator_modules(ModuleManager& module_manager) {
/* Start time count */
clock_t t_start = clock();
vpr_printf(TIO_MESSAGE_INFO,
"Building modules for constant generator...");
/* VDD */
build_constant_generator_module(module_manager, 1);
/* GND */
build_constant_generator_module(module_manager, 0);
/* End time count */
clock_t t_end = clock();
float run_time_sec = (float)(t_end - t_start) / CLOCKS_PER_SEC;
vpr_printf(TIO_MESSAGE_INFO,
"took %g seconds\n",
run_time_sec);
}

View File

@ -564,6 +564,8 @@ void add_module_pb_graph_pin_interc(ModuleManager& module_manager,
*/
std::string mux_mem_instance_name = generate_pb_memory_instance_name(GRID_MEM_INSTANCE_PREFIX, des_pb_graph_pin, std::string(""));
module_manager.set_child_instance_name(pb_module, mux_mem_module, mux_mem_instance, mux_mem_instance_name);
/* Add this MUX as a configurable child to the pb_module */
module_manager.add_configurable_child(pb_module, mux_mem_module, mux_mem_instance);
/* Add nets to connect SRAM ports of the MUX to the SRAM port of memory module */
add_module_nets_between_logic_and_memory_sram_bus(module_manager, pb_module,

View File

@ -775,8 +775,7 @@ void build_connection_block_mux_module(ModuleManager& module_manager,
/* Give an instance name: this name should be consistent with the block name given in bitstream manager,
* If you want to bind the bitstream generation to modules
*/
vtr::Point<size_t> ipin_coord(cur_rr_node->xlow, cur_rr_node->ylow);
std::string mem_instance_name = generate_cb_memory_instance_name(CONNECTION_BLOCK_MEM_INSTANCE_PREFIX, grids, ipin_coord, rr_gsb.get_ipin_node_grid_side(cb_ipin_side, ipin_index), cur_rr_node->ptc_num, std::string(""));
std::string mem_instance_name = generate_cb_memory_instance_name(CONNECTION_BLOCK_MEM_INSTANCE_PREFIX, rr_gsb.get_ipin_node_grid_side(cb_ipin_side, ipin_index), cur_rr_node->ptc_num, std::string(""));
module_manager.set_child_instance_name(cb_module, mem_module, mem_instance_id, mem_instance_name);
/* Add nets to connect regular and mode-select SRAM ports to the SRAM port of memory module */

View File

@ -310,6 +310,7 @@ std::vector<std::vector<size_t>> add_top_module_connection_block_instances(Modul
/* If we use compact routing hierarchy, we should instanciate the unique module of SB */
if (true == compact_routing_hierarchy) {
DeviceCoordinator cb_coord(ix, iy);
/* Note: use GSB coordinate when inquire for unique modules!!! */
const RRGSB& unique_mirror = L_device_rr_gsb.get_cb_unique_module(cb_type, cb_coord);
cb_coordinate.set_x(unique_mirror.get_cb_x(cb_type));
cb_coordinate.set_y(unique_mirror.get_cb_y(cb_type));
@ -324,10 +325,10 @@ std::vector<std::vector<size_t>> add_top_module_connection_block_instances(Modul
/* Set an unique name to the instance
* Note: it is your risk to gurantee the name is unique!
*/
std::string cb_instance_name = generate_connection_block_module_name(cb_type, vtr::Point<size_t>(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type)));
module_manager.set_child_instance_name(top_module, cb_module,
cb_instance_ids[rr_gsb.get_cb_x(cb_type)][rr_gsb.get_cb_y(cb_type)],
generate_connection_block_module_name(cb_type, vtr::Point<size_t>(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type))));
cb_instance_name);
}
}

View File

@ -39,7 +39,8 @@ void organize_top_module_tile_cb_modules(ModuleManager& module_manager,
vtr::Point<size_t> cb_coord(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type));
/* If we use compact routing hierarchy, we should instanciate the unique module of SB */
if (true == compact_routing_hierarchy) {
const RRGSB& unique_mirror = L_device_rr_gsb.get_cb_unique_module(cb_type, DeviceCoordinator(cb_coord.x(), cb_coord.y()));
/* Note: use GSB coordinate when inquire for unique modules!!! */
const RRGSB& unique_mirror = L_device_rr_gsb.get_cb_unique_module(cb_type, DeviceCoordinator(rr_gsb.get_x(), rr_gsb.get_y()));
cb_coord.set_x(unique_mirror.get_cb_x(cb_type));
cb_coord.set_y(unique_mirror.get_cb_y(cb_type));
}
@ -54,7 +55,8 @@ void organize_top_module_tile_cb_modules(ModuleManager& module_manager,
if (0 < find_module_num_config_bits(module_manager, cb_module,
circuit_lib, sram_model,
sram_orgz_type)) {
module_manager.add_configurable_child(top_module, cb_module, cb_instance_ids[cb_coord.x()][cb_coord.y()]);
/* Note that use the original CB coodinate for instance id searching ! */
module_manager.add_configurable_child(top_module, cb_module, cb_instance_ids[rr_gsb.get_cb_x(cb_type)][rr_gsb.get_cb_y(cb_type)]);
}
}
@ -107,7 +109,7 @@ void organize_top_module_tile_memory_modules(ModuleManager& module_manager,
if (0 < find_module_num_config_bits(module_manager, sb_module,
circuit_lib, sram_model,
sram_orgz_type)) {
module_manager.add_configurable_child(top_module, sb_module, sb_instance_ids[sb_coord.x()][sb_coord.y()]);
module_manager.add_configurable_child(top_module, sb_module, sb_instance_ids[rr_gsb.get_sb_x()][rr_gsb.get_sb_y()]);
}
/* Try to find and add CBX and CBY */
@ -126,6 +128,16 @@ void organize_top_module_tile_memory_modules(ModuleManager& module_manager,
/* Find the module name for this type of grid */
t_type_ptr grid_type = grids[tile_coord.x()][tile_coord.y()].type;
/* Skip EMPTY Grid */
if (EMPTY_TYPE == grid_type) {
return;
}
/* Skip height>1 Grid, which should already been processed when offset=0 */
if (0 < grids[tile_coord.x()][tile_coord.y()].offset) {
return;
}
std::string grid_module_name_prefix(grid_verilog_file_name_prefix);
std::string grid_module_name = generate_grid_block_module_name(grid_module_name_prefix, std::string(grid_type->name), IO_TYPE == grid_type, tile_border_side);
ModuleId grid_module = module_manager.find_module(grid_module_name);
@ -232,10 +244,26 @@ void organize_top_module_memory_modules(ModuleManager& module_manager,
io_coords[RIGHT].push_back(vtr::Point<size_t>(device_size.x() - 1, iy));
}
/* TOP side I/Os */
/* TOP side I/Os
* Special case for TOP side: We need tile at ix = 0, which has a SB!!!
*
* TOP-LEFT CORNER of FPGA fabric
*
* +--------+ +-------+
* | EMPTY | | EMPTY |
* | Grid | | CBX |
* | [0][x] | | |
* +--------+ +-------+
* +--------+ +--------+
* | EMPTY | | SB |
* | CBX | | [0][x] |
* +--------+ +--------+
*
*/
for (size_t ix = device_size.x() - 2; ix >= 1; --ix) {
io_coords[TOP].push_back(vtr::Point<size_t>(ix, device_size.y() - 1));
}
io_coords[TOP].push_back(vtr::Point<size_t>(0, device_size.y() - 1));
/* LEFT side I/Os */
for (size_t iy = device_size.y() - 2; iy >= 1; --iy) {