Merge branch 'master' into openfpga-issue-1256
This commit is contained in:
commit
bb945b2816
|
@ -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 |
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 "
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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 $@
|
||||
|
|
|
@ -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=
|
|
@ -0,0 +1 @@
|
|||
<tiles style="top_left"/>
|
|
@ -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=
|
|
@ -0,0 +1 @@
|
|||
<tiles style="top_left"/>
|
|
@ -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=
|
|
@ -0,0 +1 @@
|
|||
<tiles style="top_left"/>
|
|
@ -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
2
yosys
|
@ -1 +1 @@
|
|||
Subproject commit b04d0e09e83102e14a53bb8b8dcc8c35f63b2fbe
|
||||
Subproject commit f37ce5c839c5a5e21fb74046375e5928ad91d22e
|
Loading…
Reference in New Issue