Merge branch 'master' into openfpga-issue-1256

This commit is contained in:
tangxifan 2023-08-07 13:49:19 -07:00 committed by GitHub
commit bb945b2816
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 2636 additions and 631 deletions

View File

@ -0,0 +1,39 @@
.. _file_formats_tile_config_file:
Tile Organization (.xml)
------------------------
The XML-based description language is used to describe how each tile is composed.
For example, what programmable blocks, connection blocks and switch blocks should be included.
Using the description language, users can customize the tiles of an FPGA fabric, as detailed as each component in each tile.
Under the root node ``<tiles>``, the detailes of tile organization can be described.
.. code-block:: xml
<tiles style="<string>"/>
</tiles>
Syntax
``````
Detailed syntax are presented as follows.
.. option:: style="<string>"
Specify the style of tile organization. Can be [``top_left`` | ``top_right`` | ``bottom_left`` | ``bottom_right`` | ``custom``]
.. warning:: Currently, only ``top_left`` is supported!
The ``top_left`` is a shortcut to define the organization for all the tiles. :numref:`fig_tile_style_top_left` shows an example of tiles in the top-left sytle, where the programmable block locates in the top-left corner of all the tiles, surrounded by two connection blocks and one switch blocks.
.. _fig_tile_style_top_left:
.. figure:: ./figures/tile_style_top_left.png
:width: 100%
:alt: An example of top-left style of tile
An example of top-left style of a tile in FPGA fabric

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

@ -260,7 +260,26 @@ build_fabric
.. warning:: This option does not support ``--duplicate_grid_pin``!
.. warning:: This option requires ``--compress_routing`` to be enabled!
.. option:: --group_config_block
Group configuration memory blocks under each CLB/SB/CB etc. into a centralized configuration memory blocks, as depicted in :numref:`fig_group_config_block_overview`. When disabled, the configuration memory blocks are placed in a distributed way under CLB/SB/CB etc. For example, each programming resource, e.g., LUT, has a dedicated configuration memory block, being placed in the same module. When enabled, as illustrated in :numref:`fig_group_config_block_hierarchy`, the physical memory block locates under a CLB, driving a number of logical memory blocks which are close to the programmable resources. The logical memory blocks contain only pass-through wires which can be optimized out during physical design phase.
.. _fig_group_config_block_overview:
.. figure:: ./figures/group_config_block_overview.png
:width: 100%
Impact on grouping configuable blocks: before and after
.. _fig_group_config_block_hierarchy:
.. figure:: ./figures/group_config_block_hierarchy.png
:width: 100%
Netlist hierarchy on grouped configuable blocks
.. option:: --duplicate_grid_pin
Enable pin duplication on grid modules. This is optional unless ultra-dense layout generation is needed

View File

@ -129,10 +129,13 @@ constexpr std::array<const char*, NUM_CIRCUIT_MODEL_DELAY_TYPES>
/********************************************************************
* Types of configuration protocol
* 1. configurable memories are organized and accessed as standalone elements
* 2. configurable memories are organized and accessed by a scan-chain
* 3. configurable memories are organized and accessed by memory bank
* 4. configurable memories are organized and accessed by frames
* - configurable memories are organized and accessed as standalone elements
* - configurable memories are organized and accessed by a scan-chain
* - configurable memories are organized and accessed by quicklogic memory bank
* - configurable memories are organized and accessed by memory bank
* - configurable memories are organized and accessed by frames
* - configurable memories are organized and accessed by feedthrough. Currently,
* this is only for internal use only
*/
enum e_config_protocol_type {
CONFIG_MEM_STANDALONE,
@ -140,11 +143,13 @@ enum e_config_protocol_type {
CONFIG_MEM_MEMORY_BANK,
CONFIG_MEM_QL_MEMORY_BANK,
CONFIG_MEM_FRAME_BASED,
CONFIG_MEM_FEEDTHROUGH,
NUM_CONFIG_PROTOCOL_TYPES
};
constexpr std::array<const char*, NUM_CONFIG_PROTOCOL_TYPES>
CONFIG_PROTOCOL_TYPE_STRING = {{"standalone", "scan_chain", "memory_bank",
"ql_memory_bank", "frame_based"}};
"ql_memory_bank", "frame_based",
"feedthrough"}};
#endif

View File

@ -41,6 +41,11 @@ constexpr const char* GRID_MEM_INSTANCE_PREFIX = "mem_";
constexpr const char* SWITCH_BLOCK_MEM_INSTANCE_PREFIX = "mem_";
constexpr const char* CONNECTION_BLOCK_MEM_INSTANCE_PREFIX = "mem_";
constexpr const char* MEMORY_MODULE_POSTFIX = "_mem";
constexpr const char* MEMORY_FEEDTHROUGH_MODULE_POSTFIX = "_feedthrough_mem";
constexpr const char* MEMORY_FEEDTHROUGH_DATA_IN_PORT_NAME =
"feedthrough_mem_in";
constexpr const char* MEMORY_FEEDTHROUGH_DATA_IN_INV_PORT_NAME =
"feedthrough_mem_inb";
constexpr const char* MEMORY_BL_PORT_NAME = "bl";
constexpr const char* MEMORY_WL_PORT_NAME = "wl";
constexpr const char* MEMORY_WLR_PORT_NAME = "wlr";

View File

@ -100,6 +100,7 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd,
CommandOptionId opt_write_fabric_key = cmd.option("write_fabric_key");
CommandOptionId opt_load_fabric_key = cmd.option("load_fabric_key");
CommandOptionId opt_group_tile = cmd.option("group_tile");
CommandOptionId opt_group_config_block = cmd.option("group_config_block");
CommandOptionId opt_verbose = cmd.option("verbose");
/* Report conflicts with options:
@ -175,6 +176,7 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd,
cmd_context.option_enable(cmd, opt_compress_routing),
cmd_context.option_enable(cmd, opt_duplicate_grid_pin),
predefined_fabric_key, tile_config,
cmd_context.option_enable(cmd, opt_group_config_block),
cmd_context.option_enable(cmd, opt_gen_random_fabric_key),
cmd_context.option_enable(cmd, opt_verbose));

View File

@ -225,12 +225,18 @@ std::string generate_segment_wire_mid_output_name(
/*********************************************************************
* Generate the module name for a memory sub-circuit
* If this is a module just to feed through memory lines, use a special name
********************************************************************/
std::string generate_memory_module_name(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
const CircuitModelId& sram_model,
const std::string& postfix) {
return std::string(circuit_lib.model_name(circuit_model) + "_" +
const std::string& postfix,
const bool& feedthrough_memory) {
std::string mid_name;
if (feedthrough_memory) {
mid_name = "feedthrough_";
}
return std::string(circuit_lib.model_name(circuit_model) + "_" + mid_name +
circuit_lib.model_name(sram_model) + postfix);
}
@ -522,6 +528,15 @@ std::string generate_tile_module_netlist_name(const std::string& block_name,
return block_name + postfix;
}
/*********************************************************************
* Generate the module name of a physical memory module
**********************************************************************/
std::string generate_physical_memory_module_name(const std::string& prefix,
const size_t& mem_size) {
return prefix + std::string("_config_group_mem_size") +
std::to_string(mem_size);
}
/*********************************************************************
* Generate the module name for a connection block with a given coordinate
*********************************************************************/
@ -734,6 +749,26 @@ std::string generate_sram_port_name(
std::string port_name;
switch (sram_orgz_type) {
case CONFIG_MEM_FEEDTHROUGH:
/* Two types of ports are available:
* (1) BL indicates the mem port
* (2) BLB indicates the inverted mem port
*
* mem mem_inv
* [0] [0]
* | |
* v v
* +----------------+
* | Virtual Mem |
* +----------------+
*/
if (CIRCUIT_MODEL_PORT_BL == port_type) {
port_name = std::string(MEMORY_FEEDTHROUGH_DATA_IN_PORT_NAME);
} else {
VTR_ASSERT(CIRCUIT_MODEL_PORT_BLB == port_type);
port_name = std::string(MEMORY_FEEDTHROUGH_DATA_IN_INV_PORT_NAME);
}
break;
case CONFIG_MEM_SCAN_CHAIN:
/* Two types of ports are available:
* (1) Head of a chain of Configuration-chain Flip-Flops (CCFFs), enabled
@ -1065,8 +1100,12 @@ std::string generate_sb_mux_instance_name(const std::string& prefix,
std::string generate_sb_memory_instance_name(const std::string& prefix,
const e_side& sb_side,
const size_t& track_id,
const std::string& postfix) {
const std::string& postfix,
const bool& feedthrough_memory) {
std::string instance_name(prefix);
if (feedthrough_memory) {
instance_name = std::string("feedthrough_") + instance_name;
}
instance_name += SideManager(sb_side).to_string();
instance_name += std::string("_track_") + std::to_string(track_id);
instance_name += postfix;
@ -1103,8 +1142,12 @@ std::string generate_cb_mux_instance_name(const std::string& prefix,
std::string generate_cb_memory_instance_name(const std::string& prefix,
const e_side& cb_side,
const size_t& pin_id,
const std::string& postfix) {
const std::string& postfix,
const bool& feedthrough_memory) {
std::string instance_name(prefix);
if (feedthrough_memory) {
instance_name = std::string("feedthrough_") + instance_name;
}
instance_name += SideManager(cb_side).to_string();
instance_name += std::string("_ipin_") + std::to_string(pin_id);
@ -1159,8 +1202,10 @@ std::string generate_pb_mux_instance_name(const std::string& prefix,
********************************************************************/
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);
const std::string& postfix,
const bool& feedthrough_memory) {
std::string mid_name = feedthrough_memory ? "virtual_" : "";
std::string instance_name(mid_name + prefix);
instance_name += std::string(pb_graph_pin->parent_node->pb_type->name);
if (IN_PORT == pb_graph_pin->port->type) {

View File

@ -68,7 +68,8 @@ std::string generate_segment_wire_mid_output_name(
std::string generate_memory_module_name(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
const CircuitModelId& sram_model,
const std::string& postfix);
const std::string& postfix,
const bool& feedthrough_memory = false);
std::string generate_routing_block_netlist_name(const std::string& prefix,
const size_t& block_id,
@ -118,33 +119,34 @@ std::string generate_tile_module_port_name(const std::string& prefix,
std::string generate_tile_module_netlist_name(const std::string& block_name,
const std::string& postfix);
std::string generate_physical_memory_module_name(const std::string& prefix,
const size_t& mem_size);
std::string generate_sb_mux_instance_name(const std::string& prefix,
const e_side& sb_side,
const size_t& track_id,
const std::string& postfix);
std::string generate_sb_memory_instance_name(const std::string& prefix,
const e_side& sb_side,
const size_t& track_id,
const std::string& postfix);
std::string generate_sb_memory_instance_name(
const std::string& prefix, const e_side& sb_side, const size_t& track_id,
const std::string& postfix, const bool& feedthrough_memory = false);
std::string generate_cb_mux_instance_name(const std::string& prefix,
const e_side& cb_side,
const size_t& pin_id,
const std::string& postfix);
std::string generate_cb_memory_instance_name(const std::string& prefix,
const e_side& cb_side,
const size_t& pin_id,
const std::string& postfix);
std::string generate_cb_memory_instance_name(
const std::string& prefix, const e_side& cb_side, const size_t& pin_id,
const std::string& postfix, const bool& feedthrough_memory = false);
std::string generate_pb_mux_instance_name(const std::string& prefix,
t_pb_graph_pin* pb_graph_pin,
const std::string& postfix);
std::string generate_pb_memory_instance_name(const std::string& prefix,
t_pb_graph_pin* pb_graph_pin,
const std::string& postfix);
std::string generate_pb_memory_instance_name(
const std::string& prefix, t_pb_graph_pin* pb_graph_pin,
const std::string& postfix, const bool& feedthrough_memory = false);
std::string generate_grid_port_name(const size_t& width, const size_t& height,
const int& subtile_index,

View File

@ -412,6 +412,13 @@ ShellCommandId add_build_fabric_command_template(
"reduce the number of blocks at top-level");
shell_cmd.set_option_require_value(opt_group_tile, openfpga::OPT_STRING);
/* Add an option '--group_config_block' */
shell_cmd.add_option("group_config_block", false,
"group configuration memory blocks under CLB/SB/CB "
"blocks etc. This helps to "
"reduce optimize the density of configuration memory "
"through physical design");
/* Add an option '--generate_random_fabric_key' */
shell_cmd.add_option("generate_random_fabric_key", false,
"Create a random fabric key which will shuffle the "

View File

@ -37,8 +37,8 @@ int build_device_module_graph(
const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx,
const bool& frame_view, const bool& compress_routing,
const bool& duplicate_grid_pin, const FabricKey& fabric_key,
const TileConfig& tile_config, const bool& generate_random_fabric_key,
const bool& verbose) {
const TileConfig& tile_config, const bool& group_config_block,
const bool& generate_random_fabric_key, const bool& verbose) {
vtr::ScopedStartFinishTimer timer("Build fabric module graph");
int status = CMD_EXEC_SUCCESS;
@ -78,28 +78,34 @@ int build_device_module_graph(
/* Build memory modules */
build_memory_modules(module_manager, decoder_lib, openfpga_ctx.mux_lib(),
openfpga_ctx.arch().circuit_lib,
openfpga_ctx.arch().config_protocol.type());
openfpga_ctx.arch().config_protocol.type(),
group_config_block, verbose);
/* Build grid and programmable block modules */
build_grid_modules(module_manager, decoder_lib, vpr_device_ctx,
openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.arch().circuit_lib, openfpga_ctx.mux_lib(),
openfpga_ctx.arch().config_protocol.type(), sram_model,
duplicate_grid_pin, verbose);
status = build_grid_modules(
module_manager, decoder_lib, vpr_device_ctx,
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.arch().circuit_lib,
openfpga_ctx.mux_lib(), openfpga_ctx.arch().config_protocol.type(),
sram_model, duplicate_grid_pin, group_config_block, verbose);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
if (true == compress_routing) {
build_unique_routing_modules(
module_manager, decoder_lib, vpr_device_ctx,
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.device_rr_gsb(),
openfpga_ctx.arch().circuit_lib,
openfpga_ctx.arch().config_protocol.type(), sram_model, verbose);
build_unique_routing_modules(module_manager, decoder_lib, vpr_device_ctx,
openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.device_rr_gsb(),
openfpga_ctx.arch().circuit_lib,
openfpga_ctx.arch().config_protocol.type(),
sram_model, group_config_block, verbose);
} else {
VTR_ASSERT_SAFE(false == compress_routing);
build_flatten_routing_modules(
module_manager, decoder_lib, vpr_device_ctx,
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.device_rr_gsb(),
openfpga_ctx.arch().circuit_lib,
openfpga_ctx.arch().config_protocol.type(), sram_model, verbose);
build_flatten_routing_modules(module_manager, decoder_lib, vpr_device_ctx,
openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.device_rr_gsb(),
openfpga_ctx.arch().circuit_lib,
openfpga_ctx.arch().config_protocol.type(),
sram_model, group_config_block, verbose);
}
/* Build tile modules if defined */
@ -128,7 +134,7 @@ int build_device_module_graph(
openfpga_ctx.device_rr_gsb(), openfpga_ctx.tile_direct(),
openfpga_ctx.arch().arch_direct, openfpga_ctx.arch().config_protocol,
sram_model, fabric_tile, frame_view, compress_routing, duplicate_grid_pin,
fabric_key, generate_random_fabric_key, verbose);
fabric_key, generate_random_fabric_key, group_config_block, verbose);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;

View File

@ -24,8 +24,8 @@ int build_device_module_graph(
const OpenfpgaContext& openfpga_ctx, const DeviceContext& vpr_device_ctx,
const bool& frame_view, const bool& compress_routing,
const bool& duplicate_grid_pin, const FabricKey& fabric_key,
const TileConfig& tile_config, const bool& generate_random_fabric_key,
const bool& verbose);
const TileConfig& tile_config, const bool& group_config_block,
const bool& generate_random_fabric_key, const bool& verbose);
} /* end namespace openfpga */

View File

@ -381,7 +381,8 @@ int add_fpga_core_to_device_module_graph(ModuleManager& module_manager,
/* Now fpga_core should be the only configurable child under the top-level
* module */
module_manager.add_configurable_child(new_top_module, top_module, 0);
module_manager.add_configurable_child(
new_top_module, top_module, 0, ModuleManager::e_config_child_type::UNIFIED);
return status;
}

View File

@ -6,6 +6,7 @@
#include <vector>
/* Headers from vtrutil library */
#include "command_exit_codes.h"
#include "vtr_assert.h"
#include "vtr_geometry.h"
#include "vtr_log.h"
@ -15,6 +16,7 @@
#include "build_grid_module_duplicated_pins.h"
#include "build_grid_module_utils.h"
#include "build_grid_modules.h"
#include "build_memory_modules.h"
#include "circuit_library_utils.h"
#include "module_manager_utils.h"
#include "openfpga_interconnect_types.h"
@ -265,7 +267,7 @@ static void build_primitive_block_module(
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, t_pb_graph_node* primitive_pb_graph_node,
const bool& verbose) {
const bool& group_config_block, const bool& verbose) {
/* Ensure a valid pb_graph_node */
VTR_ASSERT(nullptr != primitive_pb_graph_node);
@ -277,7 +279,8 @@ static void build_primitive_block_module(
std::string primitive_module_name =
generate_physical_block_module_name(primitive_pb_graph_node->pb_type);
VTR_LOGV(verbose, "Building module '%s'...", primitive_module_name.c_str());
VTR_LOGV(verbose, "Building primitive module '%s'...\n",
primitive_module_name.c_str());
/* Create a module of the primitive LUT and register it to module manager */
ModuleId primitive_module = module_manager.add_module(primitive_module_name);
@ -310,11 +313,13 @@ static void build_primitive_block_module(
}
/* Regular (independent) SRAM ports */
e_config_protocol_type mem_module_type =
group_config_block ? CONFIG_MEM_FEEDTHROUGH : sram_orgz_type;
size_t num_config_bits =
find_circuit_num_config_bits(sram_orgz_type, circuit_lib, primitive_model);
find_circuit_num_config_bits(mem_module_type, circuit_lib, primitive_model);
if (0 < num_config_bits) {
add_sram_ports_to_module_manager(module_manager, primitive_module,
circuit_lib, sram_model, sram_orgz_type,
circuit_lib, sram_model, mem_module_type,
num_config_bits);
}
@ -333,9 +338,9 @@ static void build_primitive_block_module(
circuit_lib, primitive_pb_graph_node->pb_type, device_annotation);
/* Add the associated memory module as a child of primitive module */
std::string memory_module_name =
generate_memory_module_name(circuit_lib, primitive_model, sram_model,
std::string(MEMORY_MODULE_POSTFIX));
std::string memory_module_name = generate_memory_module_name(
circuit_lib, primitive_model, sram_model,
std::string(MEMORY_MODULE_POSTFIX), group_config_block);
ModuleId memory_module = module_manager.find_module(memory_module_name);
/* If there is no memory module required, we can skip the assocated net
@ -355,18 +360,41 @@ static void build_primitive_block_module(
module_manager, primitive_module, logic_module, logic_instance_id,
memory_module, memory_instance_id, circuit_lib, primitive_model);
/* Record memory-related information */
module_manager.add_configurable_child(primitive_module, memory_module,
memory_instance_id);
size_t config_child_id = module_manager.num_configurable_children(
primitive_module, ModuleManager::e_config_child_type::LOGICAL);
module_manager.add_configurable_child(
primitive_module, memory_module, memory_instance_id,
group_config_block ? ModuleManager::e_config_child_type::LOGICAL
: ModuleManager::e_config_child_type::UNIFIED);
/* For logical memory, define the physical memory here */
if (group_config_block) {
std::string physical_memory_module_name =
generate_memory_module_name(circuit_lib, primitive_model, sram_model,
std::string(MEMORY_MODULE_POSTFIX), false);
ModuleId physical_memory_module =
module_manager.find_module(physical_memory_module_name);
VTR_LOGV(verbose,
"Mapping feedthrough memory module '%s' to physical memory "
"module '%s'...\n",
memory_module_name.c_str(), physical_memory_module_name.c_str());
VTR_ASSERT(module_manager.valid_module_id(physical_memory_module));
module_manager.set_logical2physical_configurable_child(
primitive_module, config_child_id, physical_memory_module);
module_manager.set_logical2physical_configurable_child_instance_name(
primitive_module, config_child_id, physical_memory_module_name);
}
}
/* Add all the nets to connect configuration ports from memory module to
* primitive modules This is a one-shot addition that covers all the memory
* modules in this primitive module!
*/
if (0 < module_manager.configurable_children(primitive_module).size()) {
add_module_nets_memory_config_bus(module_manager, decoder_lib,
primitive_module, sram_orgz_type,
circuit_lib.design_tech_type(sram_model));
if (0 < module_manager.num_configurable_children(
primitive_module, ModuleManager::e_config_child_type::LOGICAL)) {
add_module_nets_memory_config_bus(
module_manager, decoder_lib, primitive_module, mem_module_type,
circuit_lib.design_tech_type(sram_model),
ModuleManager::e_config_child_type::LOGICAL);
}
/* Add global ports to the pb_module:
@ -504,7 +532,7 @@ static void add_module_pb_graph_pin_interc(
std::vector<ModuleId>& memory_modules, std::vector<size_t>& memory_instances,
const VprDeviceAnnotation& device_annotation,
const CircuitLibrary& circuit_lib, t_pb_graph_pin* des_pb_graph_pin,
t_mode* physical_mode) {
t_mode* physical_mode, const bool& group_config_block, const bool& verbose) {
/* Find the number of fan-in and detailed interconnection information
* related to the destination pb_graph_pin
*/
@ -628,6 +656,11 @@ static void add_module_pb_graph_pin_interc(
std::string mux_mem_module_name =
generate_mux_subckt_name(circuit_lib, interc_circuit_model, fan_in,
std::string(MEMORY_MODULE_POSTFIX));
if (group_config_block) {
mux_mem_module_name = generate_mux_subckt_name(
circuit_lib, interc_circuit_model, fan_in,
std::string(MEMORY_FEEDTHROUGH_MODULE_POSTFIX));
}
ModuleId mux_mem_module = module_manager.find_module(mux_mem_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mux_mem_module));
size_t mux_mem_instance =
@ -638,12 +671,38 @@ static void add_module_pb_graph_pin_interc(
* generation to modules
*/
std::string mux_mem_instance_name = generate_pb_memory_instance_name(
GRID_MEM_INSTANCE_PREFIX, des_pb_graph_pin, std::string(""));
GRID_MEM_INSTANCE_PREFIX, des_pb_graph_pin, std::string(""),
group_config_block);
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);
size_t config_child_id = module_manager.num_configurable_children(
pb_module, ModuleManager::e_config_child_type::LOGICAL);
module_manager.add_configurable_child(
pb_module, mux_mem_module, mux_mem_instance,
group_config_block ? ModuleManager::e_config_child_type::LOGICAL
: ModuleManager::e_config_child_type::UNIFIED);
if (group_config_block) {
std::string phy_mem_module_name =
generate_mux_subckt_name(circuit_lib, interc_circuit_model, fan_in,
std::string(MEMORY_MODULE_POSTFIX));
ModuleId phy_mem_module =
module_manager.find_module(phy_mem_module_name);
VTR_ASSERT(module_manager.valid_module_id(phy_mem_module));
VTR_LOGV(verbose,
"Mapping feedthrough memory module '%s' to physical memory "
"module '%s'...\n",
mux_mem_module_name.c_str(), phy_mem_module_name.c_str());
module_manager.set_logical2physical_configurable_child(
pb_module, config_child_id, phy_mem_module);
std::string phy_mux_mem_instance_name =
generate_pb_memory_instance_name(
GRID_MEM_INSTANCE_PREFIX, des_pb_graph_pin, std::string(""), false);
module_manager.set_logical2physical_configurable_child_instance_name(
pb_module, config_child_id, phy_mux_mem_instance_name);
VTR_LOGV(verbose, "Now use a feedthrough memory for '%s'\n",
phy_mem_module_name.c_str());
}
/* Add nets to connect SRAM ports of the MUX to the SRAM port of memory
* module */
@ -732,7 +791,8 @@ static void add_module_pb_graph_port_interc(
std::vector<ModuleId>& memory_modules, std::vector<size_t>& memory_instances,
const VprDeviceAnnotation& device_annotation,
const CircuitLibrary& circuit_lib, t_pb_graph_node* des_pb_graph_node,
const e_circuit_pb_port_type& pb_port_type, t_mode* physical_mode) {
const e_circuit_pb_port_type& pb_port_type, t_mode* physical_mode,
const bool& group_config_block, const bool& verbose) {
switch (pb_port_type) {
case CIRCUIT_PB_PORT_INPUT: {
for (int iport = 0; iport < des_pb_graph_node->num_input_ports; ++iport) {
@ -742,7 +802,8 @@ static void add_module_pb_graph_port_interc(
add_module_pb_graph_pin_interc(
module_manager, pb_module, memory_modules, memory_instances,
device_annotation, circuit_lib,
&(des_pb_graph_node->input_pins[iport][ipin]), physical_mode);
&(des_pb_graph_node->input_pins[iport][ipin]), physical_mode,
group_config_block, verbose);
}
}
break;
@ -755,7 +816,8 @@ static void add_module_pb_graph_port_interc(
add_module_pb_graph_pin_interc(
module_manager, pb_module, memory_modules, memory_instances,
device_annotation, circuit_lib,
&(des_pb_graph_node->output_pins[iport][ipin]), physical_mode);
&(des_pb_graph_node->output_pins[iport][ipin]), physical_mode,
group_config_block, verbose);
}
}
break;
@ -767,7 +829,8 @@ static void add_module_pb_graph_port_interc(
add_module_pb_graph_pin_interc(
module_manager, pb_module, memory_modules, memory_instances,
device_annotation, circuit_lib,
&(des_pb_graph_node->clock_pins[iport][ipin]), physical_mode);
&(des_pb_graph_node->clock_pins[iport][ipin]), physical_mode,
group_config_block, verbose);
}
}
break;
@ -814,7 +877,8 @@ static void add_module_pb_graph_interc(
std::vector<ModuleId>& memory_modules, std::vector<size_t>& memory_instances,
const VprDeviceAnnotation& device_annotation,
const CircuitLibrary& circuit_lib, t_pb_graph_node* physical_pb_graph_node,
const int& physical_mode_index) {
const int& physical_mode_index, const bool& group_config_block,
const bool& verbose) {
/* Check cur_pb_graph_node*/
VTR_ASSERT(nullptr != physical_pb_graph_node);
@ -830,10 +894,10 @@ static void add_module_pb_graph_interc(
* |
* input_pins, edges, output_pins
*/
add_module_pb_graph_port_interc(module_manager, pb_module, memory_modules,
memory_instances, device_annotation,
circuit_lib, physical_pb_graph_node,
CIRCUIT_PB_PORT_OUTPUT, physical_mode);
add_module_pb_graph_port_interc(
module_manager, pb_module, memory_modules, memory_instances,
device_annotation, circuit_lib, physical_pb_graph_node,
CIRCUIT_PB_PORT_OUTPUT, physical_mode, group_config_block, verbose);
/* We check input_pins of child_pb_graph_node and its the input_edges
* Built the interconnections between inputs of cur_pb_graph_node and inputs
@ -856,16 +920,16 @@ static void add_module_pb_graph_interc(
&(physical_pb_graph_node
->child_pb_graph_nodes[physical_mode_index][child][inst]);
/* For each child_pb_graph_node input pins*/
add_module_pb_graph_port_interc(module_manager, pb_module, memory_modules,
memory_instances, device_annotation,
circuit_lib, child_pb_graph_node,
CIRCUIT_PB_PORT_INPUT, physical_mode);
add_module_pb_graph_port_interc(
module_manager, pb_module, memory_modules, memory_instances,
device_annotation, circuit_lib, child_pb_graph_node,
CIRCUIT_PB_PORT_INPUT, physical_mode, group_config_block, verbose);
/* For each child_pb_graph_node clock pins*/
add_module_pb_graph_port_interc(module_manager, pb_module, memory_modules,
memory_instances, device_annotation,
circuit_lib, child_pb_graph_node,
CIRCUIT_PB_PORT_CLOCK, physical_mode);
add_module_pb_graph_port_interc(
module_manager, pb_module, memory_modules, memory_instances,
device_annotation, circuit_lib, child_pb_graph_node,
CIRCUIT_PB_PORT_CLOCK, physical_mode, group_config_block, verbose);
}
}
}
@ -892,7 +956,7 @@ static void rec_build_logical_tile_modules(
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, t_pb_graph_node* physical_pb_graph_node,
const bool& verbose) {
const bool& group_config_block, const bool& verbose) {
/* Check cur_pb_graph_node*/
VTR_ASSERT(nullptr != physical_pb_graph_node);
@ -913,7 +977,7 @@ static void rec_build_logical_tile_modules(
sram_orgz_type, sram_model,
&(physical_pb_graph_node
->child_pb_graph_nodes[physical_mode->index][ipb][0]),
verbose);
group_config_block, verbose);
}
}
@ -921,7 +985,8 @@ static void rec_build_logical_tile_modules(
if (true == is_primitive_pb_type(physical_pb_type)) {
build_primitive_block_module(module_manager, decoder_lib, device_annotation,
circuit_lib, sram_orgz_type, sram_model,
physical_pb_graph_node, verbose);
physical_pb_graph_node, group_config_block,
verbose);
/* Finish for primitive node, return */
return;
}
@ -930,7 +995,7 @@ static void rec_build_logical_tile_modules(
std::string pb_module_name =
generate_physical_block_module_name(physical_pb_type);
VTR_LOGV(verbose, "Building module '%s'...", pb_module_name.c_str());
VTR_LOGV(verbose, "Building module '%s'...\n", pb_module_name.c_str());
/* Register the Verilog module in module manager */
ModuleId pb_module = module_manager.add_module(pb_module_name);
@ -949,6 +1014,9 @@ static void rec_build_logical_tile_modules(
std::vector<ModuleId> memory_modules;
std::vector<size_t> memory_instances;
e_config_protocol_type mem_module_type =
group_config_block ? CONFIG_MEM_FEEDTHROUGH : sram_orgz_type;
/* Add all the child Verilog modules as instances */
for (int ichild = 0; ichild < physical_mode->num_pb_type_children; ++ichild) {
/* Get the name and module id for this child pb_type */
@ -986,14 +1054,19 @@ static void rec_build_logical_tile_modules(
module_manager.set_child_instance_name(
pb_module, child_pb_module, child_instance_id, child_pb_instance_name);
VTR_LOGV(verbose, "Building instance '%s'\n",
child_pb_instance_name.c_str());
/* Identify if this sub module includes configuration bits,
* we will update the memory module and instance list
*/
if (0 < find_module_num_config_bits(module_manager, child_pb_module,
circuit_lib, sram_model,
sram_orgz_type)) {
module_manager.add_configurable_child(pb_module, child_pb_module,
child_instance_id);
mem_module_type)) {
module_manager.add_configurable_child(
pb_module, child_pb_module, child_instance_id,
group_config_block ? ModuleManager::e_config_child_type::LOGICAL
: ModuleManager::e_config_child_type::UNIFIED);
}
}
}
@ -1001,9 +1074,11 @@ static void rec_build_logical_tile_modules(
/* Add modules and nets for programmable/non-programmable interconnections
* inside the Verilog module
*/
VTR_LOGV(verbose, "Building local interconnecting modules\n");
add_module_pb_graph_interc(module_manager, pb_module, memory_modules,
memory_instances, device_annotation, circuit_lib,
physical_pb_graph_node, physical_mode->index);
physical_pb_graph_node, physical_mode->index,
group_config_block, verbose);
/* Add global ports to the pb_module:
* This is a much easier job after adding sub modules (instances),
@ -1039,10 +1114,11 @@ static void rec_build_logical_tile_modules(
*/
size_t module_num_config_bits =
find_module_num_config_bits_from_child_modules(
module_manager, pb_module, circuit_lib, sram_model, sram_orgz_type);
module_manager, pb_module, circuit_lib, sram_model, mem_module_type,
ModuleManager::e_config_child_type::LOGICAL);
if (0 < module_num_config_bits) {
add_sram_ports_to_module_manager(module_manager, pb_module, circuit_lib,
sram_model, sram_orgz_type,
sram_model, mem_module_type,
module_num_config_bits);
}
@ -1050,10 +1126,12 @@ static void rec_build_logical_tile_modules(
* This is a one-shot addition that covers all the memory modules in this pb
* module!
*/
if (0 < module_manager.configurable_children(pb_module).size()) {
add_module_nets_memory_config_bus(module_manager, decoder_lib, pb_module,
sram_orgz_type,
circuit_lib.design_tech_type(sram_model));
if (0 < module_manager.num_configurable_children(
pb_module, ModuleManager::e_config_child_type::LOGICAL)) {
add_module_nets_memory_config_bus(
module_manager, decoder_lib, pb_module, mem_module_type,
circuit_lib.design_tech_type(sram_model),
ModuleManager::e_config_child_type::LOGICAL);
}
VTR_LOGV(verbose, "Done\n");
@ -1067,14 +1145,15 @@ static void rec_build_logical_tile_modules(
* The param 'border_side' is required, which is specify which side of fabric
* the I/O block locates at.
*****************************************************************************/
static void build_physical_tile_module(
static int build_physical_tile_module(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const VprDeviceAnnotation& vpr_device_annotation,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, t_physical_tile_type_ptr phy_block_type,
const e_side& border_side, const bool& duplicate_grid_pin,
const bool& verbose) {
const bool& group_config_block, const bool& verbose) {
int status = CMD_EXEC_SUCCESS;
/* Create a Module for the top-level physical block, and add to module manager
*/
std::string grid_module_name = generate_grid_block_module_name(
@ -1124,15 +1203,29 @@ static void build_physical_tile_module(
/* Identify if this sub module includes configuration bits,
* we will update the memory module and instance list
*/
if (0 < find_module_num_config_bits(module_manager, pb_module,
circuit_lib, sram_model,
sram_orgz_type)) {
module_manager.add_configurable_child(grid_module, pb_module,
pb_instance_id);
if (0 < find_module_num_config_bits(
module_manager, pb_module, circuit_lib, sram_model,
group_config_block ? CONFIG_MEM_FEEDTHROUGH : sram_orgz_type)) {
/* Only add logical configurable children here. Since we will add a
* physical memory block at this level */
module_manager.add_configurable_child(
grid_module, pb_module, pb_instance_id,
group_config_block ? ModuleManager::e_config_child_type::LOGICAL
: ModuleManager::e_config_child_type::UNIFIED);
}
}
}
/* TODO: Add a physical memory block */
if (group_config_block) {
status = add_physical_memory_module(module_manager, decoder_lib,
grid_module, circuit_lib,
sram_orgz_type, sram_model, verbose);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
}
/* Add grid ports(pins) to the module */
if (false == duplicate_grid_pin) {
/* Default way to add these ports by following the definition in pb_types */
@ -1218,9 +1311,13 @@ static void build_physical_tile_module(
* we just need to find all the I/O ports from the child modules and build a
* list of it
*/
ModuleManager::e_config_child_type config_child_type =
group_config_block ? ModuleManager::e_config_child_type::PHYSICAL
: ModuleManager::e_config_child_type::LOGICAL;
size_t module_num_config_bits =
find_module_num_config_bits_from_child_modules(
module_manager, grid_module, circuit_lib, sram_model, sram_orgz_type);
module_manager, grid_module, circuit_lib, sram_model, sram_orgz_type,
config_child_type);
if (0 < module_num_config_bits) {
add_pb_sram_ports_to_module_manager(module_manager, grid_module,
circuit_lib, sram_model, sram_orgz_type,
@ -1231,13 +1328,16 @@ static void build_physical_tile_module(
* This is a one-shot addition that covers all the memory modules in this pb
* module!
*/
if (0 < module_manager.configurable_children(grid_module).size()) {
if (0 < module_manager.num_configurable_children(grid_module,
config_child_type)) {
add_pb_module_nets_memory_config_bus(
module_manager, decoder_lib, grid_module, sram_orgz_type,
circuit_lib.design_tech_type(sram_model));
circuit_lib.design_tech_type(sram_model), config_child_type);
}
VTR_LOGV(verbose, "Done\n");
return status;
}
/*****************************************************************************
@ -1253,18 +1353,18 @@ static void build_physical_tile_module(
* - Only one module for each CLB (FILL_TYPE)
* - Only one module for each heterogeneous block
****************************************************************************/
void build_grid_modules(ModuleManager& module_manager,
DecoderLibrary& decoder_lib,
const DeviceContext& device_ctx,
const VprDeviceAnnotation& device_annotation,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model,
const bool& duplicate_grid_pin, const bool& verbose) {
int build_grid_modules(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation,
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const bool& duplicate_grid_pin,
const bool& group_config_block, const bool& verbose) {
/* Start time count */
vtr::ScopedStartFinishTimer timer("Build grid modules");
int status = CMD_EXEC_SUCCESS;
/* Enumerate the types of logical tiles, and build a module for each
* Build modules for all the pb_types/pb_graph_nodes
* use a Depth-First Search Algorithm to print the sub-modules
@ -1284,7 +1384,8 @@ void build_grid_modules(ModuleManager& module_manager,
}
rec_build_logical_tile_modules(
module_manager, decoder_lib, device_annotation, circuit_lib, mux_lib,
sram_orgz_type, sram_model, logical_tile.pb_graph_head, verbose);
sram_orgz_type, sram_model, logical_tile.pb_graph_head,
group_config_block, verbose);
}
VTR_LOG("Done\n");
@ -1311,20 +1412,28 @@ void build_grid_modules(ModuleManager& module_manager,
std::set<e_side> io_type_sides =
find_physical_io_tile_located_sides(device_ctx.grid, &physical_tile);
for (const e_side& io_type_side : io_type_sides) {
build_physical_tile_module(module_manager, decoder_lib,
device_annotation, circuit_lib,
sram_orgz_type, sram_model, &physical_tile,
io_type_side, duplicate_grid_pin, verbose);
status = build_physical_tile_module(
module_manager, decoder_lib, device_annotation, circuit_lib,
sram_orgz_type, sram_model, &physical_tile, io_type_side,
duplicate_grid_pin, group_config_block, verbose);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
}
} else {
/* For CLB and heterogenenous blocks */
build_physical_tile_module(module_manager, decoder_lib, device_annotation,
circuit_lib, sram_orgz_type, sram_model,
&physical_tile, NUM_SIDES, duplicate_grid_pin,
verbose);
status = build_physical_tile_module(
module_manager, decoder_lib, device_annotation, circuit_lib,
sram_orgz_type, sram_model, &physical_tile, NUM_SIDES,
duplicate_grid_pin, group_config_block, verbose);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
}
}
VTR_LOG("Done\n");
return status;
}
} /* end namespace openfpga */

View File

@ -17,15 +17,13 @@
/* begin namespace openfpga */
namespace openfpga {
void build_grid_modules(ModuleManager& module_manager,
DecoderLibrary& decoder_lib,
const DeviceContext& device_ctx,
const VprDeviceAnnotation& device_annotation,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model,
const bool& duplicate_grid_pin, const bool& verbose);
int build_grid_modules(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation,
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const bool& duplicate_grid_pin,
const bool& group_config_block, const bool& verbose);
} /* end namespace openfpga */

View File

@ -3,15 +3,18 @@
* the memories that are affiliated to multiplexers and other programmable
* circuit models, such as IOPADs, LUTs, etc.
********************************************************************/
#include "build_memory_modules.h"
#include <algorithm>
#include <ctime>
#include <map>
#include <string>
/* Headers from vtrutil library */
#include "build_decoder_modules.h"
#include "build_memory_modules.h"
#include "circuit_library_utils.h"
#include "command_exit_codes.h"
#include "decoder_library_utils.h"
#include "memory_utils.h"
#include "module_manager.h"
#include "module_manager_utils.h"
#include "mux_graph.h"
@ -173,7 +176,11 @@ static void add_module_nets_to_cmos_memory_config_chain_module(
const CircuitLibrary& circuit_lib, const CircuitPortId& model_input_port,
const CircuitPortId& model_output_port) {
for (size_t mem_index = 0;
mem_index < module_manager.configurable_children(parent_module).size();
mem_index <
module_manager
.configurable_children(parent_module,
ModuleManager::e_config_child_type::LOGICAL)
.size();
++mem_index) {
ModuleId net_src_module_id;
size_t net_src_instance_id;
@ -193,28 +200,30 @@ static void add_module_nets_to_cmos_memory_config_chain_module(
/* Find the port name of next memory module */
std::string sink_port_name = circuit_lib.port_prefix(model_input_port);
net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_module_id = module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::LOGICAL)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, ModuleManager::e_config_child_type::LOGICAL)[mem_index];
net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
} else {
/* Find the port name of previous memory module */
std::string src_port_name = circuit_lib.port_prefix(model_output_port);
net_src_module_id =
module_manager.configurable_children(parent_module)[mem_index - 1];
net_src_module_id = module_manager.configurable_children(
parent_module,
ModuleManager::e_config_child_type::LOGICAL)[mem_index - 1];
net_src_instance_id = module_manager.configurable_child_instances(
parent_module)[mem_index - 1];
parent_module,
ModuleManager::e_config_child_type::LOGICAL)[mem_index - 1];
net_src_port_id =
module_manager.find_module_port(net_src_module_id, src_port_name);
/* Find the port name of next memory module */
std::string sink_port_name = circuit_lib.port_prefix(model_input_port);
net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_module_id = module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::LOGICAL)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, ModuleManager::e_config_child_type::LOGICAL)[mem_index];
net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
}
@ -248,9 +257,15 @@ static void add_module_nets_to_cmos_memory_config_chain_module(
/* Find the port name of previous memory module */
std::string src_port_name = circuit_lib.port_prefix(model_output_port);
ModuleId net_src_module_id =
module_manager.configurable_children(parent_module).back();
module_manager
.configurable_children(parent_module,
ModuleManager::e_config_child_type::LOGICAL)
.back();
size_t net_src_instance_id =
module_manager.configurable_child_instances(parent_module).back();
module_manager
.configurable_child_instances(parent_module,
ModuleManager::e_config_child_type::LOGICAL)
.back();
ModulePortId net_src_port_id =
module_manager.find_module_port(net_src_module_id, src_port_name);
@ -310,7 +325,11 @@ static void add_module_nets_to_cmos_memory_scan_chain_module(
const CircuitLibrary& circuit_lib, const CircuitPortId& model_input_port,
const CircuitPortId& model_output_port) {
for (size_t mem_index = 0;
mem_index < module_manager.configurable_children(parent_module).size();
mem_index <
module_manager
.configurable_children(parent_module,
ModuleManager::e_config_child_type::LOGICAL)
.size();
++mem_index) {
ModuleId net_src_module_id;
size_t net_src_instance_id;
@ -330,28 +349,30 @@ static void add_module_nets_to_cmos_memory_scan_chain_module(
/* Find the port name of next memory module */
std::string sink_port_name = circuit_lib.port_prefix(model_input_port);
net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_module_id = module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::LOGICAL)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, ModuleManager::e_config_child_type::LOGICAL)[mem_index];
net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
} else {
/* Find the port name of previous memory module */
std::string src_port_name = circuit_lib.port_prefix(model_output_port);
net_src_module_id =
module_manager.configurable_children(parent_module)[mem_index - 1];
net_src_module_id = module_manager.configurable_children(
parent_module,
ModuleManager::e_config_child_type::LOGICAL)[mem_index - 1];
net_src_instance_id = module_manager.configurable_child_instances(
parent_module)[mem_index - 1];
parent_module,
ModuleManager::e_config_child_type::LOGICAL)[mem_index - 1];
net_src_port_id =
module_manager.find_module_port(net_src_module_id, src_port_name);
/* Find the port name of next memory module */
std::string sink_port_name = circuit_lib.port_prefix(model_input_port);
net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_module_id = module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::LOGICAL)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, ModuleManager::e_config_child_type::LOGICAL)[mem_index];
net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
}
@ -404,7 +425,8 @@ static void build_memory_flatten_module(ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const std::string& module_name,
const CircuitModelId& sram_model,
const size_t& num_mems) {
const size_t& num_mems,
const bool& verbose) {
/* Get the global ports required by the SRAM */
std::vector<enum e_circuit_model_port_type> global_port_types;
global_port_types.push_back(CIRCUIT_MODEL_PORT_CLOCK);
@ -433,6 +455,7 @@ static void build_memory_flatten_module(ModuleManager& module_manager,
VTR_ASSERT(2 == sram_output_ports.size());
/* Create a module and add to the module manager */
VTR_LOGV(verbose, "Building memory module '%s'\n", module_name.c_str());
ModuleId mem_module = module_manager.add_module(module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mem_module));
@ -479,8 +502,9 @@ static void build_memory_flatten_module(ModuleManager& module_manager,
size_t sram_mem_instance =
module_manager.num_instance(mem_module, sram_mem_module);
module_manager.add_child_module(mem_module, sram_mem_module);
module_manager.add_configurable_child(mem_module, sram_mem_module,
sram_mem_instance);
module_manager.add_configurable_child(
mem_module, sram_mem_module, sram_mem_instance,
ModuleManager::e_config_child_type::UNIFIED);
/* Build module nets */
/* Wire inputs of parent module to inputs of child modules */
@ -530,7 +554,8 @@ static void build_memory_chain_module(ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const std::string& module_name,
const CircuitModelId& sram_model,
const size_t& num_mems) {
const size_t& num_mems,
const bool& verbose) {
/* Get the input ports from the SRAM */
std::vector<CircuitPortId> sram_input_ports =
circuit_lib.model_ports_by_type(sram_model, CIRCUIT_MODEL_PORT_INPUT, true);
@ -546,6 +571,7 @@ static void build_memory_chain_module(ModuleManager& module_manager,
(3 == sram_output_ports.size()));
/* Create a module and add to the module manager */
VTR_LOGV(verbose, "Building memory module '%s'\n", module_name.c_str());
ModuleId mem_module = module_manager.add_module(module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mem_module));
@ -612,8 +638,9 @@ static void build_memory_chain_module(ModuleManager& module_manager,
size_t sram_mem_instance =
module_manager.num_instance(mem_module, sram_mem_module);
module_manager.add_child_module(mem_module, sram_mem_module);
module_manager.add_configurable_child(mem_module, sram_mem_module,
sram_mem_instance);
module_manager.add_configurable_child(
mem_module, sram_mem_module, sram_mem_instance,
ModuleManager::e_config_child_type::UNIFIED);
/* Build module nets to wire outputs of sram modules to outputs of memory
* module */
@ -689,7 +716,8 @@ static void build_frame_memory_module(ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const std::string& module_name,
const CircuitModelId& sram_model,
const size_t& num_mems) {
const size_t& num_mems,
const bool& verbose) {
/* Get the global ports required by the SRAM */
std::vector<enum e_circuit_model_port_type> global_port_types;
global_port_types.push_back(CIRCUIT_MODEL_PORT_CLOCK);
@ -732,6 +760,7 @@ static void build_frame_memory_module(ModuleManager& module_manager,
VTR_ASSERT(0 == sram_blb_ports.size());
/* Create a module and add to the module manager */
VTR_LOGV(verbose, "Building memory module '%s'\n", module_name.c_str());
ModuleId mem_module = module_manager.add_module(module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mem_module));
@ -829,8 +858,9 @@ static void build_frame_memory_module(ModuleManager& module_manager,
size_t sram_instance =
module_manager.num_instance(mem_module, sram_mem_module);
module_manager.add_child_module(mem_module, sram_mem_module);
module_manager.add_configurable_child(mem_module, sram_mem_module,
sram_instance);
module_manager.add_configurable_child(
mem_module, sram_mem_module, sram_instance,
ModuleManager::e_config_child_type::UNIFIED);
/* Wire data_in port to SRAM BL port */
ModulePortId sram_bl_port = module_manager.find_module_port(
@ -890,7 +920,8 @@ static void build_frame_memory_module(ModuleManager& module_manager,
add_module_global_ports_from_child_modules(module_manager, mem_module);
/* Add the decoder as the last configurable children */
module_manager.add_configurable_child(mem_module, decoder_module, 0);
module_manager.add_configurable_child(
mem_module, decoder_module, 0, ModuleManager::e_config_child_type::UNIFIED);
}
/*********************************************************************
@ -909,21 +940,21 @@ static void build_memory_module(ModuleManager& module_manager,
const e_config_protocol_type& sram_orgz_type,
const std::string& module_name,
const CircuitModelId& sram_model,
const size_t& num_mems) {
const size_t& num_mems, const bool& verbose) {
switch (sram_orgz_type) {
case CONFIG_MEM_STANDALONE:
case CONFIG_MEM_QL_MEMORY_BANK:
case CONFIG_MEM_MEMORY_BANK:
build_memory_flatten_module(module_manager, circuit_lib, module_name,
sram_model, num_mems);
sram_model, num_mems, verbose);
break;
case CONFIG_MEM_SCAN_CHAIN:
build_memory_chain_module(module_manager, circuit_lib, module_name,
sram_model, num_mems);
sram_model, num_mems, verbose);
break;
case CONFIG_MEM_FRAME_BASED:
build_frame_memory_module(module_manager, arch_decoder_lib, circuit_lib,
module_name, sram_model, num_mems);
module_name, sram_model, num_mems, verbose);
break;
default:
VTR_LOGF_ERROR(__FILE__, __LINE__,
@ -932,6 +963,84 @@ static void build_memory_module(ModuleManager& module_manager,
}
}
/*********************************************************************
* Generate Verilog modules for the feedthrough memories that are used
* by a circuit model
* mem_out mem_outb
* | |
* v v
* +------------------------------------+
* | |
* | |
* | |
* +------------------------------------+
* | |
* | mem_in | mem_inb
* v v
* +------------------------------------+
* | Multiplexer Configuration port |
*
********************************************************************/
static int build_feedthrough_memory_module(ModuleManager& module_manager,
const std::string& module_name,
const size_t& num_mems,
const bool& verbose) {
/* Create a module and add to the module manager */
VTR_LOGV(verbose, "Building feedthrough memory module '%s'\n",
module_name.c_str());
ModuleId mem_module = module_manager.add_module(module_name);
if (!module_manager.valid_module_id(mem_module)) {
return CMD_EXEC_FATAL_ERROR;
}
/* Label module usage */
module_manager.set_module_usage(mem_module, ModuleManager::MODULE_CONFIG);
/* Add module ports */
/* Input: memory inputs */
BasicPort in_port(std::string(MEMORY_FEEDTHROUGH_DATA_IN_PORT_NAME),
num_mems);
ModulePortId mem_in_port = module_manager.add_port(
mem_module, in_port, ModuleManager::MODULE_INPUT_PORT);
BasicPort inb_port(std::string(MEMORY_FEEDTHROUGH_DATA_IN_INV_PORT_NAME),
num_mems);
ModulePortId mem_inb_port = module_manager.add_port(
mem_module, inb_port, ModuleManager::MODULE_INPUT_PORT);
/* Add each output port */
BasicPort out_port(std::string(CONFIGURABLE_MEMORY_DATA_OUT_NAME), num_mems);
ModulePortId mem_out_port = module_manager.add_port(
mem_module, out_port, ModuleManager::MODULE_OUTPUT_PORT);
BasicPort outb_port(std::string(CONFIGURABLE_MEMORY_INVERTED_DATA_OUT_NAME),
num_mems);
ModulePortId mem_outb_port = module_manager.add_port(
mem_module, outb_port, ModuleManager::MODULE_OUTPUT_PORT);
/* Build feedthrough nets */
for (size_t pin_id = 0; pin_id < in_port.pins().size(); ++pin_id) {
ModuleNetId net = module_manager.create_module_net(mem_module);
if (!module_manager.valid_module_net_id(mem_module, net)) {
return CMD_EXEC_FATAL_ERROR;
}
module_manager.add_module_net_source(mem_module, net, mem_module, 0,
mem_in_port, in_port.pins()[pin_id]);
module_manager.add_module_net_sink(mem_module, net, mem_module, 0,
mem_out_port, out_port.pins()[pin_id]);
}
for (size_t pin_id = 0; pin_id < inb_port.pins().size(); ++pin_id) {
ModuleNetId net = module_manager.create_module_net(mem_module);
if (!module_manager.valid_module_net_id(mem_module, net)) {
return CMD_EXEC_FATAL_ERROR;
}
module_manager.add_module_net_source(mem_module, net, mem_module, 0,
mem_inb_port, inb_port.pins()[pin_id]);
module_manager.add_module_net_sink(mem_module, net, mem_module, 0,
mem_outb_port, outb_port.pins()[pin_id]);
}
return CMD_EXEC_SUCCESS;
}
/*********************************************************************
* Generate Verilog modules for the memories that are used
* by multiplexers
@ -949,7 +1058,7 @@ static void build_mux_memory_module(
ModuleManager& module_manager, DecoderLibrary& arch_decoder_lib,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type, const CircuitModelId& mux_model,
const MuxGraph& mux_graph) {
const MuxGraph& mux_graph, const bool& verbose) {
/* Find the actual number of configuration bits, based on the mux graph
* Due to the use of local decoders inside mux, this may be
*/
@ -973,7 +1082,7 @@ static void build_mux_memory_module(
build_memory_module(module_manager, arch_decoder_lib, circuit_lib,
sram_orgz_type, module_name, sram_models[0],
num_config_bits);
num_config_bits, verbose);
break;
}
case CIRCUIT_MODEL_DESIGN_RRAM:
@ -990,6 +1099,61 @@ static void build_mux_memory_module(
}
}
/*********************************************************************
* Generate Verilog modules for the feedthrough memories that are used
* by multiplexers
* SRAM ports as feedthrough (driven by physical memory blocks)
* | | | |
* v v ... v v
* +----------------+
* | Memory Module |
* +----------------+
* | | ... | |
* v v v v SRAM ports of multiplexer
* +---------------------+
* in--->| Multiplexer Module |---> out
* +---------------------+
********************************************************************/
static int build_mux_feedthrough_memory_module(
ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type, const CircuitModelId& mux_model,
const MuxGraph& mux_graph, const bool& verbose) {
int status = CMD_EXEC_SUCCESS;
/* Find the actual number of configuration bits, based on the mux graph
* Due to the use of local decoders inside mux, this may be
*/
size_t num_config_bits =
find_mux_num_config_bits(circuit_lib, mux_model, mux_graph, sram_orgz_type);
/* Multiplexers built with different technology is in different organization
*/
switch (circuit_lib.design_tech_type(mux_model)) {
case CIRCUIT_MODEL_DESIGN_CMOS: {
/* Generate module name */
std::string module_name = generate_mux_subckt_name(
circuit_lib, mux_model,
find_mux_num_datapath_inputs(circuit_lib, mux_model,
mux_graph.num_inputs()),
std::string(MEMORY_FEEDTHROUGH_MODULE_POSTFIX));
status = build_feedthrough_memory_module(module_manager, module_name,
num_config_bits, verbose);
break;
}
case CIRCUIT_MODEL_DESIGN_RRAM:
/* We do not need a memory submodule for RRAM MUX,
* RRAM are embedded in the datapath
* TODO: generate local encoders for RRAM-based multiplexers here!!!
*/
break;
default:
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Invalid design technology of multiplexer '%s'\n",
circuit_lib.model_name(mux_model).c_str());
exit(1);
}
return status;
}
/*********************************************************************
* Build modules for
* the memories that are affiliated to multiplexers and other programmable
@ -1005,12 +1169,17 @@ static void build_mux_memory_module(
* memory modules.
* Take another example, the memory circuit can implement the scan-chain or
* memory-bank organization for the memories.
* If we need feedthrough memory blocks, build the memory modules which contain
*only feedthrough wires
********************************************************************/
void build_memory_modules(ModuleManager& module_manager,
DecoderLibrary& arch_decoder_lib,
const MuxLibrary& mux_lib,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type) {
int build_memory_modules(ModuleManager& module_manager,
DecoderLibrary& arch_decoder_lib,
const MuxLibrary& mux_lib,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const bool& require_feedthrough_memory,
const bool& verbose) {
int status = CMD_EXEC_SUCCESS;
vtr::ScopedStartFinishTimer timer("Build memory modules");
/* Create the memory circuits for the multiplexer */
@ -1026,7 +1195,16 @@ void build_memory_modules(ModuleManager& module_manager,
}
/* Create a Verilog module for the memories used by the multiplexer */
build_mux_memory_module(module_manager, arch_decoder_lib, circuit_lib,
sram_orgz_type, mux_model, mux_graph);
sram_orgz_type, mux_model, mux_graph, verbose);
/* Create feedthrough memory module */
if (require_feedthrough_memory) {
status = build_mux_feedthrough_memory_module(module_manager, circuit_lib,
sram_orgz_type, mux_model,
mux_graph, verbose);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
}
}
/* Create the memory circuits for non-MUX circuit models.
@ -1062,8 +1240,381 @@ void build_memory_modules(ModuleManager& module_manager,
/* Create a Verilog module for the memories used by the circuit model */
build_memory_module(module_manager, arch_decoder_lib, circuit_lib,
sram_orgz_type, module_name, sram_models[0], num_mems);
sram_orgz_type, module_name, sram_models[0], num_mems,
verbose);
/* Create feedthrough memory module */
if (require_feedthrough_memory) {
module_name =
generate_memory_module_name(circuit_lib, model, sram_models[0],
std::string(MEMORY_MODULE_POSTFIX), true);
status = build_feedthrough_memory_module(module_manager, module_name,
num_mems, verbose);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
}
}
return status;
}
/*********************************************************************
* Add module nets to connect an output port of a configuration-chain
* memory module to an output port of its child module
* Restriction: this function is really designed for memory modules
* 1. It assumes that output port name of child module is the same as memory
*module
* 2. It assumes exact pin-to-pin mapping:
* j-th pin of output port of the i-th child module is wired to the j + i*W
*-th pin of output port of the memory module, where W is the size of port
* 3. It assumes fixed port name for output ports
********************************************************************/
static void add_module_output_nets_to_memory_group_module(
ModuleManager& module_manager, const ModuleId& mem_module,
const std::string& mem_module_output_name, const ModuleId& child_module,
const size_t& output_pin_start_index, const size_t& child_instance) {
/* Wire inputs of parent module to inputs of child modules */
ModulePortId src_port_id =
module_manager.find_module_port(child_module, mem_module_output_name);
ModulePortId sink_port_id =
module_manager.find_module_port(mem_module, mem_module_output_name);
for (size_t pin_id = 0;
pin_id <
module_manager.module_port(child_module, src_port_id).pins().size();
++pin_id) {
ModuleNetId net = module_manager.create_module_net(mem_module);
/* Source pin is shifted by the number of memories */
size_t src_pin_id =
module_manager.module_port(child_module, src_port_id).pins()[pin_id];
/* Source node of the input net is the input of memory module */
module_manager.add_module_net_source(
mem_module, net, child_module, child_instance, src_port_id, src_pin_id);
/* Sink node of the input net is the input of sram module */
size_t sink_pin_id =
output_pin_start_index +
module_manager.module_port(mem_module, sink_port_id).pins()[pin_id];
module_manager.add_module_net_sink(mem_module, net, mem_module, 0,
sink_port_id, sink_pin_id);
}
}
/*********************************************************************
* Build a grouped memory module based on existing memory modules
* - Create the module
* - Add dedicated instance
* - Add ports
* - Add nets
********************************************************************/
int build_memory_group_module(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type, const std::string& module_name,
const CircuitModelId& sram_model, const std::vector<ModuleId>& child_modules,
const std::vector<std::string>& child_instance_names, const size_t& num_mems,
const bool& verbose) {
VTR_LOGV(verbose, "Building memory group module '%s'...\n",
module_name.c_str());
ModuleId mem_module = module_manager.add_module(module_name);
if (!module_manager.valid_module_id(mem_module)) {
return CMD_EXEC_FATAL_ERROR;
}
/* Label module usage */
module_manager.set_module_usage(mem_module,
ModuleManager::MODULE_CONFIG_GROUP);
/* Add output ports */
std::string out_port_name = generate_configurable_memory_data_out_name();
BasicPort out_port(out_port_name, num_mems);
module_manager.add_port(mem_module, out_port,
ModuleManager::MODULE_OUTPUT_PORT);
std::string outb_port_name =
generate_configurable_memory_inverted_data_out_name();
BasicPort outb_port(outb_port_name, num_mems);
module_manager.add_port(mem_module, outb_port,
ModuleManager::MODULE_OUTPUT_PORT);
/* Identify the duplicated instance name: This mainly comes from the grid
* modules, which contains multi-instanced blocks. Therefore, we just count
* the duplicated instance names and name each of them with a unique index,
* e.g., mem_lut -> mem_lut_0, mem_lut_1 etc. The only exception is for the
* uinque instance name, we keep the original instance name */
std::vector<std::string> unique_child_instance_names;
unique_child_instance_names.reserve(child_instance_names.size());
std::map<std::string, size_t> unique_child_instance_name_count;
for (std::string curr_inst_name : child_instance_names) {
auto result = unique_child_instance_name_count.find(curr_inst_name);
if (result == unique_child_instance_name_count.end()) {
unique_child_instance_name_count[curr_inst_name] = 1;
} else {
unique_child_instance_name_count[curr_inst_name]++;
}
}
std::map<std::string, size_t> unique_child_instance_name_scoreboard;
for (std::string curr_inst_name : child_instance_names) {
if (1 == unique_child_instance_name_count[curr_inst_name]) {
unique_child_instance_names.push_back(curr_inst_name);
unique_child_instance_name_scoreboard[curr_inst_name] = 1;
continue;
}
auto result = unique_child_instance_name_scoreboard.find(curr_inst_name);
if (result == unique_child_instance_name_scoreboard.end()) {
unique_child_instance_name_scoreboard[curr_inst_name] = 0;
unique_child_instance_names.push_back(curr_inst_name);
} else {
unique_child_instance_name_scoreboard[curr_inst_name]++;
unique_child_instance_names.push_back(generate_instance_name(
curr_inst_name, unique_child_instance_name_scoreboard[curr_inst_name]));
}
}
VTR_ASSERT(unique_child_instance_names.size() == child_instance_names.size());
/* Add nets between child module outputs and memory modules */
size_t mem_out_pin_start_index = 0;
size_t mem_outb_pin_start_index = 0;
for (size_t ichild = 0; ichild < child_modules.size(); ++ichild) {
ModuleId child_module = child_modules[ichild];
size_t child_instance =
module_manager.num_instance(mem_module, child_module);
module_manager.add_child_module(mem_module, child_module, false);
module_manager.set_child_instance_name(mem_module, child_module,
child_instance,
unique_child_instance_names[ichild]);
module_manager.add_configurable_child(
mem_module, child_module, child_instance,
ModuleManager::e_config_child_type::UNIFIED);
/* Wire outputs of child module to outputs of parent module */
ModulePortId child_out_port_id =
module_manager.find_module_port(child_module, out_port_name);
if (module_manager.valid_module_port_id(child_module, child_out_port_id)) {
add_module_output_nets_to_memory_group_module(
module_manager, mem_module, out_port_name, child_module,
mem_out_pin_start_index, child_instance);
/* Update pin counter */
mem_out_pin_start_index +=
module_manager.module_port(child_module, child_out_port_id).get_width();
}
ModulePortId child_outb_port_id =
module_manager.find_module_port(child_module, outb_port_name);
if (module_manager.valid_module_port_id(child_module, child_outb_port_id)) {
add_module_output_nets_to_memory_group_module(
module_manager, mem_module, outb_port_name, child_module,
mem_outb_pin_start_index, child_instance);
/* Update pin counter */
mem_outb_pin_start_index +=
module_manager.module_port(child_module, child_outb_port_id)
.get_width();
}
}
/* Add global ports to the pb_module:
* This is a much easier job after adding sub modules (instances),
* we just need to find all the global ports from the child modules and build
* a list of it
*/
add_module_global_ports_from_child_modules(module_manager, mem_module);
/* Count GPIO ports from the sub-modules under this Verilog module
* This is a much easier job after adding sub modules (instances),
* we just need to find all the I/O ports from the child modules and build a
* list of it
*/
add_module_gpio_ports_from_child_modules(module_manager, mem_module);
/* Count shared SRAM ports from the sub-modules under this Verilog module
* This is a much easier job after adding sub modules (instances),
* we just need to find all the I/O ports from the child modules and build a
* list of it
*/
size_t module_num_shared_config_bits =
find_module_num_shared_config_bits_from_child_modules(module_manager,
mem_module);
if (0 < module_num_shared_config_bits) {
add_reserved_sram_ports_to_module_manager(module_manager, mem_module,
module_num_shared_config_bits);
}
/* Count SRAM ports from the sub-modules under this Verilog module
* This is a much easier job after adding sub modules (instances),
* we just need to find all the I/O ports from the child modules and build a
* list of it
*/
ModuleManager::e_config_child_type config_child_type =
ModuleManager::e_config_child_type::PHYSICAL;
size_t module_num_config_bits =
find_module_num_config_bits_from_child_modules(
module_manager, mem_module, circuit_lib, sram_model, sram_orgz_type,
config_child_type);
if (0 < module_num_config_bits) {
add_sram_ports_to_module_manager(module_manager, mem_module, circuit_lib,
sram_model, sram_orgz_type,
module_num_config_bits);
}
/* Add module nets to connect memory cells inside
* This is a one-shot addition that covers all the memory modules in this pb
* module!
*/
if (0 <
module_manager.num_configurable_children(mem_module, config_child_type)) {
add_module_nets_memory_config_bus(
module_manager, decoder_lib, mem_module, sram_orgz_type,
circuit_lib.design_tech_type(sram_model), config_child_type);
}
return CMD_EXEC_SUCCESS;
}
/*****************************************************************************
* This function creates a physical memory module and add it the current module
* The following tasks will be accomplished:
* - Traverse all the logical configurable children in the module tree, starting
*from the current module
* - Build a list of the leaf logical configurable children and count the total
*memory sizes, the memory size for each physical memory submodule. Note that
*the physical memory submodule should be cached already in each leaf logical
*configurable children
* - Get the physical memory module required by each leaf logical configurable
*child
* - Create a dedicated module name for the physical memory (check if already
*exists, if yes, skip creating a new module)
* - Instanciate the module
* - Built nets. Note that only the output ports of the physical memory block is
*required, since they should drive the dedicated memory ports of logical
*configurable children
*****************************************************************************/
int add_physical_memory_module(ModuleManager& module_manager,
DecoderLibrary& decoder_lib,
const ModuleId& curr_module,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model,
const bool& verbose) {
int status = CMD_EXEC_SUCCESS;
std::vector<ModuleId> required_phy_mem_modules;
std::vector<std::string> required_phy_mem_instance_names;
status = rec_find_physical_memory_children(
static_cast<const ModuleManager&>(module_manager), curr_module,
required_phy_mem_modules, required_phy_mem_instance_names, verbose);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
size_t module_num_config_bits =
find_module_num_config_bits_from_child_modules(
module_manager, curr_module, circuit_lib, sram_model,
CONFIG_MEM_FEEDTHROUGH, ModuleManager::e_config_child_type::LOGICAL);
/* No need to build a memory when there are no configuration bits required */
if (module_num_config_bits == 0) {
return CMD_EXEC_SUCCESS;
}
std::string phy_mem_module_name = generate_physical_memory_module_name(
module_manager.module_name(curr_module), module_num_config_bits);
VTR_LOGV(verbose, "Adding memory group module '%s' as a child to '%s'...\n",
phy_mem_module_name.c_str(),
module_manager.module_name(curr_module).c_str());
ModuleId phy_mem_module = module_manager.find_module(phy_mem_module_name);
if (!module_manager.valid_module_id(phy_mem_module)) {
status = build_memory_group_module(
module_manager, decoder_lib, circuit_lib, sram_orgz_type,
phy_mem_module_name, sram_model, required_phy_mem_modules,
required_phy_mem_instance_names, module_num_config_bits, verbose);
}
if (status != CMD_EXEC_SUCCESS) {
VTR_LOG_ERROR("Failed to create the physical memory module '%s'!\n",
phy_mem_module_name.c_str());
return CMD_EXEC_FATAL_ERROR;
}
phy_mem_module = module_manager.find_module(phy_mem_module_name);
if (!module_manager.valid_module_id(phy_mem_module)) {
VTR_LOG_ERROR("Failed to create the physical memory module '%s'!\n",
phy_mem_module_name.c_str());
return CMD_EXEC_FATAL_ERROR;
}
/* Add the physical memory module to the current module */
size_t phy_mem_instance =
module_manager.num_instance(curr_module, phy_mem_module);
module_manager.add_child_module(curr_module, phy_mem_module, false);
/* TODO: Give a more meaningful instance name? */
module_manager.set_child_instance_name(curr_module, phy_mem_module,
phy_mem_instance, phy_mem_module_name);
/* Register in the physical configurable children list */
module_manager.add_configurable_child(
curr_module, phy_mem_module, phy_mem_instance,
ModuleManager::e_config_child_type::PHYSICAL);
/* Build nets between the data output of the physical memory module and the
* outputs of the logical configurable children */
std::map<e_circuit_model_port_type, size_t> curr_mem_pin_index;
curr_mem_pin_index[CIRCUIT_MODEL_PORT_BL] = 0;
curr_mem_pin_index[CIRCUIT_MODEL_PORT_BLB] = 0;
std::map<e_circuit_model_port_type, std::string> mem2mem_port_map;
mem2mem_port_map[CIRCUIT_MODEL_PORT_BL] =
std::string(CONFIGURABLE_MEMORY_DATA_OUT_NAME);
mem2mem_port_map[CIRCUIT_MODEL_PORT_BLB] =
std::string(CONFIGURABLE_MEMORY_INVERTED_DATA_OUT_NAME);
for (size_t ichild = 0;
ichild < module_manager
.configurable_children(
curr_module, ModuleManager::e_config_child_type::LOGICAL)
.size();
++ichild) {
ModuleId des_module = module_manager.configurable_children(
curr_module, ModuleManager::e_config_child_type::LOGICAL)[ichild];
size_t des_instance = module_manager.configurable_child_instances(
curr_module, ModuleManager::e_config_child_type::LOGICAL)[ichild];
for (e_circuit_model_port_type port_type :
{CIRCUIT_MODEL_PORT_BL, CIRCUIT_MODEL_PORT_BLB}) {
std::string src_port_name = mem2mem_port_map[port_type];
std::string des_port_name =
generate_sram_port_name(CONFIG_MEM_FEEDTHROUGH, port_type);
/* Try to find these ports in the module manager */
ModulePortId src_port_id =
module_manager.find_module_port(phy_mem_module, src_port_name);
if (!module_manager.valid_module_port_id(phy_mem_module, src_port_id)) {
return CMD_EXEC_FATAL_ERROR;
}
BasicPort src_port =
module_manager.module_port(phy_mem_module, src_port_id);
ModulePortId des_port_id =
module_manager.find_module_port(des_module, des_port_name);
if (!module_manager.valid_module_port_id(des_module, des_port_id)) {
return CMD_EXEC_FATAL_ERROR;
}
BasicPort des_port = module_manager.module_port(des_module, des_port_id);
/* Build nets */
for (size_t ipin = 0; ipin < des_port.pins().size(); ++ipin) {
VTR_LOGV(
verbose, "Building net '%s[%lu].%s[%lu]' -> '%s[%lu].%s[%lu]\n",
module_manager.module_name(phy_mem_module).c_str(), phy_mem_instance,
src_port.get_name().c_str(), curr_mem_pin_index[port_type],
module_manager.module_name(des_module).c_str(), des_instance,
des_port.get_name().c_str(), des_port.pins()[ipin]);
/* Create a net and add source and sink to it */
ModuleNetId net = create_module_source_pin_net(
module_manager, curr_module, phy_mem_module, phy_mem_instance,
src_port_id, src_port.pins()[curr_mem_pin_index[port_type]]);
if (!module_manager.valid_module_net_id(curr_module, net)) {
return CMD_EXEC_FATAL_ERROR;
}
/* Add net sink */
module_manager.add_module_net_sink(curr_module, net, des_module,
des_instance, des_port_id,
des_port.pins()[ipin]);
curr_mem_pin_index[port_type]++;
}
}
}
VTR_ASSERT(curr_mem_pin_index[CIRCUIT_MODEL_PORT_BL] ==
module_num_config_bits);
VTR_ASSERT(curr_mem_pin_index[CIRCUIT_MODEL_PORT_BLB] ==
module_num_config_bits);
return status;
}
} /* end namespace openfpga */

View File

@ -22,11 +22,29 @@ std::vector<ModuleNetId> add_module_output_nets_to_chain_mem_modules(
const CircuitPortId& circuit_port, const ModuleId& child_module,
const size_t& child_index, const size_t& child_instance);
void build_memory_modules(ModuleManager& module_manager,
DecoderLibrary& arch_decoder_lib,
const MuxLibrary& mux_lib,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type);
int build_memory_modules(ModuleManager& module_manager,
DecoderLibrary& arch_decoder_lib,
const MuxLibrary& mux_lib,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const bool& require_feedthrough_memory,
const bool& verbose);
int build_memory_group_module(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type, const std::string& module_name,
const CircuitModelId& sram_model, const std::vector<ModuleId>& child_modules,
const std::vector<std::string>& child_instance_names, const size_t& num_mems,
const bool& verbose);
int add_physical_memory_module(ModuleManager& module_manager,
DecoderLibrary& decoder_lib,
const ModuleId& curr_module,
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model,
const bool& verbose);
} /* end namespace openfpga */

View File

@ -14,6 +14,7 @@
#include "vtr_time.h"
/* Headers from openfpgautil library */
#include "build_memory_modules.h"
#include "build_module_graph_utils.h"
#include "build_routing_module_utils.h"
#include "build_routing_modules.h"
@ -108,7 +109,8 @@ static void build_switch_block_mux_module(
const CircuitLibrary& circuit_lib, const e_side& chan_side,
const size_t& chan_node_id, const RRNodeId& cur_rr_node,
const std::vector<RRNodeId>& driver_rr_nodes, const RRSwitchId& switch_index,
const std::map<ModulePinInfo, ModuleNetId>& input_port_to_module_nets) {
const std::map<ModulePinInfo, ModuleNetId>& input_port_to_module_nets,
const bool& group_config_block) {
/* Check current rr_node is CHANX or CHANY*/
VTR_ASSERT((CHANX == rr_graph.node_type(cur_rr_node)) ||
(CHANY == rr_graph.node_type(cur_rr_node)));
@ -214,6 +216,11 @@ static void build_switch_block_mux_module(
std::string mem_module_name =
generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size,
std::string(MEMORY_MODULE_POSTFIX));
if (group_config_block) {
mem_module_name =
generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size,
std::string(MEMORY_FEEDTHROUGH_MODULE_POSTFIX));
}
ModuleId mem_module = module_manager.find_module(mem_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mem_module));
@ -224,7 +231,8 @@ static void build_switch_block_mux_module(
* modules
*/
std::string mem_instance_name = generate_sb_memory_instance_name(
SWITCH_BLOCK_MEM_INSTANCE_PREFIX, chan_side, chan_node_id, std::string(""));
SWITCH_BLOCK_MEM_INSTANCE_PREFIX, chan_side, chan_node_id, std::string(""),
group_config_block);
module_manager.set_child_instance_name(sb_module, mem_module, mem_instance_id,
mem_instance_name);
@ -234,7 +242,28 @@ static void build_switch_block_mux_module(
module_manager, sb_module, mux_module, mux_instance_id, mem_module,
mem_instance_id, circuit_lib, mux_model);
/* Update memory and instance list */
module_manager.add_configurable_child(sb_module, mem_module, mem_instance_id);
size_t config_child_id = module_manager.num_configurable_children(
sb_module, ModuleManager::e_config_child_type::LOGICAL);
module_manager.add_configurable_child(
sb_module, mem_module, mem_instance_id,
group_config_block ? ModuleManager::e_config_child_type::LOGICAL
: ModuleManager::e_config_child_type::UNIFIED);
/* For logical memory, define the physical memory here */
if (group_config_block) {
std::string physical_mem_module_name =
generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size,
std::string(MEMORY_MODULE_POSTFIX));
ModuleId physical_mem_module =
module_manager.find_module(physical_mem_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(physical_mem_module));
module_manager.set_logical2physical_configurable_child(
sb_module, config_child_id, physical_mem_module);
std::string physical_mem_instance_name = generate_sb_memory_instance_name(
SWITCH_BLOCK_MEM_INSTANCE_PREFIX, chan_side, chan_node_id,
std::string(""), false);
module_manager.set_logical2physical_configurable_child_instance_name(
sb_module, config_child_id, physical_mem_instance_name);
}
}
/*********************************************************************
@ -248,7 +277,8 @@ static void build_switch_block_interc_modules(
const RRGraphView& rr_graph, const RRGSB& rr_gsb,
const CircuitLibrary& circuit_lib, const e_side& chan_side,
const size_t& chan_node_id,
const std::map<ModulePinInfo, ModuleNetId>& input_port_to_module_nets) {
const std::map<ModulePinInfo, ModuleNetId>& input_port_to_module_nets,
const bool& group_config_block) {
std::vector<RRNodeId> driver_rr_nodes;
/* Get the node */
@ -284,7 +314,7 @@ static void build_switch_block_interc_modules(
build_switch_block_mux_module(
module_manager, sb_module, device_annotation, grids, rr_graph, rr_gsb,
circuit_lib, chan_side, chan_node_id, cur_rr_node, driver_rr_nodes,
driver_switches[0], input_port_to_module_nets);
driver_switches[0], input_port_to_module_nets, group_config_block);
} /*Nothing should be done else*/
}
@ -354,7 +384,8 @@ static void build_switch_block_module(
const VprDeviceAnnotation& device_annotation, const DeviceGrid& grids,
const RRGraphView& rr_graph, const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const RRGSB& rr_gsb, const bool& verbose) {
const CircuitModelId& sram_model, const RRGSB& rr_gsb,
const bool& group_config_block, const bool& verbose) {
/* Create a Module of Switch Block and add to module manager */
vtr::Point<size_t> gsb_coordinate(rr_gsb.get_sb_x(), rr_gsb.get_sb_y());
ModuleId sb_module = module_manager.add_module(
@ -456,11 +487,18 @@ static void build_switch_block_module(
build_switch_block_interc_modules(
module_manager, sb_module, device_annotation, grids, rr_graph, rr_gsb,
circuit_lib, side_manager.get_side(), itrack,
input_port_to_module_nets);
input_port_to_module_nets, group_config_block);
}
}
}
/* Build a physical memory block */
if (group_config_block) {
add_physical_memory_module(module_manager, decoder_lib, sb_module,
circuit_lib, sram_orgz_type, sram_model,
verbose);
}
/* Add global ports to the pb_module:
* This is a much easier job after adding sub modules (instances),
* we just need to find all the global ports from the child modules and build
@ -486,9 +524,13 @@ static void build_switch_block_module(
* we just need to find all the I/O ports from the child modules and build a
* list of it
*/
ModuleManager::e_config_child_type config_child_type =
group_config_block ? ModuleManager::e_config_child_type::PHYSICAL
: ModuleManager::e_config_child_type::LOGICAL;
size_t module_num_config_bits =
find_module_num_config_bits_from_child_modules(
module_manager, sb_module, circuit_lib, sram_model, sram_orgz_type);
module_manager, sb_module, circuit_lib, sram_model, sram_orgz_type,
config_child_type);
if (0 < module_num_config_bits) {
add_pb_sram_ports_to_module_manager(module_manager, sb_module, circuit_lib,
sram_model, sram_orgz_type,
@ -499,10 +541,11 @@ static void build_switch_block_module(
* primitive modules This is a one-shot addition that covers all the memory
* modules in this primitive module!
*/
if (0 < module_manager.configurable_children(sb_module).size()) {
if (0 <
module_manager.num_configurable_children(sb_module, config_child_type)) {
add_pb_module_nets_memory_config_bus(
module_manager, decoder_lib, sb_module, sram_orgz_type,
circuit_lib.design_tech_type(sram_model));
circuit_lib.design_tech_type(sram_model), config_child_type);
}
VTR_LOGV(verbose, "Done\n");
@ -586,7 +629,8 @@ static void build_connection_block_mux_module(
const RRGraphView& rr_graph, const RRGSB& rr_gsb, const t_rr_type& cb_type,
const CircuitLibrary& circuit_lib, const e_side& cb_ipin_side,
const size_t& ipin_index,
const std::map<ModulePinInfo, ModuleNetId>& input_port_to_module_nets) {
const std::map<ModulePinInfo, ModuleNetId>& input_port_to_module_nets,
const bool& group_config_block) {
const RRNodeId& cur_rr_node = rr_gsb.get_ipin_node(cb_ipin_side, ipin_index);
/* Check current rr_node is an input pin of a CLB */
VTR_ASSERT(IPIN == rr_graph.node_type(cur_rr_node));
@ -697,6 +741,11 @@ static void build_connection_block_mux_module(
std::string mem_module_name =
generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size,
std::string(MEMORY_MODULE_POSTFIX));
if (group_config_block) {
mem_module_name =
generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size,
std::string(MEMORY_FEEDTHROUGH_MODULE_POSTFIX));
}
ModuleId mem_module = module_manager.find_module(mem_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mem_module));
@ -711,7 +760,7 @@ static void build_connection_block_mux_module(
CONNECTION_BLOCK_MEM_INSTANCE_PREFIX,
get_rr_graph_single_node_side(
rr_graph, rr_gsb.get_ipin_node(cb_ipin_side, ipin_index)),
ipin_index, std::string(""));
ipin_index, std::string(""), group_config_block);
module_manager.set_child_instance_name(cb_module, mem_module, mem_instance_id,
mem_instance_name);
@ -721,7 +770,30 @@ static void build_connection_block_mux_module(
module_manager, cb_module, mux_module, mux_instance_id, mem_module,
mem_instance_id, circuit_lib, mux_model);
/* Update memory and instance list */
module_manager.add_configurable_child(cb_module, mem_module, mem_instance_id);
size_t config_child_id = module_manager.num_configurable_children(
cb_module, ModuleManager::e_config_child_type::LOGICAL);
module_manager.add_configurable_child(
cb_module, mem_module, mem_instance_id,
group_config_block ? ModuleManager::e_config_child_type::LOGICAL
: ModuleManager::e_config_child_type::UNIFIED);
/* For logical memory, define the physical memory here */
if (group_config_block) {
std::string physical_mem_module_name =
generate_mux_subckt_name(circuit_lib, mux_model, datapath_mux_size,
std::string(MEMORY_MODULE_POSTFIX));
ModuleId physical_mem_module =
module_manager.find_module(physical_mem_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(physical_mem_module));
module_manager.set_logical2physical_configurable_child(
cb_module, config_child_id, physical_mem_module);
std::string physical_mem_instance_name = generate_cb_memory_instance_name(
CONNECTION_BLOCK_MEM_INSTANCE_PREFIX,
get_rr_graph_single_node_side(
rr_graph, rr_gsb.get_ipin_node(cb_ipin_side, ipin_index)),
ipin_index, std::string(""), false);
module_manager.set_logical2physical_configurable_child_instance_name(
cb_module, config_child_id, physical_mem_instance_name);
}
}
/********************************************************************
@ -737,7 +809,8 @@ static void build_connection_block_interc_modules(
const RRGraphView& rr_graph, const RRGSB& rr_gsb, const t_rr_type& cb_type,
const CircuitLibrary& circuit_lib, const e_side& cb_ipin_side,
const size_t& ipin_index,
const std::map<ModulePinInfo, ModuleNetId>& input_port_to_module_nets) {
const std::map<ModulePinInfo, ModuleNetId>& input_port_to_module_nets,
const bool& group_config_block) {
std::vector<RREdgeId> driver_rr_edges =
rr_gsb.get_ipin_node_in_edges(rr_graph, cb_ipin_side, ipin_index);
@ -753,8 +826,8 @@ static void build_connection_block_interc_modules(
/* Print the multiplexer, fan_in >= 2 */
build_connection_block_mux_module(
module_manager, cb_module, device_annotation, grids, rr_graph, rr_gsb,
cb_type, circuit_lib, cb_ipin_side, ipin_index,
input_port_to_module_nets);
cb_type, circuit_lib, cb_ipin_side, ipin_index, input_port_to_module_nets,
group_config_block);
} /*Nothing should be done else*/
}
@ -819,7 +892,8 @@ static void build_connection_block_module(
const RRGraphView& rr_graph, const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const RRGSB& rr_gsb,
const t_rr_type& cb_type, const bool& verbose) {
const t_rr_type& cb_type, const bool& group_config_block,
const bool& verbose) {
/* Create the netlist */
vtr::Point<size_t> gsb_coordinate(rr_gsb.get_cb_x(cb_type),
rr_gsb.get_cb_y(cb_type));
@ -941,10 +1015,18 @@ static void build_connection_block_module(
++inode) {
build_connection_block_interc_modules(
module_manager, cb_module, device_annotation, grids, rr_graph, rr_gsb,
cb_type, circuit_lib, cb_ipin_side, inode, input_port_to_module_nets);
cb_type, circuit_lib, cb_ipin_side, inode, input_port_to_module_nets,
group_config_block);
}
}
/* Build a physical memory block */
if (group_config_block) {
add_physical_memory_module(module_manager, decoder_lib, cb_module,
circuit_lib, sram_orgz_type, sram_model,
verbose);
}
/* Add global ports to the pb_module:
* This is a much easier job after adding sub modules (instances),
* we just need to find all the global ports from the child modules and build
@ -970,9 +1052,13 @@ static void build_connection_block_module(
* we just need to find all the I/O ports from the child modules and build a
* list of it
*/
ModuleManager::e_config_child_type config_child_type =
group_config_block ? ModuleManager::e_config_child_type::PHYSICAL
: ModuleManager::e_config_child_type::LOGICAL;
size_t module_num_config_bits =
find_module_num_config_bits_from_child_modules(
module_manager, cb_module, circuit_lib, sram_model, sram_orgz_type);
module_manager, cb_module, circuit_lib, sram_model, sram_orgz_type,
config_child_type);
if (0 < module_num_config_bits) {
add_pb_sram_ports_to_module_manager(module_manager, cb_module, circuit_lib,
sram_model, sram_orgz_type,
@ -983,10 +1069,11 @@ static void build_connection_block_module(
* primitive modules This is a one-shot addition that covers all the memory
* modules in this primitive module!
*/
if (0 < module_manager.configurable_children(cb_module).size()) {
if (0 <
module_manager.num_configurable_children(cb_module, config_child_type)) {
add_pb_module_nets_memory_config_bus(
module_manager, decoder_lib, cb_module, sram_orgz_type,
circuit_lib.design_tech_type(sram_model));
circuit_lib.design_tech_type(sram_model), config_child_type);
}
VTR_LOGV(verbose, "Done\n");
@ -1002,7 +1089,7 @@ static void build_flatten_connection_block_modules(
const DeviceRRGSB& device_rr_gsb, const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const t_rr_type& cb_type,
const bool& verbose) {
const bool& group_config_block, const bool& verbose) {
/* Build unique X-direction connection block modules */
vtr::Point<size_t> cb_range = device_rr_gsb.get_gsb_range();
@ -1019,7 +1106,7 @@ static void build_flatten_connection_block_modules(
build_connection_block_module(
module_manager, decoder_lib, device_annotation, device_ctx.grid,
device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model, rr_gsb,
cb_type, verbose);
cb_type, group_config_block, verbose);
}
}
}
@ -1038,7 +1125,8 @@ void build_flatten_routing_modules(
const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation,
const DeviceRRGSB& device_rr_gsb, const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const bool& verbose) {
const CircuitModelId& sram_model, const bool& group_config_block,
const bool& verbose) {
vtr::ScopedStartFinishTimer timer("Build routing modules...");
vtr::Point<size_t> sb_range = device_rr_gsb.get_gsb_range();
@ -1053,17 +1141,19 @@ void build_flatten_routing_modules(
build_switch_block_module(module_manager, decoder_lib, device_annotation,
device_ctx.grid, device_ctx.rr_graph,
circuit_lib, sram_orgz_type, sram_model, rr_gsb,
verbose);
group_config_block, verbose);
}
}
build_flatten_connection_block_modules(
module_manager, decoder_lib, device_ctx, device_annotation, device_rr_gsb,
circuit_lib, sram_orgz_type, sram_model, CHANX, verbose);
circuit_lib, sram_orgz_type, sram_model, CHANX, group_config_block,
verbose);
build_flatten_connection_block_modules(
module_manager, decoder_lib, device_ctx, device_annotation, device_rr_gsb,
circuit_lib, sram_orgz_type, sram_model, CHANY, verbose);
circuit_lib, sram_orgz_type, sram_model, CHANY, group_config_block,
verbose);
}
/********************************************************************
@ -1082,7 +1172,8 @@ void build_unique_routing_modules(
const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation,
const DeviceRRGSB& device_rr_gsb, const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const bool& verbose) {
const CircuitModelId& sram_model, const bool& group_config_block,
const bool& verbose) {
vtr::ScopedStartFinishTimer timer("Build unique routing modules...");
/* Build unique switch block modules */
@ -1091,7 +1182,7 @@ void build_unique_routing_modules(
build_switch_block_module(module_manager, decoder_lib, device_annotation,
device_ctx.grid, device_ctx.rr_graph, circuit_lib,
sram_orgz_type, sram_model, unique_mirror,
verbose);
group_config_block, verbose);
}
/* Build unique X-direction connection block modules */
@ -1102,7 +1193,7 @@ void build_unique_routing_modules(
build_connection_block_module(
module_manager, decoder_lib, device_annotation, device_ctx.grid,
device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model,
unique_mirror, CHANX, verbose);
unique_mirror, CHANX, group_config_block, verbose);
}
/* Build unique X-direction connection block modules */
@ -1113,7 +1204,7 @@ void build_unique_routing_modules(
build_connection_block_module(
module_manager, decoder_lib, device_annotation, device_ctx.grid,
device_ctx.rr_graph, circuit_lib, sram_orgz_type, sram_model,
unique_mirror, CHANY, verbose);
unique_mirror, CHANY, group_config_block, verbose);
}
}

View File

@ -24,14 +24,16 @@ void build_flatten_routing_modules(
const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation,
const DeviceRRGSB& device_rr_gsb, const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const bool& verbose);
const CircuitModelId& sram_model, const bool& group_config_block,
const bool& verbose);
void build_unique_routing_modules(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation,
const DeviceRRGSB& device_rr_gsb, const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const bool& verbose);
const CircuitModelId& sram_model, const bool& group_config_block,
const bool& verbose);
} /* end namespace openfpga */

View File

@ -1331,8 +1331,9 @@ static int build_tile_module(
if (0 < find_module_num_config_bits(module_manager, pb_module,
circuit_lib, sram_model,
sram_orgz_type)) {
module_manager.add_configurable_child(tile_module, pb_module,
pb_instance);
module_manager.add_configurable_child(
tile_module, pb_module, pb_instance,
ModuleManager::e_config_child_type::UNIFIED);
}
VTR_LOGV(
verbose,
@ -1378,8 +1379,9 @@ static int build_tile_module(
if (0 < find_module_num_config_bits(module_manager, cb_module,
circuit_lib, sram_model,
sram_orgz_type)) {
module_manager.add_configurable_child(tile_module, cb_module,
cb_instance);
module_manager.add_configurable_child(
tile_module, cb_module, cb_instance,
ModuleManager::e_config_child_type::UNIFIED);
}
VTR_LOGV(verbose,
"Added connection block module '%s' (instance: '%s') to "
@ -1417,8 +1419,9 @@ static int build_tile_module(
sb_instance_name);
if (0 < find_module_num_config_bits(module_manager, sb_module, circuit_lib,
sram_model, sram_orgz_type)) {
module_manager.add_configurable_child(tile_module, sb_module,
sb_instance);
module_manager.add_configurable_child(
tile_module, sb_module, sb_instance,
ModuleManager::e_config_child_type::UNIFIED);
}
VTR_LOGV(
verbose,
@ -1468,7 +1471,8 @@ static int build_tile_module(
*/
size_t module_num_config_bits =
find_module_num_config_bits_from_child_modules(
module_manager, tile_module, circuit_lib, sram_model, sram_orgz_type);
module_manager, tile_module, circuit_lib, sram_model, sram_orgz_type,
ModuleManager::e_config_child_type::LOGICAL);
if (0 < module_num_config_bits) {
add_pb_sram_ports_to_module_manager(module_manager, tile_module,
circuit_lib, sram_model, sram_orgz_type,
@ -1479,10 +1483,12 @@ static int build_tile_module(
* This is a one-shot addition that covers all the memory modules in this pb
* module!
*/
if (0 < module_manager.configurable_children(tile_module).size()) {
if (0 < module_manager.num_configurable_children(
tile_module, ModuleManager::e_config_child_type::LOGICAL)) {
add_pb_module_nets_memory_config_bus(
module_manager, decoder_lib, tile_module, sram_orgz_type,
circuit_lib.design_tech_type(sram_model));
circuit_lib.design_tech_type(sram_model),
ModuleManager::e_config_child_type::LOGICAL);
}
VTR_LOGV(verbose, "Done\n");

View File

@ -57,7 +57,8 @@ int build_top_module(
const CircuitModelId& sram_model, const FabricTile& fabric_tile,
const bool& frame_view, const bool& compact_routing_hierarchy,
const bool& duplicate_grid_pin, const FabricKey& fabric_key,
const bool& generate_random_fabric_key, const bool& verbose) {
const bool& generate_random_fabric_key, const bool& group_config_block,
const bool& verbose) {
vtr::ScopedStartFinishTimer timer("Build FPGA fabric module");
int status = CMD_EXEC_SUCCESS;
@ -75,14 +76,15 @@ int build_top_module(
module_manager, top_module, blwl_sr_banks, circuit_lib, clk_ntwk,
rr_clock_lookup, vpr_device_annotation, grids, tile_annotation, rr_graph,
device_rr_gsb, tile_direct, arch_direct, config_protocol, sram_model,
frame_view, compact_routing_hierarchy, duplicate_grid_pin, fabric_key);
frame_view, compact_routing_hierarchy, duplicate_grid_pin, fabric_key,
group_config_block);
} else {
/* TODO: Build the tile instances under the top module */
status = build_top_module_tile_child_instances(
module_manager, top_module, blwl_sr_banks, circuit_lib, clk_ntwk,
rr_clock_lookup, vpr_device_annotation, grids, tile_annotation, rr_graph,
device_rr_gsb, tile_direct, arch_direct, fabric_tile, config_protocol,
sram_model, fabric_key, frame_view, verbose);
sram_model, fabric_key, group_config_block, frame_view, verbose);
}
if (status != CMD_EXEC_SUCCESS) {
@ -134,7 +136,10 @@ int build_top_module(
* module!
*/
if (false == frame_view) {
if (0 < module_manager.configurable_children(top_module).size()) {
if (0 < module_manager
.configurable_children(
top_module, ModuleManager::e_config_child_type::PHYSICAL)
.size()) {
add_top_module_nets_memory_config_bus(
module_manager, decoder_lib, blwl_sr_banks, top_module, circuit_lib,
config_protocol, circuit_lib.design_tech_type(sram_model),

View File

@ -44,7 +44,8 @@ int build_top_module(
const CircuitModelId& sram_model, const FabricTile& fabric_tile,
const bool& frame_view, const bool& compact_routing_hierarchy,
const bool& duplicate_grid_pin, const FabricKey& fabric_key,
const bool& generate_random_fabric_key, const bool& verbose);
const bool& generate_random_fabric_key, const bool& group_config_block,
const bool& verbose);
} /* end namespace openfpga */

View File

@ -436,7 +436,7 @@ int build_top_module_fine_grained_child_instances(
const ArchDirect& arch_direct, const ConfigProtocol& config_protocol,
const CircuitModelId& sram_model, const bool& frame_view,
const bool& compact_routing_hierarchy, const bool& duplicate_grid_pin,
const FabricKey& fabric_key) {
const FabricKey& fabric_key, const bool& group_config_block) {
int status = CMD_EXEC_SUCCESS;
std::map<t_rr_type, vtr::Matrix<size_t>> cb_instance_ids;
@ -529,7 +529,8 @@ int build_top_module_fine_grained_child_instances(
/* Update the memory organization in sub module (non-top) */
status = load_submodules_memory_modules_from_fabric_key(
module_manager, circuit_lib, config_protocol, fabric_key);
module_manager, circuit_lib, config_protocol, fabric_key,
group_config_block);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}

View File

@ -43,7 +43,7 @@ int build_top_module_fine_grained_child_instances(
const ArchDirect& arch_direct, const ConfigProtocol& config_protocol,
const CircuitModelId& sram_model, const bool& frame_view,
const bool& compact_routing_hierarchy, const bool& duplicate_grid_pin,
const FabricKey& fabric_key);
const FabricKey& fabric_key, const bool& group_config_block);
} /* end namespace openfpga */

View File

@ -1076,7 +1076,11 @@ static void organize_top_module_tile_based_memory_modules(
const CircuitModelId& sram_model, const DeviceGrid& grids,
const vtr::Matrix<size_t>& tile_instance_ids, const FabricTile& fabric_tile) {
/* Ensure clean vectors to return */
VTR_ASSERT(true == module_manager.configurable_children(top_module).empty());
VTR_ASSERT(true ==
module_manager
.configurable_children(
top_module, ModuleManager::e_config_child_type::PHYSICAL)
.empty());
std::vector<vtr::Point<size_t>> tile_coords;
bool positive_direction = true;
@ -1116,6 +1120,7 @@ static void organize_top_module_tile_based_memory_modules(
module_manager.add_configurable_child(
top_module, tile_module,
tile_instance_ids[curr_tile_coord.x()][curr_tile_coord.y()],
ModuleManager::e_config_child_type::UNIFIED,
vtr::Point<int>(curr_tile_coord.x(), curr_tile_coord.y()));
}
}
@ -1859,7 +1864,8 @@ int build_top_module_tile_child_instances(
const DeviceRRGSB& device_rr_gsb, const TileDirect& tile_direct,
const ArchDirect& arch_direct, const FabricTile& fabric_tile,
const ConfigProtocol& config_protocol, const CircuitModelId& sram_model,
const FabricKey& fabric_key, const bool& frame_view, const bool& verbose) {
const FabricKey& fabric_key, const bool& group_config_block,
const bool& frame_view, const bool& verbose) {
int status = CMD_EXEC_SUCCESS;
vtr::Matrix<size_t> tile_instance_ids;
status = add_top_module_tile_instances(module_manager, top_module,
@ -1941,7 +1947,8 @@ int build_top_module_tile_child_instances(
/* Update the memory organization in sub module (non-top) */
status = load_submodules_memory_modules_from_fabric_key(
module_manager, circuit_lib, config_protocol, fabric_key);
module_manager, circuit_lib, config_protocol, fabric_key,
group_config_block);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}

View File

@ -42,7 +42,8 @@ int build_top_module_tile_child_instances(
const DeviceRRGSB& device_rr_gsb, const TileDirect& tile_direct,
const ArchDirect& arch_direct, const FabricTile& fabric_tile,
const ConfigProtocol& config_protocol, const CircuitModelId& sram_model,
const FabricKey& fabric_key, const bool& frame_view, const bool& verbose);
const FabricKey& fabric_key, const bool& group_config_block,
const bool& frame_view, const bool& verbose);
} /* end namespace openfpga */

View File

@ -86,7 +86,7 @@ static void organize_top_module_tile_cb_modules(
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)],
config_coord);
ModuleManager::e_config_child_type::UNIFIED, config_coord);
}
}
@ -173,7 +173,8 @@ static void organize_top_module_tile_memory_modules(
rr_gsb.get_sb_y() * 2 + 1);
module_manager.add_configurable_child(
top_module, sb_module,
sb_instance_ids[rr_gsb.get_sb_x()][rr_gsb.get_sb_y()], config_coord);
sb_instance_ids[rr_gsb.get_sb_x()][rr_gsb.get_sb_y()],
ModuleManager::e_config_child_type::UNIFIED, config_coord);
}
}
@ -219,7 +220,8 @@ static void organize_top_module_tile_memory_modules(
vtr::Point<int> config_coord(tile_coord.x() * 2, tile_coord.y() * 2);
module_manager.add_configurable_child(
top_module, grid_module,
grid_instance_ids[tile_coord.x()][tile_coord.y()], config_coord);
grid_instance_ids[tile_coord.x()][tile_coord.y()],
ModuleManager::e_config_child_type::UNIFIED, config_coord);
}
}
@ -269,14 +271,21 @@ void build_top_module_configurable_regions(
"Build configurable regions for the top module");
/* Ensure we have valid configurable children */
VTR_ASSERT(false == module_manager.configurable_children(top_module).empty());
VTR_ASSERT(false ==
module_manager
.configurable_children(
top_module, ModuleManager::e_config_child_type::PHYSICAL)
.empty());
/* Ensure that our region definition is valid */
VTR_ASSERT(1 <= config_protocol.num_regions());
/* Exclude decoders from the list */
size_t num_configurable_children =
module_manager.configurable_children(top_module).size();
module_manager
.configurable_children(top_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size();
if (CONFIG_MEM_MEMORY_BANK == config_protocol.type() ||
CONFIG_MEM_QL_MEMORY_BANK == config_protocol.type()) {
num_configurable_children -= 2;
@ -291,7 +300,10 @@ void build_top_module_configurable_regions(
bool create_region = true;
ConfigRegionId curr_region = ConfigRegionId::INVALID();
for (size_t ichild = 0;
ichild < module_manager.configurable_children(top_module).size();
ichild < module_manager
.configurable_children(
top_module, ModuleManager::e_config_child_type::PHYSICAL)
.size();
++ichild) {
if (true == create_region) {
curr_region = module_manager.add_config_region(top_module);
@ -300,8 +312,11 @@ void build_top_module_configurable_regions(
/* Add the child to a region */
module_manager.add_configurable_child_to_region(
top_module, curr_region,
module_manager.configurable_children(top_module)[ichild],
module_manager.configurable_child_instances(top_module)[ichild], ichild);
module_manager.configurable_children(
top_module, ModuleManager::e_config_child_type::PHYSICAL)[ichild],
module_manager.configurable_child_instances(
top_module, ModuleManager::e_config_child_type::PHYSICAL)[ichild],
ichild);
/* See if the current region is full or not:
* For the last region, we will keep adding until we finish all the children
@ -427,7 +442,11 @@ void organize_top_module_memory_modules(
const std::map<t_rr_type, vtr::Matrix<size_t>>& cb_instance_ids,
const bool& compact_routing_hierarchy) {
/* Ensure clean vectors to return */
VTR_ASSERT(true == module_manager.configurable_children(top_module).empty());
VTR_ASSERT(true ==
module_manager
.configurable_children(
top_module, ModuleManager::e_config_child_type::PHYSICAL)
.empty());
/* First, organize the I/O tiles on the border */
/* Special for the I/O tileas on RIGHT and BOTTOM,
@ -530,7 +549,11 @@ void organize_top_module_memory_modules(
void shuffle_top_module_configurable_children(
ModuleManager& module_manager, const ModuleId& top_module,
const ConfigProtocol& config_protocol) {
size_t num_keys = module_manager.configurable_children(top_module).size();
size_t num_keys =
module_manager
.configurable_children(top_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size();
std::vector<size_t> shuffled_keys;
shuffled_keys.reserve(num_keys);
for (size_t ikey = 0; ikey < num_keys; ++ikey) {
@ -541,11 +564,14 @@ void shuffle_top_module_configurable_children(
/* Cache the configurable children and their instances */
std::vector<ModuleId> orig_configurable_children =
module_manager.configurable_children(top_module);
module_manager.configurable_children(
top_module, ModuleManager::e_config_child_type::PHYSICAL);
std::vector<size_t> orig_configurable_child_instances =
module_manager.configurable_child_instances(top_module);
module_manager.configurable_child_instances(
top_module, ModuleManager::e_config_child_type::PHYSICAL);
std::vector<vtr::Point<int>> orig_configurable_child_coordinates =
module_manager.configurable_child_coordinates(top_module);
module_manager.configurable_child_coordinates(
top_module, ModuleManager::e_config_child_type::PHYSICAL);
/* Reorganize the configurable children */
module_manager.clear_configurable_children(top_module);
@ -554,6 +580,7 @@ void shuffle_top_module_configurable_children(
module_manager.add_configurable_child(
top_module, orig_configurable_children[shuffled_keys[ikey]],
orig_configurable_child_instances[shuffled_keys[ikey]],
ModuleManager::e_config_child_type::UNIFIED,
orig_configurable_child_coordinates[shuffled_keys[ikey]]);
}
@ -650,9 +677,10 @@ int load_top_module_memory_modules_from_fabric_key(
}
/* Now we can add the child to configurable children of the top module */
module_manager.add_configurable_child(top_module, instance_info.first,
instance_info.second,
fabric_key.key_coordinate(key));
module_manager.add_configurable_child(
top_module, instance_info.first, instance_info.second,
ModuleManager::e_config_child_type::UNIFIED,
fabric_key.key_coordinate(key));
module_manager.add_configurable_child_to_region(
top_module, top_module_config_region, instance_info.first,
instance_info.second, curr_configurable_child_id);
@ -1329,17 +1357,27 @@ static void add_top_module_nets_cmos_memory_bank_config_bus(
* Note: this MUST be done after adding all the module nets to other regular
* configurable children
*/
module_manager.add_configurable_child(top_module, bl_decoder_module,
curr_bl_decoder_instance_id);
module_manager.add_configurable_child(
top_module, bl_decoder_module, curr_bl_decoder_instance_id,
ModuleManager::e_config_child_type::PHYSICAL);
module_manager.add_configurable_child_to_region(
top_module, config_region, bl_decoder_module, curr_bl_decoder_instance_id,
module_manager.configurable_children(top_module).size() - 1);
module_manager
.configurable_children(top_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size() -
1);
module_manager.add_configurable_child(top_module, wl_decoder_module,
curr_wl_decoder_instance_id);
module_manager.add_configurable_child(
top_module, wl_decoder_module, curr_wl_decoder_instance_id,
ModuleManager::e_config_child_type::PHYSICAL);
module_manager.add_configurable_child_to_region(
top_module, config_region, wl_decoder_module, curr_wl_decoder_instance_id,
module_manager.configurable_children(top_module).size() - 1);
module_manager
.configurable_children(top_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size() -
1);
}
}
@ -1759,8 +1797,8 @@ static void add_top_module_nets_cmos_memory_frame_decoder_config_bus(
for (size_t mem_index = 0; mem_index < configurable_children.size();
++mem_index) {
ModuleId child_module = configurable_children[mem_index];
size_t child_instance =
module_manager.configurable_child_instances(parent_module)[mem_index];
size_t child_instance = module_manager.configurable_child_instances(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)[mem_index];
ModulePortId child_din_port = module_manager.find_module_port(
child_module, std::string(DECODER_DATA_IN_PORT_NAME));
BasicPort child_din_port_info =
@ -1794,8 +1832,8 @@ static void add_top_module_nets_cmos_memory_frame_decoder_config_bus(
for (size_t mem_index = 0; mem_index < configurable_children.size();
++mem_index) {
ModuleId child_module = configurable_children[mem_index];
size_t child_instance =
module_manager.configurable_child_instances(parent_module)[mem_index];
size_t child_instance = module_manager.configurable_child_instances(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)[mem_index];
ModulePortId child_en_port = module_manager.find_module_port(
child_module, std::string(DECODER_ENABLE_PORT_NAME));
BasicPort child_en_port_info =
@ -1814,12 +1852,17 @@ static void add_top_module_nets_cmos_memory_frame_decoder_config_bus(
}
/* Add the decoder as the last configurable children */
module_manager.add_configurable_child(parent_module, decoder_module,
decoder_instance);
module_manager.add_configurable_child(
parent_module, decoder_module, decoder_instance,
ModuleManager::e_config_child_type::PHYSICAL);
/* Register the configurable child to configuration region */
module_manager.add_configurable_child_to_region(
parent_module, config_region, decoder_module, decoder_instance,
module_manager.configurable_children(parent_module).size() - 1);
module_manager
.configurable_children(parent_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size() -
1);
}
/*********************************************************************
@ -1927,10 +1970,10 @@ static void add_top_module_nets_cmos_memory_config_bus(
case CONFIG_MEM_STANDALONE:
add_module_nets_cmos_flatten_memory_config_bus(
module_manager, parent_module, config_protocol.type(),
CIRCUIT_MODEL_PORT_BL);
CIRCUIT_MODEL_PORT_BL, ModuleManager::e_config_child_type::PHYSICAL);
add_module_nets_cmos_flatten_memory_config_bus(
module_manager, parent_module, config_protocol.type(),
CIRCUIT_MODEL_PORT_WL);
CIRCUIT_MODEL_PORT_WL, ModuleManager::e_config_child_type::PHYSICAL);
break;
case CONFIG_MEM_SCAN_CHAIN: {
add_top_module_nets_cmos_memory_chain_config_bus(

View File

@ -58,7 +58,11 @@ static void add_module_nets_to_ql_memory_bank_shift_register_module(
const std::string& chain_head_port_name,
const std::string& chain_tail_port_name) {
for (size_t mem_index = 0;
mem_index < module_manager.configurable_children(parent_module).size();
mem_index <
module_manager
.configurable_children(parent_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size();
++mem_index) {
ModuleId net_src_module_id;
size_t net_src_instance_id;
@ -78,28 +82,30 @@ static void add_module_nets_to_ql_memory_bank_shift_register_module(
/* Find the port name of next memory module */
std::string sink_port_name = circuit_lib.port_prefix(model_input_port);
net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_module_id = module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)[mem_index];
net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
} else {
/* Find the port name of previous memory module */
std::string src_port_name = circuit_lib.port_prefix(model_output_port);
net_src_module_id =
module_manager.configurable_children(parent_module)[mem_index - 1];
net_src_module_id = module_manager.configurable_children(
parent_module,
ModuleManager::e_config_child_type::PHYSICAL)[mem_index - 1];
net_src_instance_id = module_manager.configurable_child_instances(
parent_module)[mem_index - 1];
parent_module,
ModuleManager::e_config_child_type::PHYSICAL)[mem_index - 1];
net_src_port_id =
module_manager.find_module_port(net_src_module_id, src_port_name);
/* Find the port name of next memory module */
std::string sink_port_name = circuit_lib.port_prefix(model_input_port);
net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_module_id = module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)[mem_index];
net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
}
@ -133,9 +139,15 @@ static void add_module_nets_to_ql_memory_bank_shift_register_module(
/* Find the port name of previous memory module */
std::string src_port_name = circuit_lib.port_prefix(model_output_port);
ModuleId net_src_module_id =
module_manager.configurable_children(parent_module).back();
module_manager
.configurable_children(parent_module,
ModuleManager::e_config_child_type::PHYSICAL)
.back();
size_t net_src_instance_id =
module_manager.configurable_child_instances(parent_module).back();
module_manager
.configurable_child_instances(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)
.back();
ModulePortId net_src_port_id =
module_manager.find_module_port(net_src_module_id, src_port_name);
@ -244,8 +256,9 @@ static ModuleId build_bl_shift_register_chain_module(
size_t sram_mem_instance =
module_manager.num_instance(mem_module, sram_mem_module);
module_manager.add_child_module(mem_module, sram_mem_module);
module_manager.add_configurable_child(mem_module, sram_mem_module,
sram_mem_instance);
module_manager.add_configurable_child(
mem_module, sram_mem_module, sram_mem_instance,
ModuleManager::e_config_child_type::UNIFIED);
/* Build module nets to wire bl outputs of sram modules to BL outputs of
* memory module */
@ -362,8 +375,9 @@ static ModuleId build_wl_shift_register_chain_module(
size_t sram_mem_instance =
module_manager.num_instance(mem_module, sram_mem_module);
module_manager.add_child_module(mem_module, sram_mem_module);
module_manager.add_configurable_child(mem_module, sram_mem_module,
sram_mem_instance);
module_manager.add_configurable_child(
mem_module, sram_mem_module, sram_mem_instance,
ModuleManager::e_config_child_type::UNIFIED);
/* Build module nets to wire wl outputs of sram modules to WL outputs of
* memory module */
@ -698,11 +712,16 @@ static void add_top_module_nets_cmos_ql_memory_bank_bl_decoder_config_bus(
* Note: this MUST be done after adding all the module nets to other regular
* configurable children
*/
module_manager.add_configurable_child(top_module, bl_decoder_module,
curr_bl_decoder_instance_id);
module_manager.add_configurable_child(
top_module, bl_decoder_module, curr_bl_decoder_instance_id,
ModuleManager::e_config_child_type::UNIFIED);
module_manager.add_configurable_child_to_region(
top_module, config_region, bl_decoder_module, curr_bl_decoder_instance_id,
module_manager.configurable_children(top_module).size() - 1);
module_manager
.configurable_children(top_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size() -
1);
}
}
@ -967,11 +986,16 @@ static void add_top_module_nets_cmos_ql_memory_bank_wl_decoder_config_bus(
* Note: this MUST be done after adding all the module nets to other regular
* configurable children
*/
module_manager.add_configurable_child(top_module, wl_decoder_module,
curr_wl_decoder_instance_id);
module_manager.add_configurable_child(
top_module, wl_decoder_module, curr_wl_decoder_instance_id,
ModuleManager::e_config_child_type::UNIFIED);
module_manager.add_configurable_child_to_region(
top_module, config_region, wl_decoder_module, curr_wl_decoder_instance_id,
module_manager.configurable_children(top_module).size() - 1);
module_manager
.configurable_children(top_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size() -
1);
}
}

View File

@ -32,7 +32,10 @@ static int add_module_keys_to_fabric_key(const ModuleManager& module_manager,
return CMD_EXEC_SUCCESS;
}
/* Bypass modules which does not have any configurable children */
if (module_manager.configurable_children(curr_module).empty()) {
if (module_manager
.configurable_children(curr_module,
ModuleManager::e_config_child_type::PHYSICAL)
.empty()) {
return CMD_EXEC_SUCCESS;
}
/* Now create the module and add subkey one by one */
@ -41,12 +44,15 @@ static int add_module_keys_to_fabric_key(const ModuleManager& module_manager,
return CMD_EXEC_FATAL_ERROR;
}
size_t num_config_child =
module_manager.configurable_children(curr_module).size();
module_manager
.configurable_children(curr_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size();
for (size_t ichild = 0; ichild < num_config_child; ++ichild) {
ModuleId child_module =
module_manager.configurable_children(curr_module)[ichild];
size_t child_instance =
module_manager.configurable_child_instances(curr_module)[ichild];
ModuleId child_module = module_manager.configurable_children(
curr_module, ModuleManager::e_config_child_type::PHYSICAL)[ichild];
size_t child_instance = module_manager.configurable_child_instances(
curr_module, ModuleManager::e_config_child_type::PHYSICAL)[ichild];
FabricSubKeyId sub_key = fabric_key.create_module_key(key_module_id);
fabric_key.set_sub_key_name(sub_key,
@ -111,7 +117,11 @@ int write_fabric_key_to_xml_file(
/* Build a fabric key database by visiting all the configurable children */
FabricKey fabric_key;
size_t num_keys = module_manager.configurable_children(top_module).size();
size_t num_keys =
module_manager
.configurable_children(top_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size();
fabric_key.reserve_keys(num_keys);

View File

@ -26,6 +26,17 @@ ModuleManager::module_range ModuleManager::modules() const {
return vtr::make_range(ids_.begin(), ids_.end());
}
std::vector<ModuleId> ModuleManager::modules_by_usage(
const ModuleManager::e_module_usage_type& usage) const {
std::vector<ModuleId> module_list;
for (ModuleId curr_module : ids_) {
if (usages_[curr_module] == usage) {
module_list.push_back(curr_module);
}
}
return module_list;
}
/* Find all the ports belonging to a module */
ModuleManager::module_port_range ModuleManager::module_ports(
const ModuleId& module) const {
@ -78,28 +89,56 @@ std::vector<size_t> ModuleManager::child_module_instances(
/* Find all the configurable child modules under a parent module */
std::vector<ModuleId> ModuleManager::configurable_children(
const ModuleId& parent_module) const {
const ModuleId& parent_module, const e_config_child_type& type) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
return configurable_children_[parent_module];
if (type == ModuleManager::e_config_child_type::LOGICAL) {
return logical_configurable_children_[parent_module];
}
VTR_ASSERT(type == ModuleManager::e_config_child_type::PHYSICAL);
return physical_configurable_children_[parent_module];
}
/* Find all the instances of configurable child modules under a parent module */
std::vector<size_t> ModuleManager::configurable_child_instances(
const ModuleId& parent_module) const {
const ModuleId& parent_module, const e_config_child_type& type) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
return configurable_child_instances_[parent_module];
if (type == ModuleManager::e_config_child_type::LOGICAL) {
return logical_configurable_child_instances_[parent_module];
}
VTR_ASSERT(type == ModuleManager::e_config_child_type::PHYSICAL);
return physical_configurable_child_instances_[parent_module];
}
std::vector<vtr::Point<int>> ModuleManager::configurable_child_coordinates(
const ModuleId& parent_module, const e_config_child_type& type) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
VTR_ASSERT(type == ModuleManager::e_config_child_type::PHYSICAL);
return physical_configurable_child_coordinates_[parent_module];
}
/* Find all the configurable child modules under a parent module */
std::vector<ModuleId> ModuleManager::logical2physical_configurable_children(
const ModuleId& parent_module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
return configurable_child_coordinates_[parent_module];
return logical2physical_configurable_children_[parent_module];
}
/* Find all the instances of configurable child modules under a parent module */
std::vector<std::string>
ModuleManager::logical2physical_configurable_child_instance_names(
const ModuleId& parent_module) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(parent_module));
return logical2physical_configurable_child_instance_names_[parent_module];
}
/* Find all the configurable child modules under a parent module */
@ -166,7 +205,7 @@ std::vector<ModuleId> ModuleManager::region_configurable_children(
for (const size_t& child_id :
config_region_children_[parent_module][region]) {
region_config_children.push_back(
configurable_children_[parent_module][child_id]);
physical_configurable_children_[parent_module][child_id]);
}
return region_config_children;
@ -185,7 +224,7 @@ std::vector<size_t> ModuleManager::region_configurable_child_instances(
for (const size_t& child_id :
config_region_children_[parent_module][region]) {
region_config_child_instances.push_back(
configurable_child_instances_[parent_module][child_id]);
physical_configurable_child_instances_[parent_module][child_id]);
}
return region_config_child_instances;
@ -205,7 +244,7 @@ ModuleManager::region_configurable_child_coordinates(
for (const size_t& child_id :
config_region_children_[parent_module][region]) {
region_config_child_coordinates.push_back(
configurable_child_coordinates_[parent_module][child_id]);
physical_configurable_child_coordinates_[parent_module][child_id]);
}
return region_config_child_coordinates;
@ -376,6 +415,16 @@ size_t ModuleManager::instance_id(const ModuleId& parent_module,
return size_t(-1);
}
size_t ModuleManager::num_configurable_children(
const ModuleId& parent_module, const e_config_child_type& type) const {
VTR_ASSERT(valid_module_id(parent_module));
if (type == ModuleManager::e_config_child_type::LOGICAL) {
return logical_configurable_children_[parent_module].size();
}
VTR_ASSERT(type == ModuleManager::e_config_child_type::PHYSICAL);
return physical_configurable_children_[parent_module].size();
}
ModuleManager::e_module_port_type ModuleManager::port_type(
const ModuleId& module, const ModulePortId& port) const {
/* validate both module id and port id*/
@ -612,6 +661,26 @@ bool ModuleManager::net_sink_exist(const ModuleId& module,
return false;
}
bool ModuleManager::unified_configurable_children(
const ModuleId& curr_module) const {
if (logical_configurable_children_[curr_module].size() !=
physical_configurable_children_[curr_module].size()) {
return false;
}
for (size_t ichild = 0;
ichild < logical_configurable_children_[curr_module].size(); ++ichild) {
if (logical_configurable_children_[curr_module][ichild] !=
physical_configurable_children_[curr_module][ichild]) {
return false;
}
if (logical_configurable_child_instances_[curr_module][ichild] !=
physical_configurable_child_instances_[curr_module][ichild]) {
return false;
}
}
return true;
}
/******************************************************************************
* Private Accessors
******************************************************************************/
@ -654,10 +723,15 @@ ModuleId ModuleManager::add_module(const std::string& name) {
children_.emplace_back();
num_child_instances_.emplace_back();
child_instance_names_.emplace_back();
configurable_children_.emplace_back();
configurable_child_instances_.emplace_back();
configurable_child_regions_.emplace_back();
configurable_child_coordinates_.emplace_back();
logical_configurable_children_.emplace_back();
logical_configurable_child_instances_.emplace_back();
physical_configurable_children_.emplace_back();
physical_configurable_child_instances_.emplace_back();
physical_configurable_child_regions_.emplace_back();
physical_configurable_child_coordinates_.emplace_back();
logical2physical_configurable_children_.emplace_back();
logical2physical_configurable_child_instance_names_.emplace_back();
config_region_ids_.emplace_back();
config_region_children_.emplace_back();
@ -903,6 +977,7 @@ void ModuleManager::set_child_instance_name(const ModuleId& parent_module,
void ModuleManager::add_configurable_child(const ModuleId& parent_module,
const ModuleId& child_module,
const size_t& child_instance,
const e_config_child_type& type,
const vtr::Point<int> coord) {
/* Validate the id of both parent and child modules */
VTR_ASSERT(valid_module_id(parent_module));
@ -910,29 +985,108 @@ void ModuleManager::add_configurable_child(const ModuleId& parent_module,
/* Ensure that the instance id is in range */
VTR_ASSERT(child_instance < num_instance(parent_module, child_module));
configurable_children_[parent_module].push_back(child_module);
configurable_child_instances_[parent_module].push_back(child_instance);
configurable_child_regions_[parent_module].push_back(
ConfigRegionId::INVALID());
configurable_child_coordinates_[parent_module].push_back(coord);
if (type == ModuleManager::e_config_child_type::LOGICAL ||
type == ModuleManager::e_config_child_type::UNIFIED) {
logical_configurable_children_[parent_module].push_back(child_module);
logical_configurable_child_instances_[parent_module].push_back(
child_instance);
}
if (type == ModuleManager::e_config_child_type::PHYSICAL ||
type == ModuleManager::e_config_child_type::UNIFIED) {
physical_configurable_children_[parent_module].push_back(child_module);
physical_configurable_child_instances_[parent_module].push_back(
child_instance);
physical_configurable_child_regions_[parent_module].push_back(
ConfigRegionId::INVALID());
physical_configurable_child_coordinates_[parent_module].push_back(coord);
}
if (type == ModuleManager::e_config_child_type::UNIFIED) {
logical2physical_configurable_children_[parent_module].push_back(
child_module);
logical2physical_configurable_child_instance_names_[parent_module]
.emplace_back();
} else if (type == ModuleManager::e_config_child_type::LOGICAL) {
logical2physical_configurable_children_[parent_module].emplace_back();
logical2physical_configurable_child_instance_names_[parent_module]
.emplace_back();
}
}
void ModuleManager::reserve_configurable_child(const ModuleId& parent_module,
const size_t& num_children) {
void ModuleManager::set_logical2physical_configurable_child(
const ModuleId& parent_module, const size_t& logical_child_id,
const ModuleId& physical_child_module) {
/* Sanity checks */
VTR_ASSERT(valid_module_id(parent_module));
/* Do reserve when the number of children is larger than current size of lists
*/
if (num_children > configurable_children_[parent_module].size()) {
configurable_children_[parent_module].reserve(num_children);
VTR_ASSERT(logical_child_id <
num_configurable_children(
parent_module, ModuleManager::e_config_child_type::LOGICAL));
/* Create the pair */
logical2physical_configurable_children_[parent_module][logical_child_id] =
physical_child_module;
}
void ModuleManager::set_logical2physical_configurable_child_instance_name(
const ModuleId& parent_module, const size_t& logical_child_id,
const std::string& physical_child_instance_name) {
/* Sanity checks */
VTR_ASSERT(valid_module_id(parent_module));
VTR_ASSERT(logical_child_id <
num_configurable_children(
parent_module, ModuleManager::e_config_child_type::LOGICAL));
/* Create the pair */
logical2physical_configurable_child_instance_names_
[parent_module][logical_child_id] = physical_child_instance_name;
}
void ModuleManager::reserve_configurable_child(
const ModuleId& parent_module, const size_t& num_children,
const e_config_child_type& type) {
VTR_ASSERT(valid_module_id(parent_module));
if (type == ModuleManager::e_config_child_type::LOGICAL ||
type == ModuleManager::e_config_child_type::UNIFIED) {
/* Do reserve when the number of children is larger than current size of
* lists
*/
if (num_children > logical_configurable_children_[parent_module].size()) {
logical_configurable_children_[parent_module].reserve(num_children);
}
if (num_children >
logical_configurable_child_instances_[parent_module].size()) {
logical_configurable_child_instances_[parent_module].reserve(
num_children);
}
if (num_children >
logical2physical_configurable_children_[parent_module].size()) {
logical2physical_configurable_children_[parent_module].reserve(
num_children);
}
if (num_children >
logical2physical_configurable_child_instance_names_[parent_module]
.size()) {
logical2physical_configurable_child_instance_names_[parent_module]
.reserve(num_children);
}
}
if (num_children > configurable_child_instances_[parent_module].size()) {
configurable_child_instances_[parent_module].reserve(num_children);
}
if (num_children > configurable_child_regions_[parent_module].size()) {
configurable_child_regions_[parent_module].reserve(num_children);
}
if (num_children > configurable_child_coordinates_[parent_module].size()) {
configurable_child_coordinates_[parent_module].reserve(num_children);
if (type == ModuleManager::e_config_child_type::PHYSICAL ||
type == ModuleManager::e_config_child_type::UNIFIED) {
if (num_children > physical_configurable_children_[parent_module].size()) {
physical_configurable_children_[parent_module].reserve(num_children);
}
if (num_children >
physical_configurable_child_instances_[parent_module].size()) {
physical_configurable_child_instances_[parent_module].reserve(
num_children);
}
if (num_children >
physical_configurable_child_regions_[parent_module].size()) {
physical_configurable_child_regions_[parent_module].reserve(num_children);
}
if (num_children >
physical_configurable_child_coordinates_[parent_module].size()) {
physical_configurable_child_coordinates_[parent_module].reserve(
num_children);
}
}
}
@ -961,23 +1115,28 @@ void ModuleManager::add_configurable_child_to_region(
/* Ensure that the child module is in the configurable children list */
VTR_ASSERT(child_module ==
configurable_children(parent_module)[config_child_id]);
configurable_children(
parent_module,
ModuleManager::e_config_child_type::PHYSICAL)[config_child_id]);
VTR_ASSERT(child_instance ==
configurable_child_instances(parent_module)[config_child_id]);
configurable_child_instances(
parent_module,
ModuleManager::e_config_child_type::PHYSICAL)[config_child_id]);
/* If the child is already in another region, error out */
if ((true ==
valid_region_id(
parent_module,
configurable_child_regions_[parent_module][config_child_id])) &&
if ((true == valid_region_id(
parent_module,
physical_configurable_child_regions_[parent_module]
[config_child_id])) &&
(config_region !=
configurable_child_regions_[parent_module][config_child_id])) {
physical_configurable_child_regions_[parent_module][config_child_id])) {
VTR_LOGF_ERROR(
__FILE__, __LINE__,
"Try to add a configurable child '%s[%lu]' to region '%lu' which is "
"already added to another region '%lu'!\n",
module_name(child_module).c_str(), child_instance, size_t(config_region),
size_t(configurable_child_regions_[parent_module][config_child_id]));
size_t(
physical_configurable_child_regions_[parent_module][config_child_id]));
exit(1);
}
@ -1299,10 +1458,15 @@ ModuleId ModuleManager::create_wrapper_module(
void ModuleManager::clear_configurable_children(const ModuleId& parent_module) {
VTR_ASSERT(valid_module_id(parent_module));
configurable_children_[parent_module].clear();
configurable_child_instances_[parent_module].clear();
configurable_child_regions_[parent_module].clear();
configurable_child_coordinates_[parent_module].clear();
logical_configurable_children_[parent_module].clear();
logical_configurable_child_instances_[parent_module].clear();
physical_configurable_children_[parent_module].clear();
physical_configurable_child_instances_[parent_module].clear();
physical_configurable_child_regions_[parent_module].clear();
physical_configurable_child_coordinates_[parent_module].clear();
logical2physical_configurable_children_[parent_module].clear();
logical2physical_configurable_child_instance_names_[parent_module].clear();
}
void ModuleManager::clear_config_region(const ModuleId& parent_module) {

View File

@ -53,8 +53,9 @@ class ModuleManager {
* port should be applied to modules
*/
enum e_module_usage_type {
MODULE_TOP, /* Top-level module */
MODULE_CONFIG, /* Configuration modules, i.e., decoders, sram etc. */
MODULE_TOP, /* Top-level module */
MODULE_CONFIG, /* Configuration modules, i.e., decoders, sram etc. */
MODULE_CONFIG_GROUP, /* Configuration modules, i.e., decoders, sram etc. */
MODULE_INTERC, /* Programmable interconnection, e.g., routing multiplexer
etc. */
MODULE_GRID, /* Grids (programmable blocks) */
@ -68,6 +69,15 @@ class ModuleManager {
NUM_MODULE_USAGE_TYPES
};
/* Type of configurable child:
* - logical: represent a logical configurable block, which may not contain a
* physical memory inside
* - physical: represent a physical configurable block, which contains a
* physical memory inside
* - unified: a unified block whose physical memory is also the logical memory
*/
enum class e_config_child_type { LOGICAL, PHYSICAL, UNIFIED, NUM_TYPES };
public: /* Public Constructors */
public: /* Type implementations */
/*
@ -156,6 +166,11 @@ class ModuleManager {
public: /* Public aggregators */
/* Find all the modules */
module_range modules() const;
/** @brief find all the modules with a given usage. Note that this function is
* not optimized when the number of modules are large. In most cases, the
* number of modules are fairly small (less than 10k). */
std::vector<ModuleId> modules_by_usage(
const ModuleManager::e_module_usage_type& usage) const;
/* Find all the ports belonging to a module */
module_port_range module_ports(const ModuleId& module) const;
/* Find all the nets belonging to a module */
@ -167,14 +182,27 @@ class ModuleManager {
const ModuleId& parent_module, const ModuleId& child_module) const;
/* Find all the configurable child modules under a parent module */
std::vector<ModuleId> configurable_children(
const ModuleId& parent_module) const;
const ModuleId& parent_module, const e_config_child_type& type) const;
/* Find all the instances of configurable child modules under a parent module
*/
std::vector<size_t> configurable_child_instances(
const ModuleId& parent_module) const;
const ModuleId& parent_module, const e_config_child_type& type) const;
/* Find the coordindate of a configurable child module under a parent module
*/
std::vector<vtr::Point<int>> configurable_child_coordinates(
const ModuleId& parent_module, const e_config_child_type& type) const;
/* Find all the configurable child modules under a parent module
* Note that a physical configurable child module may be at
* another module; Only the logical child module is under the current parent
* module
*/
std::vector<ModuleId> logical2physical_configurable_children(
const ModuleId& parent_module) const;
/* Find all the instance names of configurable child modules under a parent
* module
*/
std::vector<std::string> logical2physical_configurable_child_instance_names(
const ModuleId& parent_module) const;
/* Find all the I/O child modules under a parent module */
@ -195,16 +223,17 @@ class ModuleManager {
/* Find all the regions */
region_range regions(const ModuleId& module) const;
/* Find all the configurable child modules under a region of a parent module
* Note that we use logical children here
*/
std::vector<ModuleId> region_configurable_children(
const ModuleId& parent_module, const ConfigRegionId& region) const;
/* Find all the instances of configurable child modules under a region of a
* parent module */
* parent module; Note that we use logical children here */
std::vector<size_t> region_configurable_child_instances(
const ModuleId& parent_module, const ConfigRegionId& region) const;
/* Find all the coordinates of configurable child modules under a region of a
* parent module */
* parent module; Note that we use logical children here */
std::vector<vtr::Point<int>> region_configurable_child_coordinates(
const ModuleId& parent_module, const ConfigRegionId& region) const;
@ -238,6 +267,9 @@ class ModuleManager {
size_t instance_id(const ModuleId& parent_module,
const ModuleId& child_module,
const std::string& instance_name) const;
/** @brief Count the number of logical configurable children */
size_t num_configurable_children(const ModuleId& parent_module,
const e_config_child_type& type) const;
/* Find the type of a port */
ModuleManager::e_module_port_type port_type(const ModuleId& module,
const ModulePortId& port) const;
@ -295,6 +327,11 @@ class ModuleManager {
const ModuleId& sink_module, const size_t& instance_id,
const ModulePortId& sink_port, const size_t& sink_pin);
/** @brief Check if the configurable children under a given module are unified
* or not. If unified, it means that the logical configurable children are the
* same as the physical configurable children */
bool unified_configurable_children(const ModuleId& curr_module) const;
private: /* Private accessors */
size_t find_child_module_index_in_parent_module(
const ModuleId& parent_module, const ModuleId& child_module) const;
@ -357,18 +394,29 @@ class ModuleManager {
*/
void add_configurable_child(
const ModuleId& module, const ModuleId& child_module,
const size_t& child_instance,
const size_t& child_instance, const e_config_child_type& type,
const vtr::Point<int> coord = vtr::Point<int>(-1, -1));
/** @brief Create a pair of mapping from a logical configurable child to a
* physical configurable child */
void set_logical2physical_configurable_child(
const ModuleId& parent_module, const size_t& logical_child_id,
const ModuleId& physical_child_module);
/** @brief Create a pair of mapping from a logical configurable child to a
* physical configurable child */
void set_logical2physical_configurable_child_instance_name(
const ModuleId& parent_module, const size_t& logical_child_id,
const std::string& physical_child_instance_name);
/* Reserved a number of configurable children for memory efficiency */
void reserve_configurable_child(const ModuleId& module,
const size_t& num_children);
const size_t& num_children,
const e_config_child_type& type);
/* Create a new configurable region under a module */
ConfigRegionId add_config_region(const ModuleId& module);
/* Add a configurable child module to a region
* Note:
* - The child module must be added as a configurable child to the parent
* module before calling this function!
* - The child module must be added as a physical configurable child to the
* parent module before calling this function!
*/
void add_configurable_child_to_region(const ModuleId& parent_module,
const ConfigRegionId& config_region,
@ -511,23 +559,48 @@ class ModuleManager {
* is configured first, etc. Note that the sequence can be totally different
* from the children_ list This is really dependent how the configuration
* protocol is organized which should be made by users/designers
* Note that there could be two types of configurable children under a module
* - logical: only contains virtual/feedthough memory blocks. A logical
* configurable child can only contain logical subchild. Logical memory block
* is required for architecture bitstream generation, because it carries
* logical information (the location of memory to its programmable resources)
* - physical: contains physical memory blocks. Logical memory blocks are
* mapped to the physical memory block. A physical memory block may contain
* coordinates and configuration regions which are required for fabric
* bitstream generation.
*/
vtr::vector<ModuleId, std::vector<ModuleId>>
configurable_children_; /* Child modules with configurable memory bits that
this module contain */
logical_configurable_children_; /* Child modules with configurable memory
bits that this module contain */
vtr::vector<ModuleId, std::vector<size_t>>
configurable_child_instances_; /* Instances of child modules with
logical_configurable_child_instances_; /* Instances of child modules with
configurable memory bits that this module
contain */
vtr::vector<ModuleId, std::vector<ModuleId>>
logical2physical_configurable_children_; /* Child modules with configurable
memory bits that this module contain */
vtr::vector<ModuleId, std::vector<std::string>>
logical2physical_configurable_child_instance_names_; /* Instances of child
modules with configurable memory bits that
this module contain */
vtr::vector<ModuleId, std::vector<ModuleId>>
physical_configurable_children_; /* Child modules with configurable memory
bits that this module contain */
vtr::vector<ModuleId, std::vector<size_t>>
physical_configurable_child_instances_; /* Instances of child modules with
configurable memory bits that this module
contain */
vtr::vector<ModuleId, std::vector<ConfigRegionId>>
configurable_child_regions_; /* Instances of child modules with configurable
memory bits that this module contain */
physical_configurable_child_regions_; /* Instances of child modules with
configurable memory bits that this module
contain */
vtr::vector<ModuleId, std::vector<vtr::Point<int>>>
configurable_child_coordinates_; /* Relative coorindates of child modules
with configurable memory bits that this
module contain */
physical_configurable_child_coordinates_; /* Relative coorindates of child
modules with configurable memory bits
that this module contain */
/* Configurable regions to group the configurable children
/* Configurable regions to group the physical configurable children
* Note:
* - Each child can only be added a group
*/

View File

@ -35,15 +35,19 @@ static size_t rec_estimate_device_bitstream_num_blocks(
* actually configurable memory elements
* We skip them in couting
*/
if (0 == module_manager.configurable_children(top_module).size()) {
if (0 == module_manager.num_configurable_children(
top_module, ModuleManager::e_config_child_type::PHYSICAL)) {
return 0;
}
size_t num_configurable_children =
module_manager.configurable_children(top_module).size();
module_manager
.configurable_children(top_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size();
for (size_t ichild = 0; ichild < num_configurable_children; ++ichild) {
ModuleId child_module =
module_manager.configurable_children(top_module)[ichild];
ModuleId child_module = module_manager.configurable_children(
top_module, ModuleManager::e_config_child_type::PHYSICAL)[ichild];
num_blocks +=
rec_estimate_device_bitstream_num_blocks(module_manager, child_module);
}
@ -68,7 +72,8 @@ static size_t rec_estimate_device_bitstream_num_bits(
/* If a child module has no configurable children, this is a leaf node
* We can count it in. Otherwise, we should go recursively.
*/
if (0 == module_manager.configurable_children(parent_module).size()) {
if (0 == module_manager.num_configurable_children(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)) {
return 1;
}
@ -105,7 +110,10 @@ static size_t rec_estimate_device_bitstream_num_bits(
VTR_ASSERT_SAFE(parent_module != top_module);
size_t num_configurable_children =
module_manager.configurable_children(parent_module).size();
module_manager
.configurable_children(parent_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size();
/* Frame-based configuration protocol will have 1 decoder
* if there are more than 1 configurable children
@ -116,8 +124,8 @@ static size_t rec_estimate_device_bitstream_num_bits(
}
for (size_t ichild = 0; ichild < num_configurable_children; ++ichild) {
ModuleId child_module =
module_manager.configurable_children(parent_module)[ichild];
ModuleId child_module = module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)[ichild];
num_bits += rec_estimate_device_bitstream_num_bits(
module_manager, top_module, child_module, config_protocol);
}
@ -193,7 +201,8 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
/* Reserve child blocks for the top level block */
bitstream_manager.reserve_child_blocks(
top_block, count_module_manager_module_configurable_children(
openfpga_ctx.module_graph(), top_module));
openfpga_ctx.module_graph(), top_module,
ModuleManager::e_config_child_type::PHYSICAL));
/* Create bitstream from grids */
VTR_LOGV(verbose, "Building grid bitstream...\n");

View File

@ -74,12 +74,17 @@ static void rec_build_module_fabric_dependent_chain_bitstream(
} else {
for (size_t child_id = 0;
child_id <
module_manager.configurable_children(parent_module).size();
module_manager
.configurable_children(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)
.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];
ModuleId child_module = module_manager.configurable_children(
parent_module,
ModuleManager::e_config_child_type::PHYSICAL)[child_id];
size_t child_instance = module_manager.configurable_child_instances(
parent_module,
ModuleManager::e_config_child_type::PHYSICAL)[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);
@ -196,7 +201,8 @@ static void rec_build_module_fabric_dependent_memory_bank_bitstream(
* - no need to exclude decoders as they are not there
*/
std::vector<ModuleId> configurable_children =
module_manager.configurable_children(parent_module);
module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::PHYSICAL);
size_t num_configurable_children = configurable_children.size();
@ -211,8 +217,9 @@ static void rec_build_module_fabric_dependent_memory_bank_bitstream(
for (size_t child_id = 0; child_id < num_configurable_children;
++child_id) {
ModuleId child_module = configurable_children[child_id];
size_t child_instance =
module_manager.configurable_child_instances(parent_module)[child_id];
size_t child_instance = module_manager.configurable_child_instances(
parent_module,
ModuleManager::e_config_child_type::PHYSICAL)[child_id];
/* Get the instance name and ensure it is not empty */
std::string instance_name = module_manager.instance_name(
@ -323,10 +330,11 @@ static void rec_build_module_fabric_dependent_frame_bitstream(
config_region);
} else {
VTR_ASSERT(top_module != parent_module);
configurable_children =
module_manager.configurable_children(parent_module);
configurable_children = module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::PHYSICAL);
configurable_child_instances =
module_manager.configurable_child_instances(parent_module);
module_manager.configurable_child_instances(
parent_module, ModuleManager::e_config_child_type::PHYSICAL);
}
size_t num_configurable_children = configurable_children.size();
@ -360,10 +368,13 @@ static void rec_build_module_fabric_dependent_frame_bitstream(
/* The max address code size is the max address code size of all the
* configurable children in all the regions
*/
for (const ModuleId& child_module :
module_manager.configurable_children(parent_module)) {
for (const ModuleId& child_module : module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)) {
/* Bypass any decoder module (which no configurable children */
if (module_manager.configurable_children(child_module).empty()) {
if (module_manager
.configurable_children(
child_module, ModuleManager::e_config_child_type::PHYSICAL)
.empty()) {
continue;
}
const ModulePortId& child_addr_port_id =
@ -493,8 +504,8 @@ static void rec_build_module_fabric_dependent_frame_bitstream(
parent_modules.back(), config_region);
} else {
VTR_ASSERT(top_module != parent_modules.back());
configurable_children =
module_manager.configurable_children(parent_modules.back());
configurable_children = module_manager.configurable_children(
parent_modules.back(), ModuleManager::e_config_child_type::PHYSICAL);
}
ModuleId decoder_module = configurable_children.back();

View File

@ -123,7 +123,8 @@ static void rec_build_module_fabric_dependent_ql_memory_bank_regional_bitstream(
* - no need to exclude decoders as they are not there
*/
std::vector<ModuleId> configurable_children =
module_manager.configurable_children(parent_module);
module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::PHYSICAL);
size_t num_configurable_children = configurable_children.size();
@ -138,8 +139,9 @@ static void rec_build_module_fabric_dependent_ql_memory_bank_regional_bitstream(
for (size_t child_id = 0; child_id < num_configurable_children;
++child_id) {
ModuleId child_module = configurable_children[child_id];
size_t child_instance =
module_manager.configurable_child_instances(parent_module)[child_id];
size_t child_instance = module_manager.configurable_child_instances(
parent_module,
ModuleManager::e_config_child_type::PHYSICAL)[child_id];
/* Get the instance name and ensure it is not empty */
std::string instance_name = module_manager.instance_name(

View File

@ -50,10 +50,12 @@ static std::vector<bool> generate_mode_select_bitstream(
*******************************************************************/
static void build_primitive_bitstream(
BitstreamManager& bitstream_manager,
std::map<std::string, size_t>& grouped_mem_inst_scoreboard,
const ConfigBlockId& parent_configurable_block,
const ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
const VprDeviceAnnotation& device_annotation, const PhysicalPb& physical_pb,
const PhysicalPbId& primitive_pb_id, t_pb_type* primitive_pb_type) {
const PhysicalPbId& primitive_pb_id, t_pb_type* primitive_pb_type,
const bool& verbose) {
/* Ensure a valid physical pritimive pb */
if (nullptr == primitive_pb_type) {
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid primitive_pb_type!\n");
@ -131,11 +133,34 @@ static void build_primitive_bitstream(
mode_select_bitstream.size() ==
module_manager.module_port(mem_module, mem_out_port_id).get_width());
/* If there is a feedthrough module, we should consider the scoreboard */
std::string feedthru_mem_block_name =
generate_memory_module_name(circuit_lib, primitive_model, sram_models[0],
std::string(MEMORY_MODULE_POSTFIX), true);
ModuleId feedthru_mem_module =
module_manager.find_module(feedthru_mem_block_name);
if (module_manager.valid_module_id(feedthru_mem_module)) {
auto result = grouped_mem_inst_scoreboard.find(mem_block_name);
if (result == grouped_mem_inst_scoreboard.end()) {
/* Update scoreboard */
grouped_mem_inst_scoreboard[mem_block_name] = 0;
} else {
grouped_mem_inst_scoreboard[mem_block_name]++;
mem_block_name = generate_instance_name(
mem_block_name, grouped_mem_inst_scoreboard[mem_block_name]);
}
}
/* Create a block for the bitstream which corresponds to the memory module
* associated to the LUT */
ConfigBlockId mem_block = bitstream_manager.add_block(mem_block_name);
bitstream_manager.add_child_block(parent_configurable_block, mem_block);
VTR_LOGV(verbose, "Added %lu bits to '%s' under '%s'\n",
mode_select_bitstream.size(),
bitstream_manager.block_name(mem_block).c_str(),
bitstream_manager.block_name(parent_configurable_block).c_str());
/* Add the bitstream to the bitstream manager */
bitstream_manager.add_block_bits(mem_block, mode_select_bitstream);
}
@ -153,13 +178,14 @@ static void build_primitive_bitstream(
*******************************************************************/
static void build_physical_block_pin_interc_bitstream(
BitstreamManager& bitstream_manager,
std::map<std::string, size_t>& grouped_mem_inst_scoreboard,
const ConfigBlockId& parent_configurable_block,
const ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib, const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprBitstreamAnnotation& bitstream_annotation,
const PhysicalPb& physical_pb, t_pb_graph_pin* des_pb_graph_pin,
t_mode* physical_mode) {
t_mode* physical_mode, const bool& verbose) {
/* Identify the number of fan-in (Consider interconnection edges of only
* selected mode) */
t_interconnect* cur_interc =
@ -258,9 +284,6 @@ static void build_physical_block_pin_interc_bitstream(
* physical_block */
std::string mem_block_name = generate_pb_memory_instance_name(
GRID_MEM_INSTANCE_PREFIX, des_pb_graph_pin, std::string(""));
ConfigBlockId mux_mem_block = bitstream_manager.add_block(mem_block_name);
bitstream_manager.add_child_block(parent_configurable_block,
mux_mem_block);
/* Find the module in module manager and ensure the bitstream size
* matches! */
@ -275,6 +298,32 @@ static void build_physical_block_pin_interc_bitstream(
module_manager.module_port(mux_mem_module, mux_mem_out_port_id)
.get_width());
/* If there is a feedthrough module, we should consider the scoreboard */
std::string feedthru_mem_block_name = generate_mux_subckt_name(
circuit_lib, mux_model, datapath_mux_size,
std::string(MEMORY_FEEDTHROUGH_MODULE_POSTFIX));
ModuleId feedthru_mem_module =
module_manager.find_module(feedthru_mem_block_name);
if (module_manager.valid_module_id(feedthru_mem_module)) {
auto result = grouped_mem_inst_scoreboard.find(mem_block_name);
if (result == grouped_mem_inst_scoreboard.end()) {
/* Update scoreboard */
grouped_mem_inst_scoreboard[mem_block_name] = 0;
} else {
grouped_mem_inst_scoreboard[mem_block_name]++;
mem_block_name = generate_instance_name(
mem_block_name, grouped_mem_inst_scoreboard[mem_block_name]);
}
}
ConfigBlockId mux_mem_block = bitstream_manager.add_block(mem_block_name);
bitstream_manager.add_child_block(parent_configurable_block,
mux_mem_block);
VTR_LOGV(verbose, "Added %lu bits to '%s' under '%s'\n",
mux_bitstream.size(),
bitstream_manager.block_name(mux_mem_block).c_str(),
bitstream_manager.block_name(parent_configurable_block).c_str());
/* Add the bistream to the bitstream manager */
bitstream_manager.add_block_bits(mux_mem_block, mux_bitstream);
/* Record path ids, input and output nets */
@ -324,13 +373,15 @@ static void build_physical_block_pin_interc_bitstream(
*******************************************************************/
static void build_physical_block_interc_port_bitstream(
BitstreamManager& bitstream_manager,
std::map<std::string, size_t>& grouped_mem_inst_scoreboard,
const ConfigBlockId& parent_configurable_block,
const ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib, const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprBitstreamAnnotation& bitstream_annotation,
t_pb_graph_node* physical_pb_graph_node, const PhysicalPb& physical_pb,
const e_circuit_pb_port_type& pb_port_type, t_mode* physical_mode) {
const e_circuit_pb_port_type& pb_port_type, t_mode* physical_mode,
const bool& verbose) {
switch (pb_port_type) {
case CIRCUIT_PB_PORT_INPUT:
for (int iport = 0; iport < physical_pb_graph_node->num_input_ports;
@ -338,10 +389,11 @@ static void build_physical_block_interc_port_bitstream(
for (int ipin = 0; ipin < physical_pb_graph_node->num_input_pins[iport];
++ipin) {
build_physical_block_pin_interc_bitstream(
bitstream_manager, parent_configurable_block, module_manager,
circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, physical_pb,
&(physical_pb_graph_node->input_pins[iport][ipin]), physical_mode);
bitstream_manager, grouped_mem_inst_scoreboard,
parent_configurable_block, module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation, bitstream_annotation, physical_pb,
&(physical_pb_graph_node->input_pins[iport][ipin]), physical_mode,
verbose);
}
}
break;
@ -351,10 +403,11 @@ static void build_physical_block_interc_port_bitstream(
for (int ipin = 0;
ipin < physical_pb_graph_node->num_output_pins[iport]; ++ipin) {
build_physical_block_pin_interc_bitstream(
bitstream_manager, parent_configurable_block, module_manager,
circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, physical_pb,
&(physical_pb_graph_node->output_pins[iport][ipin]), physical_mode);
bitstream_manager, grouped_mem_inst_scoreboard,
parent_configurable_block, module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation, bitstream_annotation, physical_pb,
&(physical_pb_graph_node->output_pins[iport][ipin]), physical_mode,
verbose);
}
}
break;
@ -364,10 +417,11 @@ static void build_physical_block_interc_port_bitstream(
for (int ipin = 0; ipin < physical_pb_graph_node->num_clock_pins[iport];
++ipin) {
build_physical_block_pin_interc_bitstream(
bitstream_manager, parent_configurable_block, module_manager,
circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, physical_pb,
&(physical_pb_graph_node->clock_pins[iport][ipin]), physical_mode);
bitstream_manager, grouped_mem_inst_scoreboard,
parent_configurable_block, module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation, bitstream_annotation, physical_pb,
&(physical_pb_graph_node->clock_pins[iport][ipin]), physical_mode,
verbose);
}
}
break;
@ -383,13 +437,14 @@ static void build_physical_block_interc_port_bitstream(
*******************************************************************/
static void build_physical_block_interc_bitstream(
BitstreamManager& bitstream_manager,
std::map<std::string, size_t>& grouped_mem_inst_scoreboard,
const ConfigBlockId& parent_configurable_block,
const ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib, const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprBitstreamAnnotation& bitstream_annotation,
t_pb_graph_node* physical_pb_graph_node, const PhysicalPb& physical_pb,
t_mode* physical_mode) {
t_mode* physical_mode, const bool& verbose) {
/* Check if the pb_graph node is valid or not */
if (nullptr == physical_pb_graph_node) {
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid physical_pb_graph_node.\n");
@ -407,9 +462,10 @@ static void build_physical_block_interc_bitstream(
* Note: it is not applied to primitive pb_type!
*/
build_physical_block_interc_port_bitstream(
bitstream_manager, parent_configurable_block, module_manager, circuit_lib,
mux_lib, atom_ctx, device_annotation, bitstream_annotation,
physical_pb_graph_node, physical_pb, CIRCUIT_PB_PORT_OUTPUT, physical_mode);
bitstream_manager, grouped_mem_inst_scoreboard, parent_configurable_block,
module_manager, circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, physical_pb_graph_node, physical_pb,
CIRCUIT_PB_PORT_OUTPUT, physical_mode, verbose);
/* We check input_pins of child_pb_graph_node and its the input_edges
* Iterate over the interconnections between inputs of physical_pb_graph_node
@ -429,14 +485,16 @@ static void build_physical_block_interc_bitstream(
/* For each child_pb_graph_node input pins*/
build_physical_block_interc_port_bitstream(
bitstream_manager, parent_configurable_block, module_manager,
circuit_lib, mux_lib, atom_ctx, device_annotation, bitstream_annotation,
child_pb_graph_node, physical_pb, CIRCUIT_PB_PORT_INPUT, physical_mode);
bitstream_manager, grouped_mem_inst_scoreboard,
parent_configurable_block, module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation, bitstream_annotation, child_pb_graph_node,
physical_pb, CIRCUIT_PB_PORT_INPUT, physical_mode, verbose);
/* For clock pins, we should do the same work */
build_physical_block_interc_port_bitstream(
bitstream_manager, parent_configurable_block, module_manager,
circuit_lib, mux_lib, atom_ctx, device_annotation, bitstream_annotation,
child_pb_graph_node, physical_pb, CIRCUIT_PB_PORT_CLOCK, physical_mode);
bitstream_manager, grouped_mem_inst_scoreboard,
parent_configurable_block, module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation, bitstream_annotation, child_pb_graph_node,
physical_pb, CIRCUIT_PB_PORT_CLOCK, physical_mode, verbose);
}
}
}
@ -445,15 +503,14 @@ static void build_physical_block_interc_bitstream(
* Generate bitstream for a LUT and add it to bitstream manager
* This function supports both single-output and fracturable LUTs
*******************************************************************/
static void build_lut_bitstream(BitstreamManager& bitstream_manager,
const ConfigBlockId& parent_configurable_block,
const VprDeviceAnnotation& device_annotation,
const ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib,
const PhysicalPb& physical_pb,
const PhysicalPbId& lut_pb_id,
t_pb_type* lut_pb_type) {
static void build_lut_bitstream(
BitstreamManager& bitstream_manager,
std::map<std::string, size_t>& grouped_mem_inst_scoreboard,
const ConfigBlockId& parent_configurable_block,
const VprDeviceAnnotation& device_annotation,
const ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib, const PhysicalPb& physical_pb,
const PhysicalPbId& lut_pb_id, t_pb_type* lut_pb_type, const bool& verbose) {
/* Ensure a valid physical pritimive pb */
if (nullptr == lut_pb_type) {
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid lut_pb_type!\n");
@ -594,11 +651,33 @@ static void build_lut_bitstream(BitstreamManager& bitstream_manager,
lut_bitstream.size() ==
module_manager.module_port(mem_module, mem_out_port_id).get_width());
/* If there is a feedthrough module, we should consider the scoreboard */
std::string feedthru_mem_block_name =
generate_memory_module_name(circuit_lib, lut_model, sram_models[0],
std::string(MEMORY_MODULE_POSTFIX), true);
ModuleId feedthru_mem_module =
module_manager.find_module(feedthru_mem_block_name);
if (module_manager.valid_module_id(feedthru_mem_module)) {
auto result = grouped_mem_inst_scoreboard.find(mem_block_name);
if (result == grouped_mem_inst_scoreboard.end()) {
/* Update scoreboard */
grouped_mem_inst_scoreboard[mem_block_name] = 0;
} else {
grouped_mem_inst_scoreboard[mem_block_name]++;
mem_block_name = generate_instance_name(
mem_block_name, grouped_mem_inst_scoreboard[mem_block_name]);
}
}
/* Create a block for the bitstream which corresponds to the memory module
* associated to the LUT */
ConfigBlockId mem_block = bitstream_manager.add_block(mem_block_name);
bitstream_manager.add_child_block(parent_configurable_block, mem_block);
VTR_LOGV(verbose, "Added %lu bits to '%s' under '%s'\n", lut_bitstream.size(),
bitstream_manager.block_name(mem_block).c_str(),
bitstream_manager.block_name(parent_configurable_block).c_str());
/* Add the bitstream to the bitstream manager */
bitstream_manager.add_block_bits(mem_block, lut_bitstream);
}
@ -616,13 +695,15 @@ static void build_lut_bitstream(BitstreamManager& bitstream_manager,
*******************************************************************/
static void rec_build_physical_block_bitstream(
BitstreamManager& bitstream_manager,
std::map<std::string, size_t>& grouped_mem_inst_scoreboard,
const ConfigBlockId& parent_configurable_block,
const ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
const MuxLibrary& mux_lib, const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprBitstreamAnnotation& bitstream_annotation, const e_side& border_side,
const PhysicalPb& physical_pb, const PhysicalPbId& pb_id,
t_pb_graph_node* physical_pb_graph_node, const size_t& pb_graph_node_index) {
t_pb_graph_node* physical_pb_graph_node, const size_t& pb_graph_node_index,
const bool& verbose) {
/* Get the physical pb_type that is linked to the pb_graph node */
t_pb_type* physical_pb_type = physical_pb_graph_node->pb_type;
@ -636,7 +717,8 @@ static void rec_build_physical_block_bitstream(
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()) {
if (0 == module_manager.num_configurable_children(
pb_module, ModuleManager::e_config_child_type::LOGICAL)) {
return;
}
@ -644,16 +726,21 @@ static void rec_build_physical_block_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));
/* If there are no physical memory blocks under the current module, use the
* previous module, which is the physical memory block */
ConfigBlockId pb_configurable_block = parent_configurable_block;
if (0 < module_manager.num_configurable_children(
pb_module, ModuleManager::e_config_child_type::PHYSICAL)) {
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,
ModuleManager::e_config_child_type::PHYSICAL));
}
/* Recursively finish all the child pb_types*/
if (false == is_primitive_pb_type(physical_pb_type)) {
@ -670,12 +757,12 @@ static void rec_build_physical_block_bitstream(
}
/* Go recursively */
rec_build_physical_block_bitstream(
bitstream_manager, pb_configurable_block, module_manager, circuit_lib,
mux_lib, atom_ctx, device_annotation, bitstream_annotation,
border_side, physical_pb, child_pb,
bitstream_manager, grouped_mem_inst_scoreboard, pb_configurable_block,
module_manager, circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, border_side, physical_pb, child_pb,
&(physical_pb_graph_node
->child_pb_graph_nodes[physical_mode->index][ipb][jpb]),
jpb);
jpb, verbose);
}
}
}
@ -690,17 +777,19 @@ static void rec_build_physical_block_bitstream(
/* Special case for LUT !!!
* Mapped logical block information is stored in child_pbs of this pb!!!
*/
build_lut_bitstream(bitstream_manager, pb_configurable_block,
device_annotation, module_manager, circuit_lib,
mux_lib, physical_pb, pb_id, physical_pb_type);
build_lut_bitstream(bitstream_manager, grouped_mem_inst_scoreboard,
pb_configurable_block, device_annotation,
module_manager, circuit_lib, mux_lib, physical_pb,
pb_id, physical_pb_type, verbose);
break;
case CIRCUIT_MODEL_FF:
case CIRCUIT_MODEL_HARDLOGIC:
case CIRCUIT_MODEL_IOPAD:
/* For other types of blocks, we can apply a generic therapy */
build_primitive_bitstream(
bitstream_manager, pb_configurable_block, module_manager, circuit_lib,
device_annotation, physical_pb, pb_id, physical_pb_type);
bitstream_manager, grouped_mem_inst_scoreboard, pb_configurable_block,
module_manager, circuit_lib, device_annotation, physical_pb, pb_id,
physical_pb_type, verbose);
break;
default:
VTR_LOGF_ERROR(__FILE__, __LINE__,
@ -714,9 +803,10 @@ static void rec_build_physical_block_bitstream(
/* Generate the bitstream for the interconnection in this physical block */
build_physical_block_interc_bitstream(
bitstream_manager, pb_configurable_block, module_manager, circuit_lib,
mux_lib, atom_ctx, device_annotation, bitstream_annotation,
physical_pb_graph_node, physical_pb, physical_mode);
bitstream_manager, grouped_mem_inst_scoreboard, pb_configurable_block,
module_manager, circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, physical_pb_graph_node, physical_pb, physical_mode,
verbose);
}
/********************************************************************
@ -734,7 +824,8 @@ static void build_physical_block_bitstream(
const VprClusteringAnnotation& cluster_annotation,
const VprPlacementAnnotation& place_annotation,
const VprBitstreamAnnotation& bitstream_annotation, const DeviceGrid& grids,
const vtr::Point<size_t>& grid_coord, const e_side& border_side) {
const vtr::Point<size_t>& grid_coord, const e_side& border_side,
const bool& verbose) {
/* Create a block for the grid in bitstream manager */
t_physical_tile_type_ptr grid_type =
grids.get_physical_type(grid_coord.x(), grid_coord.y());
@ -748,7 +839,8 @@ static void build_physical_block_bitstream(
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()) {
if (0 == module_manager.num_configurable_children(
grid_module, ModuleManager::e_config_child_type::LOGICAL)) {
return;
}
@ -770,7 +862,33 @@ static void build_physical_block_bitstream(
/* 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));
module_manager, grid_module,
ModuleManager::e_config_child_type::PHYSICAL));
/* Create a dedicated block for the non-unified configurable child */
if (!module_manager.unified_configurable_children(grid_module)) {
VTR_ASSERT(1 ==
module_manager
.configurable_children(
grid_module, ModuleManager::e_config_child_type::PHYSICAL)
.size());
std::string phy_mem_instance_name = module_manager.instance_name(
grid_module,
module_manager.configurable_children(
grid_module, ModuleManager::e_config_child_type::PHYSICAL)[0],
module_manager.configurable_child_instances(
grid_module, ModuleManager::e_config_child_type::PHYSICAL)[0]);
ConfigBlockId grid_grouped_config_block =
bitstream_manager.add_block(phy_mem_instance_name);
VTR_LOGV(
verbose,
"Added grouped configurable memory block '%s' as a child to '%s'\n",
bitstream_manager.block_name(grid_grouped_config_block).c_str(),
bitstream_manager.block_name(grid_configurable_block).c_str());
bitstream_manager.add_child_block(grid_configurable_block,
grid_grouped_config_block);
grid_configurable_block = grid_grouped_config_block;
}
/* Iterate over the capacity of the grid
* Now each physical tile may have a number of logical blocks
@ -780,6 +898,7 @@ static void build_physical_block_bitstream(
* If you need different equivalent sites, you can always define
* it as a mode under a <pb_type>
*/
std::map<std::string, size_t> grouped_mem_inst_scoreboard;
for (size_t z = 0; z < place_annotation.grid_blocks(grid_coord).size(); ++z) {
int sub_tile_index =
device_annotation.physical_tile_z_to_subtile_index(grid_type, z);
@ -796,10 +915,11 @@ static void build_physical_block_bitstream(
place_annotation.grid_blocks(grid_coord)[z]) {
/* Recursively traverse the pb_graph and generate bitstream */
rec_build_physical_block_bitstream(
bitstream_manager, grid_configurable_block, module_manager,
circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, border_side, PhysicalPb(),
PhysicalPbId::INVALID(), lb_type->pb_graph_head, z);
bitstream_manager, grouped_mem_inst_scoreboard,
grid_configurable_block, module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation, bitstream_annotation, border_side,
PhysicalPb(), PhysicalPbId::INVALID(), lb_type->pb_graph_head, z,
verbose);
} else {
const PhysicalPb& phy_pb = cluster_annotation.physical_pb(
place_annotation.grid_blocks(grid_coord)[z]);
@ -811,10 +931,10 @@ static void build_physical_block_bitstream(
/* Recursively traverse the pb_graph and generate bitstream */
rec_build_physical_block_bitstream(
bitstream_manager, grid_configurable_block, module_manager,
circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, border_side, phy_pb, top_pb_id, pb_graph_head,
z);
bitstream_manager, grouped_mem_inst_scoreboard,
grid_configurable_block, module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation, bitstream_annotation, border_side,
phy_pb, top_pb_id, pb_graph_head, z, verbose);
}
}
}
@ -873,7 +993,8 @@ void build_grid_bitstream(
build_physical_block_bitstream(
bitstream_manager, parent_block, module_manager, fabric_tile, curr_tile,
circuit_lib, mux_lib, atom_ctx, device_annotation, cluster_annotation,
place_annotation, bitstream_annotation, grids, grid_coord, NUM_SIDES);
place_annotation, bitstream_annotation, grids, grid_coord, NUM_SIDES,
verbose);
}
}
VTR_LOGV(verbose, "Done\n");
@ -919,7 +1040,8 @@ void build_grid_bitstream(
build_physical_block_bitstream(
bitstream_manager, parent_block, module_manager, fabric_tile, curr_tile,
circuit_lib, mux_lib, atom_ctx, device_annotation, cluster_annotation,
place_annotation, bitstream_annotation, grids, io_coordinate, io_side);
place_annotation, bitstream_annotation, grids, io_coordinate, io_side,
verbose);
}
}
VTR_LOGV(verbose, "Done\n");

View File

@ -37,7 +37,7 @@ static void build_switch_block_mux_bitstream(
const MuxLibrary& mux_lib, const RRGraphView& rr_graph,
const RRNodeId& cur_rr_node, const std::vector<RRNodeId>& drive_rr_nodes,
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation) {
const VprRoutingAnnotation& routing_annotation, const bool& verbose) {
/* Check current rr_node is CHANX or CHANY*/
VTR_ASSERT((CHANX == rr_graph.node_type(cur_rr_node)) ||
(CHANY == rr_graph.node_type(cur_rr_node)));
@ -102,6 +102,12 @@ static void build_switch_block_mux_bitstream(
module_manager.module_port(mux_mem_module, mux_mem_out_port_id)
.get_width());
VTR_LOGV(
verbose, "Added %lu bits to '%s' under '%s'\n", mux_bitstream.size(),
bitstream_manager.block_name(mux_mem_block).c_str(),
bitstream_manager.block_name(bitstream_manager.block_parent(mux_mem_block))
.c_str());
/* Add the bistream to the bitstream manager */
bitstream_manager.add_block_bits(mux_mem_block, mux_bitstream);
/* Record path ids, input and output nets */
@ -150,7 +156,7 @@ static void build_switch_block_interc_bitstream(
const MuxLibrary& mux_lib, const RRGraphView& rr_graph,
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation, const RRGSB& rr_gsb,
const e_side& chan_side, const size_t& chan_node_id) {
const e_side& chan_side, const size_t& chan_node_id, const bool& verbose) {
std::vector<RRNodeId> driver_rr_nodes;
/* Get the node */
@ -179,11 +185,14 @@ static void build_switch_block_interc_bitstream(
std::string(""));
ConfigBlockId mux_mem_block = bitstream_manager.add_block(mem_block_name);
bitstream_manager.add_child_block(sb_configurable_block, mux_mem_block);
VTR_LOGV(verbose, "Added '%s' under '%s'\n",
bitstream_manager.block_name(mux_mem_block).c_str(),
bitstream_manager.block_name(sb_configurable_block).c_str());
/* This is a routing multiplexer! Generate bitstream */
build_switch_block_mux_bitstream(
bitstream_manager, mux_mem_block, module_manager, circuit_lib, mux_lib,
rr_graph, cur_rr_node, driver_rr_nodes, atom_ctx, device_annotation,
routing_annotation);
routing_annotation, verbose);
} /*Nothing should be done else*/
}
@ -204,7 +213,7 @@ static void build_switch_block_bitstream(
const MuxLibrary& mux_lib, const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph,
const RRGSB& rr_gsb) {
const RRGSB& rr_gsb, const bool& verbose) {
/* Iterate over all the multiplexers */
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
SideManager side_manager(side);
@ -222,7 +231,7 @@ static void build_switch_block_bitstream(
build_switch_block_interc_bitstream(
bitstream_manager, sb_config_block, module_manager, circuit_lib,
mux_lib, rr_graph, atom_ctx, device_annotation, routing_annotation,
rr_gsb, side_manager.get_side(), itrack);
rr_gsb, side_manager.get_side(), itrack, verbose);
}
}
}
@ -240,7 +249,8 @@ static void build_connection_block_mux_bitstream(
const MuxLibrary& mux_lib, const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph,
const RRGSB& rr_gsb, const e_side& cb_ipin_side, const size_t& ipin_index) {
const RRGSB& rr_gsb, const e_side& cb_ipin_side, const size_t& ipin_index,
const bool& verbose) {
RRNodeId src_rr_node = rr_gsb.get_ipin_node(cb_ipin_side, ipin_index);
/* Find drive_rr_nodes*/
std::vector<RREdgeId> driver_rr_edges =
@ -308,6 +318,12 @@ static void build_connection_block_mux_bitstream(
module_manager.module_port(mux_mem_module, mux_mem_out_port_id)
.get_width());
VTR_LOGV(
verbose, "Added %lu bits to '%s' under '%s'\n", mux_bitstream.size(),
bitstream_manager.block_name(mux_mem_block).c_str(),
bitstream_manager.block_name(bitstream_manager.block_parent(mux_mem_block))
.c_str());
/* Add the bistream to the bitstream manager */
bitstream_manager.add_block_bits(mux_mem_block, mux_bitstream);
/* Record path ids, input and output nets */
@ -381,11 +397,14 @@ static void build_connection_block_interc_bitstream(
std::string(""));
ConfigBlockId mux_mem_block = bitstream_manager.add_block(mem_block_name);
bitstream_manager.add_child_block(cb_configurable_block, mux_mem_block);
VTR_LOGV(verbose, "Added '%s' under '%s'\n",
bitstream_manager.block_name(mux_mem_block).c_str(),
bitstream_manager.block_name(cb_configurable_block).c_str());
/* This is a routing multiplexer! Generate bitstream */
build_connection_block_mux_bitstream(
bitstream_manager, mux_mem_block, module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation, routing_annotation, rr_graph, rr_gsb,
cb_ipin_side, ipin_index);
cb_ipin_side, ipin_index, verbose);
} /*Nothing should be done else*/
}
@ -486,8 +505,12 @@ static void build_connection_block_bitstreams(
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)) {
if (0 == count_module_manager_module_configurable_children(
module_manager, cb_module,
ModuleManager::e_config_child_type::LOGICAL) &&
0 == count_module_manager_module_configurable_children(
module_manager, cb_module,
ModuleManager::e_config_child_type::PHYSICAL)) {
continue;
}
@ -527,8 +550,32 @@ static void build_connection_block_bitstreams(
/* 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));
count_module_manager_module_configurable_children(
module_manager, cb_module,
ModuleManager::e_config_child_type::PHYSICAL));
/* Create a dedicated block for the non-unified configurable child */
if (!module_manager.unified_configurable_children(cb_module)) {
VTR_ASSERT(1 ==
module_manager
.configurable_children(
cb_module, ModuleManager::e_config_child_type::PHYSICAL)
.size());
std::string phy_mem_instance_name = module_manager.instance_name(
cb_module,
module_manager.configurable_children(
cb_module, ModuleManager::e_config_child_type::PHYSICAL)[0],
module_manager.configurable_child_instances(
cb_module, ModuleManager::e_config_child_type::PHYSICAL)[0]);
ConfigBlockId cb_grouped_config_block =
bitstream_manager.add_block(phy_mem_instance_name);
bitstream_manager.add_child_block(cb_configurable_block,
cb_grouped_config_block);
VTR_LOGV(verbose, "Added '%s' as a child to '%s'\n",
bitstream_manager.block_name(cb_grouped_config_block).c_str(),
bitstream_manager.block_name(cb_configurable_block).c_str());
cb_configurable_block = cb_grouped_config_block;
}
build_connection_block_bitstream(
bitstream_manager, cb_configurable_block, module_manager, circuit_lib,
@ -593,8 +640,12 @@ void build_routing_bitstream(
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)) {
if (0 == count_module_manager_module_configurable_children(
module_manager, sb_module,
ModuleManager::e_config_child_type::LOGICAL) &&
0 == count_module_manager_module_configurable_children(
module_manager, sb_module,
ModuleManager::e_config_child_type::PHYSICAL)) {
continue;
}
@ -629,13 +680,37 @@ void build_routing_bitstream(
/* 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));
count_module_manager_module_configurable_children(
module_manager, sb_module,
ModuleManager::e_config_child_type::PHYSICAL));
build_switch_block_bitstream(bitstream_manager, sb_configurable_block,
module_manager, circuit_lib, mux_lib,
atom_ctx, device_annotation,
routing_annotation, rr_graph, rr_gsb);
/* Create a dedicated block for the non-unified configurable child */
if (!module_manager.unified_configurable_children(sb_module)) {
VTR_ASSERT(1 ==
module_manager
.configurable_children(
sb_module, ModuleManager::e_config_child_type::PHYSICAL)
.size());
std::string phy_mem_instance_name = module_manager.instance_name(
sb_module,
module_manager.configurable_children(
sb_module, ModuleManager::e_config_child_type::PHYSICAL)[0],
module_manager.configurable_child_instances(
sb_module, ModuleManager::e_config_child_type::PHYSICAL)[0]);
ConfigBlockId sb_grouped_config_block =
bitstream_manager.add_block(phy_mem_instance_name);
bitstream_manager.add_child_block(sb_configurable_block,
sb_grouped_config_block);
VTR_LOGV(verbose, "Added '%s' as a child to '%s'\n",
bitstream_manager.block_name(sb_grouped_config_block).c_str(),
bitstream_manager.block_name(sb_configurable_block).c_str());
sb_configurable_block = sb_grouped_config_block;
}
build_switch_block_bitstream(
bitstream_manager, sb_configurable_block, module_manager, circuit_lib,
mux_lib, atom_ctx, device_annotation, routing_annotation, rr_graph,
rr_gsb, verbose);
VTR_LOGV(verbose, "\tDone\n");
}

View File

@ -49,13 +49,17 @@ static void rec_print_pnr_sdc_constrain_configurable_chain(
ModuleId& previous_module) {
/* For each configurable child, we will go one level down in priority */
for (size_t child_index = 0;
child_index < module_manager.configurable_children(parent_module).size();
child_index <
module_manager
.configurable_children(parent_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size();
++child_index) {
std::string child_module_path = parent_module_path;
ModuleId child_module_id =
module_manager.configurable_children(parent_module)[child_index];
size_t child_instance_id =
module_manager.configurable_child_instances(parent_module)[child_index];
ModuleId child_module_id = module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)[child_index];
size_t child_instance_id = module_manager.configurable_child_instances(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)[child_index];
std::string child_instance_name;
if (true ==
module_manager
@ -79,7 +83,10 @@ static void rec_print_pnr_sdc_constrain_configurable_chain(
/* If there is no configurable children any more, this is a leaf module, print
* a SDC command for disable timing */
if (0 < module_manager.configurable_children(parent_module).size()) {
if (0 < module_manager
.configurable_children(parent_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size()) {
return;
}

View File

@ -45,13 +45,17 @@ void rec_print_pnr_sdc_disable_configurable_memory_module_output(
/* For each configurable child, we will go one level down in priority */
for (size_t child_index = 0;
child_index < module_manager.configurable_children(parent_module).size();
child_index <
module_manager
.configurable_children(parent_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size();
++child_index) {
std::string child_module_path = parent_module_path;
ModuleId child_module_id =
module_manager.configurable_children(parent_module)[child_index];
size_t child_instance_id =
module_manager.configurable_child_instances(parent_module)[child_index];
ModuleId child_module_id = module_manager.configurable_children(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)[child_index];
size_t child_instance_id = module_manager.configurable_child_instances(
parent_module, ModuleManager::e_config_child_type::PHYSICAL)[child_index];
std::string child_instance_name;
if (true ==
module_manager
@ -96,7 +100,10 @@ void rec_print_pnr_sdc_disable_configurable_memory_module_output(
/* If there is no configurable children any more, this is a leaf module, print
* a SDC command for disable timing */
if (0 < module_manager.configurable_children(parent_module).size()) {
if (0 < module_manager
.configurable_children(parent_module,
ModuleManager::e_config_child_type::PHYSICAL)
.size()) {
return;
}

View File

@ -17,6 +17,7 @@
#include "mux_utils.h"
#include "openfpga_digest.h"
#include "openfpga_naming.h"
#include "openfpga_reserved_words.h"
#include "verilog_constants.h"
#include "verilog_memory.h"
#include "verilog_module_writer.h"
@ -51,7 +52,7 @@ static void print_verilog_mux_memory_module(
circuit_lib, mux_model,
find_mux_num_datapath_inputs(circuit_lib, mux_model,
mux_graph.num_inputs()),
std::string(VERILOG_MEM_POSTFIX));
std::string(MEMORY_MODULE_POSTFIX));
ModuleId mem_module = module_manager.find_module(module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mem_module));
/* Write the module content in Verilog format */
@ -63,6 +64,28 @@ static void print_verilog_mux_memory_module(
/* Add an empty line as a splitter */
fp << std::endl;
/* Print feedthrough memory if exists */
std::string feedthru_module_name = generate_mux_subckt_name(
circuit_lib, mux_model,
find_mux_num_datapath_inputs(circuit_lib, mux_model,
mux_graph.num_inputs()),
std::string(MEMORY_FEEDTHROUGH_MODULE_POSTFIX));
ModuleId feedthru_mem_module =
module_manager.find_module(feedthru_module_name);
if (module_manager.valid_module_id(feedthru_mem_module)) {
VTR_ASSERT(true == module_manager.valid_module_id(feedthru_mem_module));
/* Write the module content in Verilog format */
write_verilog_module_to_file(
fp, module_manager, feedthru_mem_module,
options.explicit_port_mapping() ||
circuit_lib.dump_explicit_port_map(mux_model),
options.default_net_type());
/* Add an empty line as a splitter */
fp << std::endl;
}
break;
}
case CIRCUIT_MODEL_DESIGN_RRAM:
@ -174,7 +197,7 @@ void print_verilog_submodule_memories(const ModuleManager& module_manager,
/* Create the module name for the memory block */
std::string module_name = generate_memory_module_name(
circuit_lib, model, sram_models[0], std::string(VERILOG_MEM_POSTFIX));
circuit_lib, model, sram_models[0], std::string(MEMORY_MODULE_POSTFIX));
ModuleId mem_module = module_manager.find_module(module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mem_module));
@ -186,6 +209,36 @@ void print_verilog_submodule_memories(const ModuleManager& module_manager,
/* Add an empty line as a splitter */
fp << std::endl;
/* Create the module name for the memory block */
std::string feedthru_module_name =
generate_memory_module_name(circuit_lib, model, sram_models[0],
std::string(MEMORY_MODULE_POSTFIX), true);
ModuleId feedthru_mem_module =
module_manager.find_module(feedthru_module_name);
if (module_manager.valid_module_id(feedthru_mem_module)) {
/* Write the module content in Verilog format */
write_verilog_module_to_file(fp, module_manager, feedthru_mem_module,
options.explicit_port_mapping() ||
circuit_lib.dump_explicit_port_map(model),
options.default_net_type());
/* Add an empty line as a splitter */
fp << std::endl;
}
}
/* Include memory group modules */
for (ModuleId mem_group_module : module_manager.modules_by_usage(
ModuleManager::e_module_usage_type::MODULE_CONFIG_GROUP)) {
/* Write the module content in Verilog format */
write_verilog_module_to_file(fp, module_manager, mem_group_module,
options.explicit_port_mapping(),
options.default_net_type());
/* Add an empty line as a splitter */
fp << std::endl;
}
/* Close the file stream */

View File

@ -188,6 +188,7 @@ size_t find_circuit_num_config_bits(
}
switch (config_protocol_type) {
case CONFIG_MEM_FEEDTHROUGH:
case CONFIG_MEM_STANDALONE:
case CONFIG_MEM_SCAN_CHAIN:
case CONFIG_MEM_QL_MEMORY_BANK:

View File

@ -2,9 +2,9 @@
* This file includes functions that are used for
* generating ports for memory modules
*********************************************************************/
/* Headers from vtrutil library */
#include "memory_utils.h"
#include "command_exit_codes.h"
#include "decoder_library_utils.h"
#include "openfpga_naming.h"
#include "vtr_assert.h"
@ -342,6 +342,12 @@ std::vector<std::string> generate_sram_port_names(
std::vector<e_circuit_model_port_type> model_port_types;
switch (sram_orgz_type) {
case CONFIG_MEM_FEEDTHROUGH:
/* Feed through wires are all inputs */
model_port_types.push_back(CIRCUIT_MODEL_PORT_BL); /* Indicate mem port */
model_port_types.push_back(
CIRCUIT_MODEL_PORT_BLB); /* Indicate mem_inv port */
break;
case CONFIG_MEM_SCAN_CHAIN:
model_port_types.push_back(CIRCUIT_MODEL_PORT_INPUT);
model_port_types.push_back(CIRCUIT_MODEL_PORT_OUTPUT);
@ -400,6 +406,7 @@ size_t generate_sram_port_size(const e_config_protocol_type sram_orgz_type,
size_t sram_port_size = num_config_bits;
switch (sram_orgz_type) {
case CONFIG_MEM_FEEDTHROUGH:
case CONFIG_MEM_STANDALONE:
break;
case CONFIG_MEM_SCAN_CHAIN:
@ -490,4 +497,55 @@ size_t estimate_num_configurable_children_to_skip_by_config_protocol(
return num_child_to_skip;
}
int rec_find_physical_memory_children(
const ModuleManager& module_manager, const ModuleId& curr_module,
std::vector<ModuleId>& physical_memory_children,
std::vector<std::string>& physical_memory_instance_names,
const bool& verbose) {
if (module_manager
.configurable_children(curr_module,
ModuleManager::e_config_child_type::LOGICAL)
.empty()) {
return CMD_EXEC_SUCCESS;
}
for (size_t ichild = 0;
ichild < module_manager
.configurable_children(
curr_module, ModuleManager::e_config_child_type::LOGICAL)
.size();
++ichild) {
ModuleId logical_child = module_manager.configurable_children(
curr_module, ModuleManager::e_config_child_type::LOGICAL)[ichild];
if (module_manager
.configurable_children(logical_child,
ModuleManager::e_config_child_type::LOGICAL)
.empty()) {
/* This is a leaf node, get the physical memory module */
physical_memory_children.push_back(
module_manager.logical2physical_configurable_children(
curr_module)[ichild]);
physical_memory_instance_names.push_back(
module_manager.logical2physical_configurable_child_instance_names(
curr_module)[ichild]);
VTR_LOGV(
verbose,
"Collecting physical memory module '%s' with an instance name "
"'%s'...\n",
module_manager
.module_name(module_manager.logical2physical_configurable_children(
curr_module)[ichild])
.c_str(),
module_manager
.logical2physical_configurable_child_instance_names(
curr_module)[ichild]
.c_str());
} else {
rec_find_physical_memory_children(
module_manager, logical_child, physical_memory_children,
physical_memory_instance_names, verbose);
}
}
return CMD_EXEC_SUCCESS;
}
} /* end namespace openfpga */

View File

@ -4,6 +4,7 @@
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <string>
#include <vector>
#include "circuit_types.h"
@ -53,6 +54,18 @@ size_t generate_pb_sram_port_size(const e_config_protocol_type sram_orgz_type,
size_t estimate_num_configurable_children_to_skip_by_config_protocol(
const ConfigProtocol& config_protocol, size_t curr_region_num_config_child);
/**
* @brief Find the physical memory child modules with a given root module
* This function will walk through the module tree in a recursive way until
* reaching the leaf node (which require configurable memories) Return a list of
* modules
*/
int rec_find_physical_memory_children(
const ModuleManager& module_manager, const ModuleId& curr_module,
std::vector<ModuleId>& physical_memory_children,
std::vector<std::string>& physical_memory_instance_names,
const bool& verbose);
} /* end namespace openfpga */
#endif

View File

@ -39,7 +39,10 @@ static bool submodule_memory_modules_match_fabric_key(
const FabricKey& fabric_key, const FabricKeyModuleId& key_module_id) {
/* If the length does not match, conclusion is easy to be made */
size_t len_module_memory =
module_manager.configurable_children(module_id).size();
module_manager
.configurable_children(module_id,
ModuleManager::e_config_child_type::PHYSICAL)
.size();
size_t len_fabric_sub_key = fabric_key.sub_keys(key_module_id).size();
if (len_module_memory != len_fabric_sub_key) {
return false;
@ -65,9 +68,11 @@ static bool submodule_memory_modules_match_fabric_key(
inst_info.second = fabric_key.sub_key_value(key_id);
}
if (inst_info.first !=
module_manager.configurable_children(module_id)[ikey] ||
module_manager.configurable_children(
module_id, ModuleManager::e_config_child_type::PHYSICAL)[ikey] ||
inst_info.second !=
module_manager.configurable_child_instances(module_id)[ikey]) {
module_manager.configurable_child_instances(
module_id, ModuleManager::e_config_child_type::PHYSICAL)[ikey]) {
return false;
}
}
@ -80,6 +85,7 @@ static bool submodule_memory_modules_match_fabric_key(
static bool update_submodule_memory_modules_from_fabric_key(
ModuleManager& module_manager, const ModuleId& module_id,
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol,
const ModuleManager::e_config_child_type& config_child_type,
const FabricKey& fabric_key, const FabricKeyModuleId& key_module_id) {
/* Reset the configurable children */
module_manager.clear_configurable_children(module_id);
@ -142,7 +148,8 @@ static bool update_submodule_memory_modules_from_fabric_key(
/* Now we can add the child to configurable children of the top module */
module_manager.add_configurable_child(module_id, inst_info.first,
inst_info.second, vtr::Point<int>());
inst_info.second, config_child_type,
vtr::Point<int>());
}
return CMD_EXEC_SUCCESS;
}
@ -152,9 +159,12 @@ static bool update_submodule_memory_modules_from_fabric_key(
*******************************************************************/
static int remove_submodule_nets_cmos_memory_chain_config_bus(
ModuleManager& module_manager, const ModuleId& parent_module,
const e_config_protocol_type& sram_orgz_type) {
const e_config_protocol_type& sram_orgz_type,
const ModuleManager::e_config_child_type& config_child_type) {
for (size_t mem_index = 0;
mem_index < module_manager.configurable_children(parent_module).size();
mem_index <
module_manager.configurable_children(parent_module, config_child_type)
.size();
++mem_index) {
ModuleId net_src_module_id;
size_t net_src_instance_id;
@ -171,10 +181,10 @@ static int remove_submodule_nets_cmos_memory_chain_config_bus(
} else {
/* Find the port name of previous memory module */
std::string src_port_name = generate_configuration_chain_tail_name();
net_src_module_id =
module_manager.configurable_children(parent_module)[mem_index - 1];
net_src_module_id = module_manager.configurable_children(
parent_module, config_child_type)[mem_index - 1];
net_src_instance_id = module_manager.configurable_child_instances(
parent_module)[mem_index - 1];
parent_module, config_child_type)[mem_index - 1];
net_src_port_id =
module_manager.find_module_port(net_src_module_id, src_port_name);
}
@ -201,9 +211,12 @@ static int remove_submodule_nets_cmos_memory_chain_config_bus(
/* Find the port name of previous memory module */
std::string src_port_name = generate_configuration_chain_tail_name();
ModuleId net_src_module_id =
module_manager.configurable_children(parent_module).back();
module_manager.configurable_children(parent_module, config_child_type)
.back();
size_t net_src_instance_id =
module_manager.configurable_child_instances(parent_module).back();
module_manager
.configurable_child_instances(parent_module, config_child_type)
.back();
ModulePortId net_src_port_id =
module_manager.find_module_port(net_src_module_id, src_port_name);
@ -229,11 +242,12 @@ static int remove_submodule_nets_cmos_memory_chain_config_bus(
*******************************************************************/
static int remove_submodule_nets_cmos_memory_config_bus(
ModuleManager& module_manager, const ModuleId& module_id,
const e_config_protocol_type& sram_orgz_type) {
const e_config_protocol_type& sram_orgz_type,
const ModuleManager::e_config_child_type& config_child_type) {
switch (sram_orgz_type) {
case CONFIG_MEM_SCAN_CHAIN: {
return remove_submodule_nets_cmos_memory_chain_config_bus(
module_manager, module_id, sram_orgz_type);
module_manager, module_id, sram_orgz_type, config_child_type);
break;
}
case CONFIG_MEM_STANDALONE:
@ -274,11 +288,12 @@ static int remove_submodule_nets_cmos_memory_config_bus(
*******************************************************************/
static int remove_submodule_configurable_children_nets(
ModuleManager& module_manager, const ModuleId& module_id,
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol) {
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol,
const ModuleManager::e_config_child_type& config_child_type) {
switch (circuit_lib.design_tech_type(config_protocol.memory_model())) {
case CIRCUIT_MODEL_DESIGN_CMOS:
return remove_submodule_nets_cmos_memory_config_bus(
module_manager, module_id, config_protocol.type());
module_manager, module_id, config_protocol.type(), config_child_type);
break;
case CIRCUIT_MODEL_DESIGN_RRAM:
/* TODO: */
@ -297,9 +312,12 @@ static int remove_submodule_configurable_children_nets(
*******************************************************************/
static int rebuild_submodule_nets_cmos_memory_chain_config_bus(
ModuleManager& module_manager, const ModuleId& parent_module,
const e_config_protocol_type& sram_orgz_type) {
const e_config_protocol_type& sram_orgz_type,
const ModuleManager::e_config_child_type& config_child_type) {
for (size_t mem_index = 0;
mem_index < module_manager.configurable_children(parent_module).size();
mem_index <
module_manager.configurable_children(parent_module, config_child_type)
.size();
++mem_index) {
ModuleId net_src_module_id;
size_t net_src_instance_id;
@ -320,28 +338,28 @@ static int rebuild_submodule_nets_cmos_memory_chain_config_bus(
/* Find the port name of next memory module */
std::string sink_port_name = generate_configuration_chain_head_name();
net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_module_id = module_manager.configurable_children(
parent_module, config_child_type)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, config_child_type)[mem_index];
net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
} else {
/* Find the port name of previous memory module */
std::string src_port_name = generate_configuration_chain_tail_name();
net_src_module_id =
module_manager.configurable_children(parent_module)[mem_index - 1];
net_src_module_id = module_manager.configurable_children(
parent_module, config_child_type)[mem_index - 1];
net_src_instance_id = module_manager.configurable_child_instances(
parent_module)[mem_index - 1];
parent_module, config_child_type)[mem_index - 1];
net_src_port_id =
module_manager.find_module_port(net_src_module_id, src_port_name);
/* Find the port name of next memory module */
std::string sink_port_name = generate_configuration_chain_head_name();
net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_module_id = module_manager.configurable_children(
parent_module, config_child_type)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, config_child_type)[mem_index];
net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
}
@ -375,9 +393,12 @@ static int rebuild_submodule_nets_cmos_memory_chain_config_bus(
/* Find the port name of previous memory module */
std::string src_port_name = generate_configuration_chain_tail_name();
ModuleId net_src_module_id =
module_manager.configurable_children(parent_module).back();
module_manager.configurable_children(parent_module, config_child_type)
.back();
size_t net_src_instance_id =
module_manager.configurable_child_instances(parent_module).back();
module_manager
.configurable_child_instances(parent_module, config_child_type)
.back();
ModulePortId net_src_port_id =
module_manager.find_module_port(net_src_module_id, src_port_name);
@ -418,11 +439,12 @@ static int rebuild_submodule_nets_cmos_memory_chain_config_bus(
*******************************************************************/
static int rebuild_submodule_nets_cmos_memory_config_bus(
ModuleManager& module_manager, const ModuleId& module_id,
const e_config_protocol_type& sram_orgz_type) {
const e_config_protocol_type& sram_orgz_type,
const ModuleManager::e_config_child_type& config_child_type) {
switch (sram_orgz_type) {
case CONFIG_MEM_SCAN_CHAIN: {
return rebuild_submodule_nets_cmos_memory_chain_config_bus(
module_manager, module_id, sram_orgz_type);
module_manager, module_id, sram_orgz_type, config_child_type);
break;
}
case CONFIG_MEM_STANDALONE:
@ -464,11 +486,12 @@ static int rebuild_submodule_nets_cmos_memory_config_bus(
*******************************************************************/
static int rebuild_submodule_configurable_children_nets(
ModuleManager& module_manager, const ModuleId& module_id,
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol) {
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol,
const ModuleManager::e_config_child_type& config_child_type) {
switch (circuit_lib.design_tech_type(config_protocol.memory_model())) {
case CIRCUIT_MODEL_DESIGN_CMOS:
return rebuild_submodule_nets_cmos_memory_config_bus(
module_manager, module_id, config_protocol.type());
module_manager, module_id, config_protocol.type(), config_child_type);
break;
case CIRCUIT_MODEL_DESIGN_RRAM:
/* TODO: */
@ -493,7 +516,8 @@ static int rebuild_submodule_configurable_children_nets(
static int load_and_update_submodule_memory_modules_from_fabric_key(
ModuleManager& module_manager, const ModuleId& module_id,
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol,
const FabricKey& fabric_key, const FabricKeyModuleId& key_module_id) {
const FabricKey& fabric_key, const FabricKeyModuleId& key_module_id,
const bool& group_config_block) {
int status = CMD_EXEC_SUCCESS;
/* Compare the configurable children list */
if (submodule_memory_modules_match_fabric_key(module_manager, module_id,
@ -502,20 +526,24 @@ static int load_and_update_submodule_memory_modules_from_fabric_key(
}
/* Do not match, now remove all the nets for the configurable children */
status = remove_submodule_configurable_children_nets(
module_manager, module_id, circuit_lib, config_protocol);
module_manager, module_id, circuit_lib, config_protocol,
ModuleManager::e_config_child_type::PHYSICAL);
if (status == CMD_EXEC_FATAL_ERROR) {
return status;
}
/* Overwrite the configurable children list */
status = update_submodule_memory_modules_from_fabric_key(
module_manager, module_id, circuit_lib, config_protocol, fabric_key,
key_module_id);
module_manager, module_id, circuit_lib, config_protocol,
group_config_block ? ModuleManager::e_config_child_type::PHYSICAL
: ModuleManager::e_config_child_type::UNIFIED,
fabric_key, key_module_id);
if (status == CMD_EXEC_FATAL_ERROR) {
return status;
}
/* TODO: Create the nets for the new list of configurable children */
status = rebuild_submodule_configurable_children_nets(
module_manager, module_id, circuit_lib, config_protocol);
module_manager, module_id, circuit_lib, config_protocol,
ModuleManager::e_config_child_type::PHYSICAL);
if (status == CMD_EXEC_FATAL_ERROR) {
return status;
}
@ -528,7 +556,8 @@ static int load_and_update_submodule_memory_modules_from_fabric_key(
*******************************************************************/
int load_submodules_memory_modules_from_fabric_key(
ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
const ConfigProtocol& config_protocol, const FabricKey& fabric_key) {
const ConfigProtocol& config_protocol, const FabricKey& fabric_key,
const bool& group_config_block) {
int status = CMD_EXEC_SUCCESS;
for (FabricKeyModuleId key_module_id : fabric_key.modules()) {
std::string module_name = fabric_key.module_name(key_module_id);
@ -544,7 +573,7 @@ int load_submodules_memory_modules_from_fabric_key(
/* This is a valid module, try to load and update */
status = load_and_update_submodule_memory_modules_from_fabric_key(
module_manager, module_id, circuit_lib, config_protocol, fabric_key,
key_module_id);
key_module_id, group_config_block);
if (status == CMD_EXEC_FATAL_ERROR) {
return status;
}

View File

@ -34,7 +34,8 @@ namespace openfpga {
int load_submodules_memory_modules_from_fabric_key(
ModuleManager& module_manager, const CircuitLibrary& circuit_lib,
const ConfigProtocol& config_protocol, const FabricKey& fabric_key);
const ConfigProtocol& config_protocol, const FabricKey& fabric_key,
const bool& group_config_block);
} /* end namespace openfpga */

View File

@ -86,11 +86,14 @@ void reserve_module_manager_module_nets(ModuleManager& module_manager,
*children as well
******************************************************************************/
size_t count_module_manager_module_configurable_children(
const ModuleManager& module_manager, const ModuleId& module) {
const ModuleManager& module_manager, const ModuleId& module,
const ModuleManager::e_config_child_type& config_child_type) {
size_t num_config_children = 0;
for (const ModuleId& child : module_manager.configurable_children(module)) {
if (0 != module_manager.configurable_children(child).size()) {
for (const ModuleId& child :
module_manager.configurable_children(module, config_child_type)) {
if (0 !=
module_manager.configurable_children(child, config_child_type).size()) {
num_config_children++;
}
}
@ -342,6 +345,7 @@ void add_sram_ports_to_module_manager(
/* Add ports to the module manager */
switch (sram_orgz_type) {
case CONFIG_MEM_FEEDTHROUGH:
case CONFIG_MEM_STANDALONE:
case CONFIG_MEM_QL_MEMORY_BANK:
case CONFIG_MEM_MEMORY_BANK: {
@ -1017,7 +1021,8 @@ void add_module_nets_between_logic_and_memory_sram_bus(
void add_module_nets_cmos_flatten_memory_config_bus(
ModuleManager& module_manager, const ModuleId& parent_module,
const e_config_protocol_type& sram_orgz_type,
const e_circuit_model_port_type& config_port_type) {
const e_circuit_model_port_type& config_port_type,
const ModuleManager::e_config_child_type& config_child_type) {
/* A counter for the current pin id for the source port of parent module */
size_t cur_src_pin_id = 0;
@ -1039,7 +1044,8 @@ void add_module_nets_cmos_flatten_memory_config_bus(
module_manager.module_port(net_src_module_id, net_src_port_id);
for (size_t mem_index = 0;
mem_index < module_manager.configurable_children(parent_module).size();
mem_index < module_manager.num_configurable_children(parent_module,
config_child_type);
++mem_index) {
ModuleId net_sink_module_id;
size_t net_sink_instance_id;
@ -1048,10 +1054,10 @@ void add_module_nets_cmos_flatten_memory_config_bus(
/* Find the port name of next memory module */
std::string sink_port_name =
generate_sram_port_name(sram_orgz_type, config_port_type);
net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_module_id = module_manager.configurable_children(
parent_module, config_child_type)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, config_child_type)[mem_index];
net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
@ -1105,7 +1111,8 @@ void add_module_nets_cmos_flatten_memory_config_bus(
void add_module_nets_cmos_memory_bank_bl_config_bus(
ModuleManager& module_manager, const ModuleId& parent_module,
const e_config_protocol_type& sram_orgz_type,
const e_circuit_model_port_type& config_port_type) {
const e_circuit_model_port_type& config_port_type,
const ModuleManager::e_config_child_type& config_child_type) {
/* A counter for the current pin id for the source port of parent module */
size_t cur_src_pin_id = 0;
@ -1122,15 +1129,17 @@ void add_module_nets_cmos_memory_bank_bl_config_bus(
module_manager.module_port(net_src_module_id, net_src_port_id);
for (size_t mem_index = 0;
mem_index < module_manager.configurable_children(parent_module).size();
mem_index <
module_manager.configurable_children(parent_module, config_child_type)
.size();
++mem_index) {
/* Find the port name of next memory module */
std::string sink_port_name =
generate_sram_port_name(sram_orgz_type, config_port_type);
ModuleId net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
size_t net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
ModuleId net_sink_module_id = module_manager.configurable_children(
parent_module, config_child_type)[mem_index];
size_t net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, config_child_type)[mem_index];
ModulePortId net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
@ -1188,7 +1197,8 @@ void add_module_nets_cmos_memory_bank_bl_config_bus(
void add_module_nets_cmos_memory_bank_wl_config_bus(
ModuleManager& module_manager, const ModuleId& parent_module,
const e_config_protocol_type& sram_orgz_type,
const e_circuit_model_port_type& config_port_type) {
const e_circuit_model_port_type& config_port_type,
const ModuleManager::e_config_child_type& config_child_type) {
/* A counter for the current pin id for the source port of parent module */
size_t cur_src_pin_id = 0;
@ -1217,15 +1227,17 @@ void add_module_nets_cmos_memory_bank_wl_config_bus(
module_manager.module_port(net_src_module_id, net_bl_port_id);
for (size_t mem_index = 0;
mem_index < module_manager.configurable_children(parent_module).size();
mem_index <
module_manager.configurable_children(parent_module, config_child_type)
.size();
++mem_index) {
/* Find the port name of next memory module */
std::string sink_port_name =
generate_sram_port_name(sram_orgz_type, config_port_type);
ModuleId net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
size_t net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
ModuleId net_sink_module_id = module_manager.configurable_children(
parent_module, config_child_type)[mem_index];
size_t net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, config_child_type)[mem_index];
ModulePortId net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
@ -1272,9 +1284,11 @@ void add_module_nets_cmos_memory_bank_wl_config_bus(
*********************************************************************/
void add_module_nets_cmos_memory_chain_config_bus(
ModuleManager& module_manager, const ModuleId& parent_module,
const e_config_protocol_type& sram_orgz_type) {
const e_config_protocol_type& sram_orgz_type,
const ModuleManager::e_config_child_type& config_child_type) {
for (size_t mem_index = 0;
mem_index < module_manager.configurable_children(parent_module).size();
mem_index < module_manager.num_configurable_children(parent_module,
config_child_type);
++mem_index) {
ModuleId net_src_module_id;
size_t net_src_instance_id;
@ -1295,28 +1309,28 @@ void add_module_nets_cmos_memory_chain_config_bus(
/* Find the port name of next memory module */
std::string sink_port_name = generate_configuration_chain_head_name();
net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_module_id = module_manager.configurable_children(
parent_module, config_child_type)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, config_child_type)[mem_index];
net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
} else {
/* Find the port name of previous memory module */
std::string src_port_name = generate_configuration_chain_tail_name();
net_src_module_id =
module_manager.configurable_children(parent_module)[mem_index - 1];
net_src_module_id = module_manager.configurable_children(
parent_module, config_child_type)[mem_index - 1];
net_src_instance_id = module_manager.configurable_child_instances(
parent_module)[mem_index - 1];
parent_module, config_child_type)[mem_index - 1];
net_src_port_id =
module_manager.find_module_port(net_src_module_id, src_port_name);
/* Find the port name of next memory module */
std::string sink_port_name = generate_configuration_chain_head_name();
net_sink_module_id =
module_manager.configurable_children(parent_module)[mem_index];
net_sink_instance_id =
module_manager.configurable_child_instances(parent_module)[mem_index];
net_sink_module_id = module_manager.configurable_children(
parent_module, config_child_type)[mem_index];
net_sink_instance_id = module_manager.configurable_child_instances(
parent_module, config_child_type)[mem_index];
net_sink_port_id =
module_manager.find_module_port(net_sink_module_id, sink_port_name);
}
@ -1350,9 +1364,12 @@ void add_module_nets_cmos_memory_chain_config_bus(
/* Find the port name of previous memory module */
std::string src_port_name = generate_configuration_chain_tail_name();
ModuleId net_src_module_id =
module_manager.configurable_children(parent_module).back();
module_manager.configurable_children(parent_module, config_child_type)
.back();
size_t net_src_instance_id =
module_manager.configurable_child_instances(parent_module).back();
module_manager
.configurable_child_instances(parent_module, config_child_type)
.back();
ModulePortId net_src_port_id =
module_manager.find_module_port(net_src_module_id, src_port_name);
@ -1406,9 +1423,10 @@ void add_module_nets_cmos_memory_chain_config_bus(
*
*********************************************************************/
static void add_module_nets_cmos_memory_frame_short_config_bus(
ModuleManager& module_manager, const ModuleId& parent_module) {
ModuleManager& module_manager, const ModuleId& parent_module,
const ModuleManager::e_config_child_type& config_child_type) {
std::vector<ModuleId> configurable_children =
module_manager.configurable_children(parent_module);
module_manager.configurable_children(parent_module, config_child_type);
VTR_ASSERT(1 == configurable_children.size());
ModuleId child_module = configurable_children[0];
@ -1490,9 +1508,10 @@ static void add_module_nets_cmos_memory_frame_short_config_bus(
*********************************************************************/
static void add_module_nets_cmos_memory_frame_decoder_config_bus(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const ModuleId& parent_module) {
const ModuleId& parent_module,
const ModuleManager::e_config_child_type& config_child_type) {
std::vector<ModuleId> configurable_children =
module_manager.configurable_children(parent_module);
module_manager.configurable_children(parent_module, config_child_type);
/* Find the decoder specification */
size_t addr_size =
@ -1570,8 +1589,8 @@ static void add_module_nets_cmos_memory_frame_decoder_config_bus(
for (size_t mem_index = 0; mem_index < configurable_children.size();
++mem_index) {
ModuleId child_module = configurable_children[mem_index];
size_t child_instance =
module_manager.configurable_child_instances(parent_module)[mem_index];
size_t child_instance = module_manager.configurable_child_instances(
parent_module, config_child_type)[mem_index];
ModulePortId child_addr_port = module_manager.find_module_port(
child_module, std::string(DECODER_ADDRESS_PORT_NAME));
BasicPort child_addr_port_info =
@ -1602,8 +1621,8 @@ static void add_module_nets_cmos_memory_frame_decoder_config_bus(
for (size_t mem_index = 0; mem_index < configurable_children.size();
++mem_index) {
ModuleId child_module = configurable_children[mem_index];
size_t child_instance =
module_manager.configurable_child_instances(parent_module)[mem_index];
size_t child_instance = module_manager.configurable_child_instances(
parent_module, config_child_type)[mem_index];
ModulePortId child_din_port = module_manager.find_module_port(
child_module, std::string(DECODER_DATA_IN_PORT_NAME));
add_module_bus_nets(module_manager, parent_module, parent_module, 0,
@ -1623,8 +1642,8 @@ static void add_module_nets_cmos_memory_frame_decoder_config_bus(
for (size_t mem_index = 0; mem_index < configurable_children.size();
++mem_index) {
ModuleId child_module = configurable_children[mem_index];
size_t child_instance =
module_manager.configurable_child_instances(parent_module)[mem_index];
size_t child_instance = module_manager.configurable_child_instances(
parent_module, config_child_type)[mem_index];
ModulePortId child_en_port = module_manager.find_module_port(
child_module, std::string(DECODER_ENABLE_PORT_NAME));
BasicPort child_en_port_info =
@ -1648,7 +1667,9 @@ static void add_module_nets_cmos_memory_frame_decoder_config_bus(
}
/* Add the decoder as the last configurable children */
module_manager.add_configurable_child(parent_module, decoder_module, 0);
module_manager.add_configurable_child(
parent_module, decoder_module, 0,
ModuleManager::e_config_child_type::UNIFIED);
}
/*********************************************************************
@ -1662,18 +1683,22 @@ static void add_module_nets_cmos_memory_frame_decoder_config_bus(
**********************************************************************/
void add_module_nets_cmos_memory_frame_config_bus(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const ModuleId& parent_module) {
if (0 == module_manager.configurable_children(parent_module).size()) {
const ModuleId& parent_module,
const ModuleManager::e_config_child_type& config_child_type) {
if (0 == module_manager.num_configurable_children(parent_module,
config_child_type)) {
return;
}
if (1 == module_manager.configurable_children(parent_module).size()) {
add_module_nets_cmos_memory_frame_short_config_bus(module_manager,
parent_module);
if (1 == module_manager.num_configurable_children(parent_module,
config_child_type)) {
add_module_nets_cmos_memory_frame_short_config_bus(
module_manager, parent_module, config_child_type);
} else {
VTR_ASSERT(1 < module_manager.configurable_children(parent_module).size());
VTR_ASSERT(1 < module_manager.num_configurable_children(parent_module,
config_child_type));
add_module_nets_cmos_memory_frame_decoder_config_bus(
module_manager, decoder_lib, parent_module);
module_manager, decoder_lib, parent_module, config_child_type);
}
}
@ -1723,26 +1748,38 @@ void add_module_nets_cmos_memory_frame_config_bus(
**********************************************************************/
static void add_module_nets_cmos_memory_config_bus(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const ModuleId& parent_module, const e_config_protocol_type& sram_orgz_type) {
const ModuleId& parent_module, const e_config_protocol_type& sram_orgz_type,
const ModuleManager::e_config_child_type& config_child_type) {
switch (sram_orgz_type) {
case CONFIG_MEM_SCAN_CHAIN: {
add_module_nets_cmos_memory_chain_config_bus(
module_manager, parent_module, sram_orgz_type);
module_manager, parent_module, sram_orgz_type, config_child_type);
break;
}
case CONFIG_MEM_FEEDTHROUGH:
add_module_nets_cmos_flatten_memory_config_bus(
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL,
config_child_type);
add_module_nets_cmos_flatten_memory_config_bus(
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BLB,
config_child_type);
break;
case CONFIG_MEM_STANDALONE:
case CONFIG_MEM_QL_MEMORY_BANK:
case CONFIG_MEM_MEMORY_BANK:
add_module_nets_cmos_flatten_memory_config_bus(
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL,
config_child_type);
add_module_nets_cmos_flatten_memory_config_bus(
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL,
config_child_type);
add_module_nets_cmos_flatten_memory_config_bus(
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WLR);
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WLR,
config_child_type);
break;
case CONFIG_MEM_FRAME_BASED:
add_module_nets_cmos_memory_frame_config_bus(module_manager, decoder_lib,
parent_module);
add_module_nets_cmos_memory_frame_config_bus(
module_manager, decoder_lib, parent_module, config_child_type);
break;
default:
VTR_LOGF_ERROR(__FILE__, __LINE__,
@ -1788,31 +1825,37 @@ static void add_module_nets_cmos_memory_config_bus(
**********************************************************************/
static void add_pb_module_nets_cmos_memory_config_bus(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const ModuleId& parent_module, const e_config_protocol_type& sram_orgz_type) {
const ModuleId& parent_module, const e_config_protocol_type& sram_orgz_type,
const ModuleManager::e_config_child_type& config_child_type) {
switch (sram_orgz_type) {
case CONFIG_MEM_SCAN_CHAIN: {
add_module_nets_cmos_memory_chain_config_bus(
module_manager, parent_module, sram_orgz_type);
module_manager, parent_module, sram_orgz_type, config_child_type);
break;
}
case CONFIG_MEM_STANDALONE:
case CONFIG_MEM_QL_MEMORY_BANK:
add_module_nets_cmos_memory_bank_bl_config_bus(
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL,
config_child_type);
add_module_nets_cmos_memory_bank_wl_config_bus(
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL,
config_child_type);
add_module_nets_cmos_memory_bank_wl_config_bus(
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WLR);
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WLR,
config_child_type);
break;
case CONFIG_MEM_MEMORY_BANK:
add_module_nets_cmos_flatten_memory_config_bus(
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL);
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_BL,
config_child_type);
add_module_nets_cmos_flatten_memory_config_bus(
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL);
module_manager, parent_module, sram_orgz_type, CIRCUIT_MODEL_PORT_WL,
config_child_type);
break;
case CONFIG_MEM_FRAME_BASED:
add_module_nets_cmos_memory_frame_config_bus(module_manager, decoder_lib,
parent_module);
add_module_nets_cmos_memory_frame_config_bus(
module_manager, decoder_lib, parent_module, config_child_type);
break;
default:
VTR_LOGF_ERROR(__FILE__, __LINE__,
@ -1878,11 +1921,13 @@ static void add_pb_module_nets_cmos_memory_config_bus(
void add_module_nets_memory_config_bus(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const ModuleId& parent_module, const e_config_protocol_type& sram_orgz_type,
const e_circuit_model_design_tech& mem_tech) {
const e_circuit_model_design_tech& mem_tech,
const ModuleManager::e_config_child_type& config_child_type) {
switch (mem_tech) {
case CIRCUIT_MODEL_DESIGN_CMOS:
add_module_nets_cmos_memory_config_bus(module_manager, decoder_lib,
parent_module, sram_orgz_type);
parent_module, sram_orgz_type,
config_child_type);
break;
case CIRCUIT_MODEL_DESIGN_RRAM:
/* TODO: */
@ -1909,11 +1954,13 @@ void add_module_nets_memory_config_bus(
void add_pb_module_nets_memory_config_bus(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const ModuleId& parent_module, const e_config_protocol_type& sram_orgz_type,
const e_circuit_model_design_tech& mem_tech) {
const e_circuit_model_design_tech& mem_tech,
const ModuleManager::e_config_child_type& config_child_type) {
switch (mem_tech) {
case CIRCUIT_MODEL_DESIGN_CMOS:
add_pb_module_nets_cmos_memory_config_bus(module_manager, decoder_lib,
parent_module, sram_orgz_type);
parent_module, sram_orgz_type,
config_child_type);
break;
case CIRCUIT_MODEL_DESIGN_RRAM:
/* TODO: */
@ -2364,10 +2411,12 @@ size_t find_module_num_shared_config_bits_from_child_modules(
size_t find_module_num_config_bits_from_child_modules(
ModuleManager& module_manager, const ModuleId& module_id,
const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model,
const e_config_protocol_type& sram_orgz_type) {
const e_config_protocol_type& sram_orgz_type,
const ModuleManager::e_config_child_type& config_child_type) {
size_t num_config_bits = 0;
switch (sram_orgz_type) {
case CONFIG_MEM_FEEDTHROUGH:
case CONFIG_MEM_STANDALONE:
case CONFIG_MEM_SCAN_CHAIN:
case CONFIG_MEM_QL_MEMORY_BANK:
@ -2377,7 +2426,7 @@ size_t find_module_num_config_bits_from_child_modules(
* per configurable children
*/
for (const ModuleId& child :
module_manager.configurable_children(module_id)) {
module_manager.configurable_children(module_id, config_child_type)) {
num_config_bits += find_module_num_config_bits(
module_manager, child, circuit_lib, sram_model, sram_orgz_type);
}
@ -2390,7 +2439,7 @@ size_t find_module_num_config_bits_from_child_modules(
* - and the number of configurable children
*/
for (const ModuleId& child :
module_manager.configurable_children(module_id)) {
module_manager.configurable_children(module_id, config_child_type)) {
size_t temp_num_config_bits = find_module_num_config_bits(
module_manager, child, circuit_lib, sram_model, sram_orgz_type);
num_config_bits =
@ -2400,9 +2449,11 @@ size_t find_module_num_config_bits_from_child_modules(
/* If there are more than 2 configurable children, we need a decoder
* Otherwise, we can just short wire the address port to the children
*/
if (1 < module_manager.configurable_children(module_id).size()) {
if (1 < module_manager.num_configurable_children(module_id,
config_child_type)) {
num_config_bits += find_mux_local_decoder_addr_size(
module_manager.configurable_children(module_id).size());
module_manager.num_configurable_children(module_id,
config_child_type));
}
break;

View File

@ -42,7 +42,8 @@ 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);
const ModuleManager& module_manager, const ModuleId& module,
const ModuleManager::e_config_child_type& config_child_type);
std::pair<ModuleId, size_t> find_module_manager_instance_module_info(
const ModuleManager& module_manager, const ModuleId& parent,
@ -110,35 +111,42 @@ void add_module_nets_between_logic_and_memory_sram_bus(
void add_module_nets_cmos_flatten_memory_config_bus(
ModuleManager& module_manager, const ModuleId& parent_module,
const e_config_protocol_type& sram_orgz_type,
const e_circuit_model_port_type& config_port_type);
const e_circuit_model_port_type& config_port_type,
const ModuleManager::e_config_child_type& config_child_type);
void add_module_nets_cmos_memory_bank_bl_config_bus(
ModuleManager& module_manager, const ModuleId& parent_module,
const e_config_protocol_type& sram_orgz_type,
const e_circuit_model_port_type& config_port_type);
const e_circuit_model_port_type& config_port_type,
const ModuleManager::e_config_child_type& config_child_type);
void add_module_nets_cmos_memory_bank_wl_config_bus(
ModuleManager& module_manager, const ModuleId& parent_module,
const e_config_protocol_type& sram_orgz_type,
const e_circuit_model_port_type& config_port_type);
const e_circuit_model_port_type& config_port_type,
const ModuleManager::e_config_child_type& config_child_type);
void add_module_nets_cmos_memory_chain_config_bus(
ModuleManager& module_manager, const ModuleId& parent_module,
const e_config_protocol_type& sram_orgz_type);
const e_config_protocol_type& sram_orgz_type,
const ModuleManager::e_config_child_type& config_child_type);
void add_module_nets_cmos_memory_frame_config_bus(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const ModuleId& parent_module);
const ModuleId& parent_module,
const ModuleManager::e_config_child_type& config_child_type);
void add_module_nets_memory_config_bus(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const ModuleId& parent_module, const e_config_protocol_type& sram_orgz_type,
const e_circuit_model_design_tech& mem_tech);
const e_circuit_model_design_tech& mem_tech,
const ModuleManager::e_config_child_type& config_child_type);
void add_pb_module_nets_memory_config_bus(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const ModuleId& parent_module, const e_config_protocol_type& sram_orgz_type,
const e_circuit_model_design_tech& mem_tech);
const e_circuit_model_design_tech& mem_tech,
const ModuleManager::e_config_child_type& config_child_type);
size_t find_module_num_shared_config_bits(const ModuleManager& module_manager,
const ModuleId& module_id);
@ -170,7 +178,8 @@ size_t find_module_num_shared_config_bits_from_child_modules(
size_t find_module_num_config_bits_from_child_modules(
ModuleManager& module_manager, const ModuleId& module_id,
const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model,
const e_config_protocol_type& sram_orgz_type);
const e_config_protocol_type& sram_orgz_type,
const ModuleManager::e_config_child_type& config_child_type);
ModuleNetId create_module_source_pin_net(ModuleManager& module_manager,
const ModuleId& cur_module_id,

View File

@ -0,0 +1,74 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route
# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
# Read OpenFPGA simulation settings
read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE}
# Annotate the OpenFPGA architecture to VPR data base
# to debug use --verbose options
link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges
# Check and correct any naming conflicts in the BLIF netlist
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
# Apply fix-up to Look-Up Table truth tables based on packing results
lut_truth_table_fixup
# Build the module graph
# - Enabled compression on routing architecture modules
# - Enable pin duplication on grid modules
build_fabric --compress_routing --group_config_block ${OPENFPGA_GROUP_TILE_CONFIG_OPTION} #--verbose
# Add a fpga core between fpga top and the underlying modules
${OPENFPGA_ADD_FPGA_CORE_MODULE}
# Write the fabric hierarchy of module graph to a file
# This is used by hierarchical PnR flows
write_fabric_hierarchy --file ./fabric_hierarchy.txt
# Repack the netlist to physical pbs
# This must be done before bitstream generator and testbench generation
# Strongly recommend it is done after all the fix-up have been applied
repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
# Write fabric-dependent bitstream
write_fabric_bitstream --file fabric_bitstream.bit --format plain_text
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist
write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose
# Write the Verilog testbench for FPGA fabric
# - We suggest the use of same output directory as fabric Verilog netlists
# - Must specify the reference benchmark file if you want to output any testbenches
# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
write_full_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --explicit_port_mapping --include_signal_init --bitstream fabric_bitstream.bit
# Write the SDC files for PnR backend
# - Turn on every options here
# FIXME: Not supported yet.
#write_pnr_sdc --file ./SDC
# Write SDC to disable timing for configure ports
write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc
# Write the SDC to run timing analysis for a mapped FPGA fabric
write_analysis_sdc --file ./SDC_analysis
# Finish and exit OpenFPGA
exit
# Note :
# To run verification at the end of the flow maintain source in ./SRC directory

View File

@ -0,0 +1,78 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --device ${OPENFPGA_VPR_DEVICE} --route_chan_width ${OPENFPGA_VPR_ROUTE_CHAN_WIDTH} --clock_modeling ideal ${OPENFPGA_VPR_EXTRA_OPTIONS}
# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
# Read OpenFPGA simulation settings
read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE}
# Annotate the OpenFPGA architecture to VPR data base
# to debug use --verbose options
link_openfpga_arch --sort_gsb_chan_node_in_edges
# Check and correct any naming conflicts in the BLIF netlist
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
# Apply fix-up to Look-Up Table truth tables based on packing results
lut_truth_table_fixup
# Optionally pb pin fixup
${OPENFPGA_PB_PIN_FIXUP_COMMAND}
# Build the module graph
# - Enabled compression on routing architecture modules
# - Enable pin duplication on grid modules
build_fabric --compress_routing --group_config_block ${OPENFPGA_GROUP_TILE_CONFIG_OPTION} #--verbose
# Add a fpga core between fpga top and the underlying modules
${OPENFPGA_ADD_FPGA_CORE_MODULE}
# Write the fabric hierarchy of module graph to a file
# This is used by hierarchical PnR flows
write_fabric_hierarchy --file ./fabric_hierarchy.txt
# Repack the netlist to physical pbs
# This must be done before bitstream generator and testbench generation
# Strongly recommend it is done after all the fix-up have been applied
repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
# Write fabric-dependent bitstream
write_fabric_bitstream --file fabric_bitstream.bit --format plain_text
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist
write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose
# Write the Verilog testbench for FPGA fabric
# - We suggest the use of same output directory as fabric Verilog netlists
# - Must specify the reference benchmark file if you want to output any testbenches
# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
write_preconfigured_fabric_wrapper --embed_bitstream iverilog --file ./SRC ${OPENFPGA_VERILOG_TESTBENCH_OPTIONS}
write_preconfigured_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} ${OPENFPGA_VERILOG_TESTBENCH_OPTIONS}
# Write the SDC files for PnR backend
# - Turn on every options here
# FIXME: Not supported yet.
#write_pnr_sdc --file ./SDC
# Write SDC to disable timing for configure ports
write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc
# Write the SDC to run timing analysis for a mapped FPGA fabric
write_analysis_sdc --file ./SDC_analysis
# Finish and exit OpenFPGA
exit
# Note :
# To run verification at the end of the flow maintain source in ./SRC directory

View File

@ -186,6 +186,10 @@ run-task basic_tests/tile_organization/homo_fabric_tile_adder_chain $@
run-task basic_tests/tile_organization/homo_fabric_tile_clkntwk $@
run-task basic_tests/tile_organization/hetero_fabric_tile $@
echo -e "Testing group config block";
run-task basic_tests/group_config_block/group_config_block_homo_full_testbench $@
run-task basic_tests/group_config_block/group_config_block_homo_fabric_tile $@
echo -e "Testing global port definition from tiles";
run-task basic_tests/global_tile_ports/global_tile_clock $@
run-task basic_tests/global_tile_ports/global_tile_reset $@

View File

@ -0,0 +1,55 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = false
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/group_config_block_preconfig_testbench_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
openfpga_vpr_extra_options=--constant_net_method route --skip_sync_clustering_and_routing_results on
openfpga_pb_pin_fixup_command = pb_pin_fixup --verbose
openfpga_vpr_device=3x2
openfpga_vpr_route_chan_width=60
openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml
openfpga_verilog_testbench_options=
openfpga_add_fpga_core_module=
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v
bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v
bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v
[SYNTHESIS_PARAM]
# Yosys script parameters
bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_cell_sim.v
bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm_dsp_map.v
bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8
bench_read_verilog_options_common = -nolatches
bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys
bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys
bench0_top = mac_2
bench1_top = mac_4
bench2_top = mac_6
bench3_top = mac_8
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=
vpr_fpga_verilog_formal_verification_top_netlist=

View File

@ -0,0 +1,36 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/group_config_block_full_testbench_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml
openfpga_add_fpga_core_module=
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_TileOrgzTl_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v
[SYNTHESIS_PARAM]
bench_read_verilog_options_common = -nolatches
bench0_top = or2
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=

View File

@ -0,0 +1,36 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/group_config_block_full_testbench_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml
openfpga_add_fpga_core_module=add_fpga_core_to_fabric --instance_name fpga_core_inst
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_TileOrgzTl_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v
[SYNTHESIS_PARAM]
bench_read_verilog_options_common = -nolatches
bench0_top = or2
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=

View File

@ -0,0 +1,36 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/group_config_block_full_testbench_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
openfpga_group_tile_config_option=
openfpga_add_fpga_core_module=
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_TileOrgzTl_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v
[SYNTHESIS_PARAM]
bench_read_verilog_options_common = -nolatches
bench0_top = or2
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=

2
yosys

@ -1 +1 @@
Subproject commit b04d0e09e83102e14a53bb8b8dcc8c35f63b2fbe
Subproject commit f37ce5c839c5a5e21fb74046375e5928ad91d22e