[core] developing the physical memory block builder

This commit is contained in:
tangxifan 2023-07-31 22:57:26 -07:00
parent 2f079c7b92
commit 23643f3fb1
14 changed files with 135 additions and 51 deletions

View File

@ -129,10 +129,12 @@ 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 +142,12 @@ enum e_config_protocol_type {
CONFIG_MEM_MEMORY_BANK,
CONFIG_MEM_QL_MEMORY_BANK,
CONFIG_MEM_FRAME_BASED,
CONFIG_MEM_FEEDTHROUGH,
NUM_CONFIG_PROTOCOL_TYPES
};
constexpr std::array<const char*, NUM_CONFIG_PROTOCOL_TYPES>
CONFIG_PROTOCOL_TYPE_STRING = {{"standalone", "scan_chain", "memory_bank",
"ql_memory_bank", "frame_based"}};
"ql_memory_bank", "frame_based", "feedthrough"}};
#endif

View File

@ -41,6 +41,8 @@ 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_DATA_IN_PORT_NAME = "feedthrough_mem_in";
constexpr const char* MEMORY_FEEDTHROUGH_DATA_IN_INV_PORT_NAME = "feedthrough_mem_inb";
constexpr const char* MEMORY_BL_PORT_NAME = "bl";
constexpr const char* MEMORY_WL_PORT_NAME = "wl";
constexpr const char* MEMORY_WLR_PORT_NAME = "wlr";

View File

@ -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);
}
@ -734,6 +740,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(MEMEMORY_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
@ -1159,8 +1185,10 @@ std::string generate_pb_mux_instance_name(const std::string& prefix,
********************************************************************/
std::string generate_pb_memory_instance_name(const std::string& prefix,
t_pb_graph_pin* pb_graph_pin,
const std::string& postfix) {
std::string instance_name(prefix);
const std::string& postfix,
const bool& feedthrough_memory) {
std::string mid_name = feedthrough_memory ? "virtual_" : "";
std::string instance_name(mid_name + prefix);
instance_name += std::string(pb_graph_pin->parent_node->pb_type->name);
if (IN_PORT == pb_graph_pin->port->type) {

View File

@ -68,7 +68,8 @@ std::string generate_segment_wire_mid_output_name(
std::string generate_memory_module_name(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
const CircuitModelId& sram_model,
const std::string& postfix);
const std::string& postfix,
const bool& feedthrough_memory = false);
std::string generate_routing_block_netlist_name(const std::string& prefix,
const size_t& block_id,
@ -144,7 +145,8 @@ 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);
const std::string& postfix,
const bool& feedthrough_memory = false);
std::string generate_grid_port_name(const size_t& width, const size_t& height,
const int& subtile_index,

View File

@ -78,7 +78,7 @@ 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);
/* Build grid and programmable block modules */
build_grid_modules(module_manager, decoder_lib, vpr_device_ctx,
@ -92,14 +92,14 @@ int build_device_module_graph(
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);
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);
openfpga_ctx.arch().config_protocol.type(), sram_model, group_config_block, verbose);
}
/* Build tile modules if defined */

View File

@ -310,11 +310,12 @@ 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);
}
@ -335,7 +336,7 @@ static void build_primitive_block_module(
/* 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_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
@ -356,7 +357,7 @@ static void build_primitive_block_module(
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);
memory_instance_id, group_config_block);
}
/* Add all the nets to connect configuration ports from memory module to
@ -638,12 +639,12 @@ 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);
mux_mem_instance, group_config_block);
/* Add nets to connect SRAM ports of the MUX to the SRAM port of memory
* module */
@ -955,6 +956,8 @@ static void rec_build_logical_tile_modules(
std::vector<ModuleId> memory_modules;
std::vector<size_t> memory_instances;
e_config_protocol 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 */
@ -997,9 +1000,9 @@ static void rec_build_logical_tile_modules(
*/
if (0 < find_module_num_config_bits(module_manager, child_pb_module,
circuit_lib, sram_model,
sram_orgz_type)) {
mem_module_type)) {
module_manager.add_configurable_child(pb_module, child_pb_module,
child_instance_id);
child_instance_id, group_config_block);
}
}
}
@ -1046,10 +1049,10 @@ 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);
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);
}
@ -1059,7 +1062,7 @@ static void rec_build_logical_tile_modules(
*/
if (0 < module_manager.configurable_children(pb_module).size()) {
add_module_nets_memory_config_bus(module_manager, decoder_lib, pb_module,
sram_orgz_type,
mem_module_type,
circuit_lib.design_tech_type(sram_model));
}
@ -1081,6 +1084,7 @@ static void build_physical_tile_module(
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& group_config_block,
const bool& verbose) {
/* Create a Module for the top-level physical block, and add to module manager
*/
@ -1133,13 +1137,17 @@ static void build_physical_tile_module(
*/
if (0 < find_module_num_config_bits(module_manager, pb_module,
circuit_lib, sram_model,
sram_orgz_type)) {
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);
pb_instance_id, true);
}
}
}
/* TODO: Add a physical memory block */
add_physical_memory_module(module_manager, grid_module);
/* 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 */
@ -1320,13 +1328,13 @@ void build_grid_modules(
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);
io_type_side, duplicate_grid_pin, group_config_block, verbose);
}
} 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,
&physical_tile, NUM_SIDES, duplicate_grid_pin, group_config_block,
verbose);
}
}

View File

@ -1005,12 +1005,14 @@ 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) {
const e_config_protocol_type& sram_orgz_type,
const bool& require_feedthrough_memory) {
vtr::ScopedStartFinishTimer timer("Build memory modules");
/* Create the memory circuits for the multiplexer */
@ -1027,6 +1029,7 @@ 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);
/* TODO: Create feedthrough memory module */
}
/* Create the memory circuits for non-MUX circuit models.
@ -1063,6 +1066,7 @@ 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);
/* TODO: Create feedthrough memory module */
}
}

View File

@ -26,7 +26,8 @@ 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);
const e_config_protocol_type& sram_orgz_type,
const bool& require_feedthrough_memory);
} /* end namespace openfpga */

View File

@ -461,6 +461,8 @@ static void build_switch_block_module(
}
}
/* TODO: Build a physical memory block */
/* 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
@ -1038,7 +1040,9 @@ 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();
@ -1082,7 +1086,9 @@ 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 */

View File

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

View File

@ -903,6 +903,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 bool& logical_only,
const vtr::Point<int> coord) {
/* Validate the id of both parent and child modules */
VTR_ASSERT(valid_module_id(parent_module));
@ -910,29 +911,35 @@ 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(
logical_configurable_children_[parent_module].push_back(child_module);
logical_configurable_child_instances_[parent_module].push_back(child_instance);
logical_configurable_child_regions_[parent_module].push_back(
ConfigRegionId::INVALID());
configurable_child_coordinates_[parent_module].push_back(coord);
logical_configurable_child_coordinates_[parent_module].push_back(coord);
if (!logical_only) {
physical_configurable_children_[parent_module].push_back(child_module);
physical_configurable_child_instances_[parent_module].push_back(child_instance);
physical_configurable_child_parents_[parent_module].push_back(parent_module);
}
}
void ModuleManager::reserve_configurable_child(const ModuleId& parent_module,
void ModuleManager::reserve_logical_configurable_child(const ModuleId& parent_module,
const size_t& num_children) {
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);
if (num_children > logical_configurable_children_[parent_module].size()) {
logical_configurable_children_[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 > logical_configurable_child_instances_[parent_module].size()) {
logical_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);
logical_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);
logical_configurable_child_coordinates_[parent_module].reserve(num_children);
}
}

View File

@ -358,6 +358,7 @@ class ModuleManager {
void add_configurable_child(
const ModuleId& module, const ModuleId& child_module,
const size_t& child_instance,
const bool& logical_only,
const vtr::Point<int> coord = vtr::Point<int>(-1, -1));
/* Reserved a number of configurable children for memory efficiency */
void reserve_configurable_child(const ModuleId& module,
@ -513,21 +514,31 @@ class ModuleManager {
* protocol is organized which should be made by users/designers
*/
vtr::vector<ModuleId, std::vector<ModuleId>>
configurable_children_; /* Child modules with configurable memory bits that
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<ConfigRegionId>>
configurable_child_regions_; /* Instances of child modules with configurable
logical_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
logical_configurable_child_coordinates_; /* Relative coorindates 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<ModuleId>>
physical_configurable_child_parents_; /* Parent modules with configurable memory bits that
this module contain */
/* Configurable regions to group the configurable children
/* Configurable regions to group the physical configurable children
* Note:
* - Each child can only be added a group
*/

View File

@ -342,6 +342,11 @@ 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 +405,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:

View File

@ -342,6 +342,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: {
@ -1730,6 +1731,7 @@ static void add_module_nets_cmos_memory_config_bus(
module_manager, parent_module, sram_orgz_type);
break;
}
case CONFIG_MEM_FEEDTHROUGH:
case CONFIG_MEM_STANDALONE:
case CONFIG_MEM_QL_MEMORY_BANK:
case CONFIG_MEM_MEMORY_BANK: