[Tool] Adapted tools to support I/O in center grid

This commit is contained in:
tangxifan 2020-12-04 18:50:13 -07:00
parent 6001da3a40
commit 5be9e9b736
11 changed files with 87 additions and 35 deletions

View File

@ -1003,7 +1003,7 @@ std::string generate_grid_block_netlist_name(const std::string& block_name,
/* Add the name of physical block */
std::string module_name(block_name);
if (true == is_block_io) {
if ((true == is_block_io) && (NUM_SIDES != io_side)) {
SideManager side_manager(io_side);
module_name += std::string("_");
module_name += std::string(side_manager.to_string());

View File

@ -99,6 +99,65 @@ IoLocationMap build_fabric_io_location_map(const ModuleManager& module_manager,
}
}
/* Walk through all the center grids, which may include I/O grids */
for (size_t ix = 1; ix < grids.width() - 1; ++ix) {
for (size_t iy = 1; iy < grids.height() - 1; ++iy) {
/* Bypass EMPTY grid */
if (true == is_empty_type(grids[ix][iy].type)) {
continue;
}
/* Skip width or height > 1 tiles (mostly heterogeneous blocks) */
if ( (0 < grids[ix][iy].width_offset)
|| (0 < grids[ix][iy].height_offset)) {
continue;
}
t_physical_tile_type_ptr grid_type = grids[ix][iy].type;
/* Find the module name for this type of grid */
std::string grid_module_name_prefix(GRID_MODULE_NAME_PREFIX);
std::string grid_module_name = generate_grid_block_module_name(grid_module_name_prefix, std::string(grid_type->name), is_io_type(grid_type), NUM_SIDES);
ModuleId grid_module = module_manager.find_module(grid_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(grid_module));
/* Find all the GPIO ports in the grid module */
/* MUST DO: register in io location mapping!
* I/O location mapping is a critical look-up for testbench generators
* As we add the I/O grid instances to top module by following order:
* TOP -> RIGHT -> BOTTOM -> LEFT
* The I/O index will increase in this way as well.
* This organization I/O indices is also consistent to the way
* that GPIOs are wired in function connect_gpio_module()
*
* Note: if you change the GPIO function, you should update here as well!
*/
for (int z = 0; z < grids[ix][iy].type->capacity; ++z) {
for (const ModuleManager::e_module_port_type& module_io_port_type : MODULE_IO_PORT_TYPES) {
for (const ModulePortId& gpio_port_id : module_manager.module_port_ids_by_type(grid_module, module_io_port_type)) {
/* Only care mappable I/O */
if (false == module_manager.port_is_mappable_io(grid_module, gpio_port_id)) {
continue;
}
const BasicPort& gpio_port = module_manager.module_port(grid_module, gpio_port_id);
auto curr_io_index = io_counter.find(gpio_port.get_name());
/* Index always start from zero */
if (curr_io_index == io_counter.end()) {
io_counter[gpio_port.get_name()] = 0;
}
io_location_map.set_io_index(ix, iy, z,
gpio_port.get_name(),
io_counter[gpio_port.get_name()]);
io_counter[gpio_port.get_name()]++;
}
}
}
}
}
/* Check all the GPIO ports in the top-level module has been mapped */
std::string top_module_name = generate_fpga_top_module_name();
ModuleId top_module = module_manager.find_module(top_module_name);

View File

@ -66,7 +66,7 @@ void add_grid_module_duplicated_pb_type_ports(ModuleManager& module_manager,
* Otherwise, we will iterate all the 4 sides
*/
if (true == is_io_type(grid_type_descriptor)) {
grid_pin_sides.push_back(find_grid_module_pin_side(grid_type_descriptor, border_side));
grid_pin_sides = find_grid_module_pin_sides(grid_type_descriptor, border_side);
} else {
grid_pin_sides = {TOP, RIGHT, BOTTOM, LEFT};
}
@ -147,12 +147,9 @@ void add_grid_module_net_connect_duplicated_pb_graph_pin(ModuleManager& module_m
* Otherwise, we will iterate all the 4 sides
*/
if (true == is_io_type(grid_type_descriptor)) {
grid_pin_sides.push_back(find_grid_module_pin_side(grid_type_descriptor, border_side));
grid_pin_sides = find_grid_module_pin_sides(grid_type_descriptor, border_side);
} else {
grid_pin_sides.push_back(TOP);
grid_pin_sides.push_back(RIGHT);
grid_pin_sides.push_back(BOTTOM);
grid_pin_sides.push_back(LEFT);
grid_pin_sides = {TOP, RIGHT, BOTTOM, LEFT};
}
/* num_pins/capacity = the number of pins that each type_descriptor has.

View File

@ -23,13 +23,19 @@ namespace openfpga {
* 2. I/O grids on the right side of FPGA only have ports on its left side
* 3. I/O grids on the bottom side of FPGA only have ports on its top side
* 4. I/O grids on the left side of FPGA only have ports on its right side
* 5. I/O grids in the center part of FPGA can have ports on any side
*******************************************************************/
e_side find_grid_module_pin_side(t_physical_tile_type_ptr grid_type_descriptor,
std::vector<e_side> find_grid_module_pin_sides(t_physical_tile_type_ptr grid_type_descriptor,
const e_side& border_side) {
/* We must have an regular (non-I/O) type here */
VTR_ASSERT(true == is_io_type(grid_type_descriptor));
SideManager side_manager(border_side);
return side_manager.get_opposite();
if (NUM_SIDES == border_side) {
return {TOP, RIGHT, BOTTOM, LEFT};
}
return std::vector<e_side>(1, side_manager.get_opposite());
}
/********************************************************************
@ -50,12 +56,9 @@ void add_grid_module_net_connect_pb_graph_pin(ModuleManager& module_manager,
* Otherwise, we will iterate all the 4 sides
*/
if (true == is_io_type(grid_type_descriptor)) {
grid_pin_sides.push_back(find_grid_module_pin_side(grid_type_descriptor, border_side));
grid_pin_sides = find_grid_module_pin_sides(grid_type_descriptor, border_side);
} else {
grid_pin_sides.push_back(TOP);
grid_pin_sides.push_back(RIGHT);
grid_pin_sides.push_back(BOTTOM);
grid_pin_sides.push_back(LEFT);
grid_pin_sides = {TOP, RIGHT, BOTTOM, LEFT};
}
/* num_pins/capacity = the number of pins that each type_descriptor has.

View File

@ -17,7 +17,7 @@
/* begin namespace openfpga */
namespace openfpga {
e_side find_grid_module_pin_side(t_physical_tile_type_ptr grid_type_descriptor,
std::vector<e_side> find_grid_module_pin_sides(t_physical_tile_type_ptr grid_type_descriptor,
const e_side& border_side);
void add_grid_module_net_connect_pb_graph_pin(ModuleManager& module_manager,

View File

@ -52,7 +52,7 @@ void add_grid_module_pb_type_ports(ModuleManager& module_manager,
* Otherwise, we will iterate all the 4 sides
*/
if (true == is_io_type(grid_type_descriptor)) {
grid_pin_sides.push_back(find_grid_module_pin_side(grid_type_descriptor, border_side));
grid_pin_sides = find_grid_module_pin_sides(grid_type_descriptor, border_side);
} else {
grid_pin_sides = {TOP, RIGHT, BOTTOM, LEFT};
}
@ -981,11 +981,6 @@ void build_physical_tile_module(ModuleManager& module_manager,
const e_side& border_side,
const bool& duplicate_grid_pin,
const bool& verbose) {
/* Check code: if this is an IO block, the border side MUST be valid */
if (true == is_io_type(phy_block_type)) {
VTR_ASSERT(NUM_SIDES != border_side);
}
/* Create a Module for the top-level physical block, and add to module manager */
std::string grid_module_name = generate_grid_block_module_name(std::string(GRID_MODULE_NAME_PREFIX),
std::string(phy_block_type->name),

View File

@ -120,8 +120,6 @@ vtr::Matrix<size_t> add_top_module_grid_instances(ModuleManager& module_manager,
grid_instance_ids[ix][iy] = grid_instance_ids[root_grid_coord.x()][root_grid_coord.y()];
continue;
}
/* We should not meet any I/O grid */
VTR_ASSERT(false == is_io_type(grids[ix][iy].type));
/* Add a grid module to top_module*/
vtr::Point<size_t> grid_coord(ix, iy);
grid_instance_ids[ix][iy] = add_top_module_grid_instance(module_manager, top_module,

View File

@ -710,8 +710,6 @@ void build_grid_bitstream(BitstreamManager& bitstream_manager,
|| (0 < grids[ix][iy].height_offset) ) {
continue;
}
/* We should not meet any I/O grid */
VTR_ASSERT(true != is_io_type(grids[ix][iy].type));
/* Add a grid module to top_module*/
vtr::Point<size_t> grid_coord(ix, iy);
build_physical_block_bitstream(bitstream_manager, top_block, module_manager,

View File

@ -463,6 +463,11 @@ void build_connection_block_bitstreams(BitstreamManager& bitstream_manager,
ModuleId cb_module = module_manager.find_module(cb_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(cb_module));
/* Bypass empty blocks which have none configurable children */
if (0 == count_module_manager_module_configurable_children(module_manager, cb_module)) {
continue;
}
/* Create a block for the bitstream which corresponds to the Switch block */
ConfigBlockId cb_configurable_block = bitstream_manager.add_block(generate_connection_block_module_name(cb_type, cb_coord));
/* Set switch block as a child of top block */
@ -530,6 +535,11 @@ void build_routing_bitstream(BitstreamManager& bitstream_manager,
ModuleId sb_module = module_manager.find_module(sb_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(sb_module));
/* Bypass empty blocks which have none configurable children */
if (0 == count_module_manager_module_configurable_children(module_manager, sb_module)) {
continue;
}
/* Create a block for the bitstream which corresponds to the Switch block */
ConfigBlockId sb_configurable_block = bitstream_manager.add_block(generate_switch_block_module_name(sb_coord));
/* Set switch block as a child of top block */

View File

@ -618,9 +618,6 @@ void print_analysis_sdc_disable_unused_grids(std::fstream& fp,
/* Process unused core grids */
for (size_t ix = 1; ix < grids.width() - 1; ++ix) {
for (size_t iy = 1; iy < grids.height() - 1; ++iy) {
/* We should not meet any I/O grid */
VTR_ASSERT(false == is_io_type(grids[ix][iy].type));
print_analysis_sdc_disable_unused_grid(fp, vtr::Point<size_t>(ix, iy),
grids, device_annotation, cluster_annotation, place_annotation,
module_manager, NUM_SIDES);

View File

@ -286,11 +286,6 @@ void print_verilog_physical_tile_netlist(NetlistManager& netlist_manager,
t_physical_tile_type_ptr phy_block_type,
const e_side& border_side,
const bool& use_explicit_mapping) {
/* Check code: if this is an IO block, the border side MUST be valid */
if (true == is_io_type(phy_block_type)) {
VTR_ASSERT(NUM_SIDES != border_side);
}
/* Give a name to the Verilog netlist */
/* Create the file name for Verilog */
std::string verilog_fname(subckt_dir