fabric key can now accept instance name only; decoders are no longer part of the key
This commit is contained in:
parent
462fc0d04e
commit
824b56f14c
|
@ -29,8 +29,6 @@ void read_xml_component_key(pugi::xml_node& xml_component_key,
|
|||
|
||||
/* Find the id of component key */
|
||||
const size_t& id = get_attribute(xml_component_key, "id", loc_data).as_int();
|
||||
const std::string& name = get_attribute(xml_component_key, "name", loc_data).as_string();
|
||||
const size_t& value = get_attribute(xml_component_key, "value", loc_data).as_int();
|
||||
|
||||
if (false == fabric_key.valid_key_id(FabricKeyId(id))) {
|
||||
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_component_key),
|
||||
|
@ -40,14 +38,25 @@ void read_xml_component_key(pugi::xml_node& xml_component_key,
|
|||
|
||||
VTR_ASSERT_SAFE(true == fabric_key.valid_key_id(FabricKeyId(id)));
|
||||
|
||||
fabric_key.set_key_name(FabricKeyId(id), name);
|
||||
fabric_key.set_key_value(FabricKeyId(id), value);
|
||||
|
||||
/* If we have an alias, set the value as well */
|
||||
const std::string& alias = get_attribute(xml_component_key, "alias", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string();
|
||||
if (!alias.empty()) {
|
||||
fabric_key.set_key_alias(FabricKeyId(id), alias);
|
||||
}
|
||||
|
||||
/* If we have the alias set, name and valus are optional then
|
||||
* Otherwise, they are mandatory attributes
|
||||
*/
|
||||
pugiutil::ReqOpt required_name_value = pugiutil::ReqOpt::OPTIONAL;
|
||||
if (true == alias.empty()) {
|
||||
required_name_value = pugiutil::ReqOpt::REQUIRED;
|
||||
}
|
||||
|
||||
const std::string& name = get_attribute(xml_component_key, "name", loc_data, required_name_value).as_string();
|
||||
const size_t& value = get_attribute(xml_component_key, "value", loc_data, required_name_value).as_int();
|
||||
|
||||
fabric_key.set_key_name(FabricKeyId(id), name);
|
||||
fabric_key.set_key_value(FabricKeyId(id), value);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
|
|
@ -40,7 +40,9 @@ int write_xml_fabric_component_key(std::fstream& fp,
|
|||
}
|
||||
|
||||
write_xml_attribute(fp, "id", size_t(component_key));
|
||||
if (!fabric_key.key_name(component_key).empty()) {
|
||||
write_xml_attribute(fp, "name", fabric_key.key_name(component_key).c_str());
|
||||
}
|
||||
write_xml_attribute(fp, "value", fabric_key.key_value(component_key));
|
||||
|
||||
if (!fabric_key.key_alias(component_key).empty()) {
|
||||
|
|
|
@ -83,6 +83,12 @@ int build_fabric(OpenfpgaContext& openfpga_ctx,
|
|||
|
||||
VTR_LOG("\n");
|
||||
|
||||
/* Record the execution status in curr_status for each command
|
||||
* and summarize them in the final status
|
||||
*/
|
||||
int curr_status = CMD_EXEC_SUCCESS;
|
||||
int final_status = CMD_EXEC_SUCCESS;
|
||||
|
||||
/* Load fabric key from file */
|
||||
FabricKey predefined_fabric_key;
|
||||
if (true == cmd_context.option_enable(cmd, opt_load_fabric_key)) {
|
||||
|
@ -93,7 +99,8 @@ int build_fabric(OpenfpgaContext& openfpga_ctx,
|
|||
|
||||
VTR_LOG("\n");
|
||||
|
||||
openfpga_ctx.mutable_module_graph() = build_device_module_graph(openfpga_ctx.mutable_io_location_map(),
|
||||
curr_status = build_device_module_graph(openfpga_ctx.mutable_module_graph(),
|
||||
openfpga_ctx.mutable_io_location_map(),
|
||||
openfpga_ctx.mutable_decoder_lib(),
|
||||
const_cast<const OpenfpgaContext&>(openfpga_ctx),
|
||||
g_vpr_ctx.device(),
|
||||
|
@ -104,18 +111,26 @@ int build_fabric(OpenfpgaContext& openfpga_ctx,
|
|||
cmd_context.option_enable(cmd, opt_gen_random_fabric_key),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* If there is any error, final status cannot be overwritten by a success flag */
|
||||
if (CMD_EXEC_SUCCESS != curr_status) {
|
||||
final_status = curr_status;
|
||||
}
|
||||
|
||||
/* Output fabric key if user requested */
|
||||
if (true == cmd_context.option_enable(cmd, opt_write_fabric_key)) {
|
||||
std::string fkey_fname = cmd_context.option_value(cmd, opt_write_fabric_key);
|
||||
VTR_ASSERT(false == fkey_fname.empty());
|
||||
write_fabric_key_to_xml_file(openfpga_ctx.module_graph(),
|
||||
curr_status = write_fabric_key_to_xml_file(openfpga_ctx.module_graph(),
|
||||
fkey_fname,
|
||||
openfpga_ctx.arch().config_protocol.type(),
|
||||
cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
/* If there is any error, final status cannot be overwritten by a success flag */
|
||||
if (CMD_EXEC_SUCCESS != curr_status) {
|
||||
final_status = curr_status;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: should identify the error code from internal function execution */
|
||||
return CMD_EXEC_SUCCESS;
|
||||
return final_status;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
#include "vtr_log.h"
|
||||
#include "vtr_time.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
#include "build_essential_modules.h"
|
||||
#include "build_decoder_modules.h"
|
||||
#include "build_mux_modules.h"
|
||||
|
@ -26,7 +29,8 @@ namespace openfpga {
|
|||
* The main function to be called for building module graphs
|
||||
* for a FPGA fabric
|
||||
*******************************************************************/
|
||||
ModuleManager build_device_module_graph(IoLocationMap& io_location_map,
|
||||
int build_device_module_graph(ModuleManager& module_manager,
|
||||
IoLocationMap& io_location_map,
|
||||
DecoderLibrary& decoder_lib,
|
||||
const OpenfpgaContext& openfpga_ctx,
|
||||
const DeviceContext& vpr_device_ctx,
|
||||
|
@ -38,8 +42,7 @@ ModuleManager build_device_module_graph(IoLocationMap& io_location_map,
|
|||
const bool& verbose) {
|
||||
vtr::ScopedStartFinishTimer timer("Build fabric module graph");
|
||||
|
||||
/* Module manager to be built */
|
||||
ModuleManager module_manager;
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
|
||||
CircuitModelId sram_model = openfpga_ctx.arch().config_protocol.memory_model();
|
||||
VTR_ASSERT(true == openfpga_ctx.arch().circuit_lib.valid_model_id(sram_model));
|
||||
|
@ -108,7 +111,7 @@ ModuleManager build_device_module_graph(IoLocationMap& io_location_map,
|
|||
}
|
||||
|
||||
/* Build FPGA fabric top-level module */
|
||||
build_top_module(module_manager,
|
||||
status = build_top_module(module_manager,
|
||||
io_location_map,
|
||||
decoder_lib,
|
||||
openfpga_ctx.arch().circuit_lib,
|
||||
|
@ -122,6 +125,10 @@ ModuleManager build_device_module_graph(IoLocationMap& io_location_map,
|
|||
frame_view, compress_routing, duplicate_grid_pin,
|
||||
fabric_key, generate_random_fabric_key);
|
||||
|
||||
if (CMD_EXEC_FATAL_ERROR == status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Now a critical correction has to be done!
|
||||
* In the module construction, we always use prefix of ports because they are binded
|
||||
* to the ports in architecture description (logic blocks etc.)
|
||||
|
@ -131,7 +138,7 @@ ModuleManager build_device_module_graph(IoLocationMap& io_location_map,
|
|||
*/
|
||||
rename_primitive_module_port_names(module_manager, openfpga_ctx.arch().circuit_lib);
|
||||
|
||||
return module_manager;
|
||||
return status;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
ModuleManager build_device_module_graph(IoLocationMap& io_location_map,
|
||||
int build_device_module_graph(ModuleManager& module_manager,
|
||||
IoLocationMap& io_location_map,
|
||||
DecoderLibrary& decoder_lib,
|
||||
const OpenfpgaContext& openfpga_ctx,
|
||||
const DeviceContext& vpr_device_ctx,
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
/* Headers from vpr library */
|
||||
#include "vpr_utils.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
#include "rr_gsb_utils.h"
|
||||
#include "openfpga_reserved_words.h"
|
||||
#include "openfpga_naming.h"
|
||||
|
@ -318,7 +321,7 @@ vtr::Matrix<size_t> add_top_module_connection_block_instances(ModuleManager& mod
|
|||
* 4. Add module nets to connect datapath ports
|
||||
* 5. Add module nets/submodules to connect configuration ports
|
||||
*******************************************************************/
|
||||
void build_top_module(ModuleManager& module_manager,
|
||||
int build_top_module(ModuleManager& module_manager,
|
||||
IoLocationMap& io_location_map,
|
||||
DecoderLibrary& decoder_lib,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
|
@ -337,6 +340,8 @@ void build_top_module(ModuleManager& module_manager,
|
|||
|
||||
vtr::ScopedStartFinishTimer timer("Build FPGA fabric module");
|
||||
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
|
||||
/* Create a module as the top-level fabric, and add it to the module manager */
|
||||
std::string top_module_name = generate_fpga_top_module_name();
|
||||
ModuleId top_module = module_manager.add_module(top_module_name);
|
||||
|
@ -397,8 +402,11 @@ void build_top_module(ModuleManager& module_manager,
|
|||
compact_routing_hierarchy);
|
||||
} else {
|
||||
VTR_ASSERT_SAFE(false == fabric_key.empty());
|
||||
load_top_module_memory_modules_from_fabric_key(module_manager, top_module,
|
||||
status = load_top_module_memory_modules_from_fabric_key(module_manager, top_module,
|
||||
fabric_key);
|
||||
if (CMD_EXEC_FATAL_ERROR == status) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shuffle the configurable children in a random sequence */
|
||||
|
@ -435,6 +443,8 @@ void build_top_module(ModuleManager& module_manager,
|
|||
sram_orgz_type, circuit_lib.design_tech_type(sram_model),
|
||||
module_num_config_bits);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void build_top_module(ModuleManager& module_manager,
|
||||
int build_top_module(ModuleManager& module_manager,
|
||||
IoLocationMap& io_location_map,
|
||||
DecoderLibrary& decoder_lib,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
/* Headers from vpr library */
|
||||
#include "vpr_utils.h"
|
||||
|
||||
/* Headers from openfpgashell library */
|
||||
#include "command_exit_codes.h"
|
||||
|
||||
#include "rr_gsb_utils.h"
|
||||
#include "openfpga_reserved_words.h"
|
||||
#include "openfpga_naming.h"
|
||||
|
@ -419,36 +422,47 @@ int load_top_module_memory_modules_from_fabric_key(ModuleManager& module_manager
|
|||
module_manager.clear_configurable_children(top_module);
|
||||
|
||||
for (const FabricKeyId& key : fabric_key.keys()) {
|
||||
/* Find if the module name exist */
|
||||
ModuleId child_module = module_manager.find_module(fabric_key.key_name(key));
|
||||
if (false == module_manager.valid_module_id(child_module)) {
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid key name '%s'!\n",
|
||||
fabric_key.key_name(key).c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Find if instance id is valid */
|
||||
size_t child_instance = fabric_key.key_value(key);
|
||||
/* If we have alias, we try to find a instance in this name */
|
||||
std::pair<ModuleId, size_t> instance_info(ModuleId::INVALID(), 0);
|
||||
/* If we have an alias, we try to find a instance in this name */
|
||||
if (!fabric_key.key_alias(key).empty()) {
|
||||
child_instance = module_manager.instance_id(top_module, child_module, fabric_key.key_alias(key));
|
||||
/* Find the module id and instance id */
|
||||
instance_info = find_module_manager_instance_module_info(module_manager, top_module, fabric_key.key_alias(key));
|
||||
} else {
|
||||
/* If we do not have an alias, we use the name and value to build the info deck */
|
||||
instance_info.first = module_manager.find_module(fabric_key.key_name(key));
|
||||
instance_info.second = fabric_key.key_value(key);
|
||||
}
|
||||
|
||||
if (child_instance >= module_manager.num_instance(top_module, child_module)) {
|
||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||
"Invalid key value '%ld'!\n",
|
||||
child_instance);
|
||||
return 1;
|
||||
if (false == module_manager.valid_module_id(instance_info.first)) {
|
||||
if (!fabric_key.key_alias(key).empty()) {
|
||||
VTR_LOG_ERROR("Invalid key alias '%s'!\n",
|
||||
fabric_key.key_alias(key).c_str());
|
||||
} else {
|
||||
VTR_LOG_ERROR("Invalid key name '%s'!\n",
|
||||
fabric_key.key_name(key).c_str());
|
||||
}
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
if (false == module_manager.valid_module_instance_id(top_module, instance_info.first, instance_info.second)) {
|
||||
if (!fabric_key.key_alias(key).empty()) {
|
||||
VTR_LOG_ERROR("Invalid key alias '%s'!\n",
|
||||
fabric_key.key_alias(key).c_str());
|
||||
} else {
|
||||
VTR_LOG_ERROR("Invalid key value '%ld'!\n",
|
||||
instance_info.second);
|
||||
}
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* Now we can add the child to configurable children of the top module */
|
||||
module_manager.add_configurable_child(top_module,
|
||||
child_module,
|
||||
child_instance);
|
||||
instance_info.first,
|
||||
instance_info.second);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace openfpga {
|
|||
***************************************************************************************/
|
||||
int write_fabric_key_to_xml_file(const ModuleManager& module_manager,
|
||||
const std::string& fname,
|
||||
const e_config_protocol_type& config_protocol_type,
|
||||
const bool& verbose) {
|
||||
std::string timer_message = std::string("Write fabric key to XML file '") + fname + std::string("'");
|
||||
|
||||
|
@ -56,6 +57,14 @@ int write_fabric_key_to_xml_file(const ModuleManager& module_manager,
|
|||
/* 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();
|
||||
|
||||
/* Exclude configuration-related modules in the keys */
|
||||
if (CONFIG_MEM_MEMORY_BANK == config_protocol_type) {
|
||||
num_keys -= 2;
|
||||
} else if (CONFIG_MEM_FRAME_BASED == config_protocol_type) {
|
||||
num_keys -= 1;
|
||||
}
|
||||
|
||||
fabric_key.reserve_keys(num_keys);
|
||||
|
||||
for (size_t ichild = 0; ichild < num_keys; ++ichild) {
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace openfpga {
|
|||
|
||||
int write_fabric_key_to_xml_file(const ModuleManager& module_manager,
|
||||
const std::string& fname,
|
||||
const e_config_protocol_type& config_protocol_type,
|
||||
const bool& verbose);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -892,6 +892,16 @@ bool ModuleManager::valid_module_net_id(const ModuleId& module, const ModuleNetI
|
|||
return ( size_t(net) < num_nets_[module] );
|
||||
}
|
||||
|
||||
bool ModuleManager::valid_module_instance_id(const ModuleId& parent_module,
|
||||
const ModuleId& child_module,
|
||||
const size_t& instance_id) const {
|
||||
if ( (false == valid_module_id(parent_module))
|
||||
|| (false == valid_module_id(child_module))) {
|
||||
return false;
|
||||
}
|
||||
return ( instance_id < num_instance(parent_module, child_module) );
|
||||
}
|
||||
|
||||
void ModuleManager::invalidate_name2id_map() {
|
||||
name_id_map_.clear();
|
||||
}
|
||||
|
|
|
@ -285,6 +285,9 @@ class ModuleManager {
|
|||
bool valid_module_id(const ModuleId& module) const;
|
||||
bool valid_module_port_id(const ModuleId& module, const ModulePortId& port) const;
|
||||
bool valid_module_net_id(const ModuleId& module, const ModuleNetId& net) const;
|
||||
bool valid_module_instance_id(const ModuleId& parent_module,
|
||||
const ModuleId& child_module,
|
||||
const size_t& instance_id) const;
|
||||
private: /* Private validators/invalidators */
|
||||
void invalidate_name2id_map();
|
||||
void invalidate_port_lookup();
|
||||
|
|
|
@ -93,6 +93,30 @@ size_t count_module_manager_module_configurable_children(const ModuleManager& mo
|
|||
return num_config_children;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Find the module id and instance id in module manager with a given instance name
|
||||
* This function will exhaustively search all the child module under a given parent
|
||||
* module
|
||||
******************************************************************************/
|
||||
std::pair<ModuleId, size_t> find_module_manager_instance_module_info(const ModuleManager& module_manager,
|
||||
const ModuleId& parent,
|
||||
const std::string& instance_name) {
|
||||
/* Deposit invalid values as default */
|
||||
std::pair<ModuleId, size_t> instance_info(ModuleId::INVALID(), 0);
|
||||
|
||||
/* Search all the child module and see we have a match */
|
||||
for (const ModuleId& child : module_manager.child_modules(parent)) {
|
||||
size_t child_instance = module_manager.instance_id(parent, child, instance_name);
|
||||
if (true == module_manager.valid_module_instance_id(parent, child, child_instance)) {
|
||||
instance_info.first = child;
|
||||
instance_info.second = child_instance;
|
||||
return instance_info;
|
||||
}
|
||||
}
|
||||
|
||||
return instance_info;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Add a module to the module manager based on the circuit-level
|
||||
* description of a circuit model
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
/* Headers from readarch library */
|
||||
#include "physical_types.h"
|
||||
|
@ -37,6 +38,10 @@ void reserve_module_manager_module_nets(ModuleManager& module_manager,
|
|||
size_t count_module_manager_module_configurable_children(const ModuleManager& module_manager,
|
||||
const ModuleId& module);
|
||||
|
||||
std::pair<ModuleId, size_t> find_module_manager_instance_module_info(const ModuleManager& module_manager,
|
||||
const ModuleId& parent,
|
||||
const std::string& instance_name);
|
||||
|
||||
ModuleId add_circuit_model_to_module_manager(ModuleManager& module_manager,
|
||||
const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model,
|
||||
const std::string& module_name);
|
||||
|
|
|
@ -32,5 +32,4 @@
|
|||
<key id="30" name="cbx_1__1_" value="0" alias="cbx_1__1_"/>
|
||||
<key id="31" name="grid_io_top" value="0" alias="grid_io_top_1_3"/>
|
||||
<key id="32" name="grid_io_left" value="1" alias="grid_io_left_0_2"/>
|
||||
<key id="33" name="decoder6to33" value="0"/>
|
||||
</fabric_key>
|
||||
|
|
Loading…
Reference in New Issue