diff --git a/openfpga/src/fpga_bitstream/build_device_bitstream.cpp b/openfpga/src/fpga_bitstream/build_device_bitstream.cpp index 3f38e03a7..a2aa97f57 100644 --- a/openfpga/src/fpga_bitstream/build_device_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_device_bitstream.cpp @@ -13,6 +13,8 @@ #include "openfpga_naming.h" +#include "module_manager_utils.h" + #include "build_grid_bitstream.h" #include "build_routing_bitstream.h" #include "build_device_bitstream.h" @@ -146,7 +148,7 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx, /* Reserve child blocks for the top level block */ bitstream_manager.reserve_child_blocks(top_block, - openfpga_ctx.module_graph().configurable_children(top_module).size()); + count_module_manager_module_configurable_children(openfpga_ctx.module_graph(), top_module)); /* Create bitstream from grids */ VTR_LOGV(verbose, "Building grid bitstream...\n"); @@ -172,7 +174,8 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx, openfpga_ctx.vpr_device_annotation(), openfpga_ctx.vpr_routing_annotation(), vpr_ctx.device().rr_graph, - openfpga_ctx.device_rr_gsb()); + openfpga_ctx.device_rr_gsb(), + openfpga_ctx.flow_manager().compress_routing()); VTR_LOGV(verbose, "Done\n"); VTR_LOGV(verbose, @@ -180,8 +183,8 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx, bitstream_manager.num_bits(), bitstream_manager.num_blocks()); - //VTR_ASSERT(num_blocks_to_reserve == bitstream_manager.num_blocks()); - //VTR_ASSERT(num_bits_to_reserve == bitstream_manager.num_bits()); + VTR_ASSERT(num_blocks_to_reserve == bitstream_manager.num_blocks()); + VTR_ASSERT(num_bits_to_reserve == bitstream_manager.num_bits()); return bitstream_manager; } diff --git a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp index 436c04697..f970a746c 100644 --- a/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_grid_bitstream.cpp @@ -24,6 +24,7 @@ #include "mux_bitstream_constants.h" #include "pb_type_utils.h" #include "lut_utils.h" +#include "module_manager_utils.h" #include "build_mux_bitstream.h" #include "build_grid_bitstream.h" @@ -492,11 +493,25 @@ void rec_build_physical_block_bitstream(BitstreamManager& bitstream_manager, /* Find the mode that define_idle_mode*/ t_mode* physical_mode = device_annotation.physical_mode(physical_pb_type); + /* Early exit if this parent module has no configurable child modules */ + std::string pb_module_name = generate_physical_block_module_name(physical_pb_type); + ModuleId pb_module = module_manager.find_module(pb_module_name); + VTR_ASSERT(true == module_manager.valid_module_id(pb_module)); + + /* Skip module with no configurable children */ + if (0 == module_manager.configurable_children(pb_module).size()) { + return; + } + /* Create a block for the physical block under the grid block in bitstream manager */ std::string pb_block_name = generate_physical_block_instance_name(physical_pb_type, pb_graph_node_index); ConfigBlockId pb_configurable_block = bitstream_manager.add_block(pb_block_name); bitstream_manager.add_child_block(parent_configurable_block, pb_configurable_block); + /* Reserve child blocks for new created block */ + bitstream_manager.reserve_child_blocks(parent_configurable_block, + count_module_manager_module_configurable_children(module_manager, pb_module)); + /* Recursively finish all the child pb_types*/ if (false == is_primitive_pb_type(physical_pb_type)) { for (int ipb = 0; ipb < physical_mode->num_pb_type_children; ++ipb) { @@ -583,11 +598,27 @@ void build_physical_block_bitstream(BitstreamManager& bitstream_manager, /* Create a block for the grid in bitstream manager */ t_physical_tile_type_ptr grid_type = grids[grid_coord.x()][grid_coord.y()].type; std::string grid_module_name_prefix(GRID_MODULE_NAME_PREFIX); + + /* Early exit if this parent module has no configurable child modules */ + std::string grid_module_name = generate_grid_block_module_name(grid_module_name_prefix, std::string(grid_type->name), + is_io_type(grid_type), border_side); + ModuleId grid_module = module_manager.find_module(grid_module_name); + VTR_ASSERT(true == module_manager.valid_module_id(grid_module)); + + /* Skip module with no configurable children */ + if (0 == module_manager.configurable_children(grid_module).size()) { + return; + } + std::string grid_block_name = generate_grid_block_instance_name(grid_module_name_prefix, std::string(grid_type->name), is_io_type(grid_type), border_side, grid_coord); ConfigBlockId grid_configurable_block = bitstream_manager.add_block(grid_block_name); bitstream_manager.add_child_block(top_block, grid_configurable_block); + /* Reserve child blocks for new created block */ + bitstream_manager.reserve_child_blocks(grid_configurable_block, + count_module_manager_module_configurable_children(module_manager, grid_module)); + /* Iterate over the capacity of the grid * Now each physical tile may have a number of logical blocks * OpenFPGA only considers the physical implementation of the tiles. diff --git a/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp b/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp index 1e6b8d3c6..4f25a3a44 100644 --- a/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/build_routing_bitstream.cpp @@ -18,6 +18,7 @@ #include "openfpga_reserved_words.h" #include "openfpga_naming.h" #include "openfpga_rr_graph_utils.h" +#include "module_manager_utils.h" #include "mux_bitstream_constants.h" #include "build_mux_bitstream.h" @@ -403,6 +404,7 @@ void build_connection_block_bitstreams(BitstreamManager& bitstream_manager, const VprRoutingAnnotation& routing_annotation, const RRGraph& rr_graph, const DeviceRRGSB& device_rr_gsb, + const bool& compact_routing_hierarchy, const t_rr_type& cb_type) { vtr::Point cb_range = device_rr_gsb.get_gsb_range(); @@ -421,11 +423,29 @@ void build_connection_block_bitstreams(BitstreamManager& bitstream_manager, if (true == connection_block_contain_only_routing_tracks(rr_gsb, cb_type)) { continue; } - /* Create a block for the bitstream which corresponds to the Switch block */ + + /* Find the cb module so that we can precisely reserve child blocks */ vtr::Point cb_coord(rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type)); + std::string cb_module_name = generate_connection_block_module_name(cb_type, cb_coord); + if (true == compact_routing_hierarchy) { + vtr::Point unique_cb_coord(ix, iy); + /* Note: use GSB coordinate when inquire for unique modules!!! */ + const RRGSB& unique_mirror = device_rr_gsb.get_cb_unique_module(cb_type, unique_cb_coord); + unique_cb_coord.set_x(unique_mirror.get_cb_x(cb_type)); + unique_cb_coord.set_y(unique_mirror.get_cb_y(cb_type)); + cb_module_name = generate_connection_block_module_name(cb_type, unique_cb_coord); + } + ModuleId cb_module = module_manager.find_module(cb_module_name); + VTR_ASSERT(true == module_manager.valid_module_id(cb_module)); + + /* 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 */ bitstream_manager.add_child_block(top_configurable_block, cb_configurable_block); + + /* Reserve child blocks for new created block */ + bitstream_manager.reserve_child_blocks(cb_configurable_block, + count_module_manager_module_configurable_children(module_manager, cb_module)); build_connection_block_bitstream(bitstream_manager, cb_configurable_block, module_manager, circuit_lib, mux_lib, @@ -451,7 +471,8 @@ void build_routing_bitstream(BitstreamManager& bitstream_manager, const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraph& rr_graph, - const DeviceRRGSB& device_rr_gsb) { + const DeviceRRGSB& device_rr_gsb, + const bool& compact_routing_hierarchy) { /* Generate bitstream for each switch blocks * To organize the bitstream in blocks, we create a block for each switch block @@ -470,12 +491,29 @@ void build_routing_bitstream(BitstreamManager& bitstream_manager, continue; } - /* Create a block for the bitstream which corresponds to the Switch block */ vtr::Point sb_coord(rr_gsb.get_sb_x(), rr_gsb.get_sb_y()); + + /* Find the sb module so that we can precisely reserve child blocks */ + std::string sb_module_name = generate_switch_block_module_name(sb_coord); + if (true == compact_routing_hierarchy) { + vtr::Point unique_sb_coord(ix, iy); + const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(sb_coord); + unique_sb_coord.set_x(unique_mirror.get_sb_x()); + unique_sb_coord.set_y(unique_mirror.get_sb_y()); + sb_module_name = generate_switch_block_module_name(unique_sb_coord); + } + ModuleId sb_module = module_manager.find_module(sb_module_name); + VTR_ASSERT(true == module_manager.valid_module_id(sb_module)); + + /* 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 */ bitstream_manager.add_child_block(top_configurable_block, sb_configurable_block); + /* Reserve child blocks for new created block */ + bitstream_manager.reserve_child_blocks(sb_configurable_block, + count_module_manager_module_configurable_children(module_manager, sb_module)); + build_switch_block_bitstream(bitstream_manager, sb_configurable_block, module_manager, circuit_lib, mux_lib, atom_ctx, device_annotation, routing_annotation, @@ -495,7 +533,9 @@ void build_routing_bitstream(BitstreamManager& bitstream_manager, circuit_lib, mux_lib, atom_ctx, device_annotation, routing_annotation, rr_graph, - device_rr_gsb, CHANX); + device_rr_gsb, + compact_routing_hierarchy, + CHANX); VTR_LOG("Done\n"); VTR_LOG("Generating bitstream for Y-direction Connection blocks ..."); @@ -504,7 +544,9 @@ void build_routing_bitstream(BitstreamManager& bitstream_manager, circuit_lib, mux_lib, atom_ctx, device_annotation, routing_annotation, rr_graph, - device_rr_gsb, CHANY); + device_rr_gsb, + compact_routing_hierarchy, + CHANY); VTR_LOG("Done\n"); } diff --git a/openfpga/src/fpga_bitstream/build_routing_bitstream.h b/openfpga/src/fpga_bitstream/build_routing_bitstream.h index c98e6e32e..6bd18dcbd 100644 --- a/openfpga/src/fpga_bitstream/build_routing_bitstream.h +++ b/openfpga/src/fpga_bitstream/build_routing_bitstream.h @@ -33,7 +33,8 @@ void build_routing_bitstream(BitstreamManager& bitstream_manager, const VprDeviceAnnotation& device_annotation, const VprRoutingAnnotation& routing_annotation, const RRGraph& rr_graph, - const DeviceRRGSB& device_rr_gsb); + const DeviceRRGSB& device_rr_gsb, + const bool& compact_routing_hierarchy); } /* end namespace openfpga */ diff --git a/openfpga/src/utils/module_manager_utils.cpp b/openfpga/src/utils/module_manager_utils.cpp index ce04904ba..f05bb9354 100644 --- a/openfpga/src/utils/module_manager_utils.cpp +++ b/openfpga/src/utils/module_manager_utils.cpp @@ -76,6 +76,23 @@ void reserve_module_manager_module_nets(ModuleManager& module_manager, module_manager.reserve_module_nets(parent_module, num_nets); } +/****************************************************************************** + * Count the 'actual' number of configurable children for a module in module manager + * A 'true' configurable children should have a number of configurable children as well + ******************************************************************************/ +size_t count_module_manager_module_configurable_children(const ModuleManager& module_manager, + const ModuleId& module) { + size_t num_config_children = 0; + + for (const ModuleId& child : module_manager.configurable_children(module)) { + if (0 != module_manager.configurable_children(child).size()) { + num_config_children++; + } + } + + return num_config_children; +} + /****************************************************************************** * Add a module to the module manager based on the circuit-level * description of a circuit model diff --git a/openfpga/src/utils/module_manager_utils.h b/openfpga/src/utils/module_manager_utils.h index 0532fe991..d80d200a7 100644 --- a/openfpga/src/utils/module_manager_utils.h +++ b/openfpga/src/utils/module_manager_utils.h @@ -34,6 +34,9 @@ namespace openfpga { void reserve_module_manager_module_nets(ModuleManager& module_manager, const ModuleId& module); +size_t count_module_manager_module_configurable_children(const ModuleManager& module_manager, + const ModuleId& module); + ModuleId add_circuit_model_to_module_manager(ModuleManager& module_manager, const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model, const std::string& module_name);