[core] code complete for the core wrapper creator. Start debugging
This commit is contained in:
parent
8bc70b590a
commit
c7ade72200
|
@ -12,6 +12,8 @@ namespace openfpga {
|
|||
|
||||
/* Top-level module name */
|
||||
constexpr const char* FPGA_TOP_MODULE_NAME = "fpga_top";
|
||||
constexpr const char* FPGA_CORE_MODULE_NAME = "fpga_core";
|
||||
constexpr const char* FPGA_CORE_INSTANCE_NAME = "fpga_instance";
|
||||
|
||||
/* Configuration chain naming constant strings */
|
||||
constexpr const char* CONFIGURABLE_MEMORY_CHAIN_IN_NAME = "ccff_head";
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "fabric_hierarchy_writer.h"
|
||||
#include "fabric_key_writer.h"
|
||||
#include "globals.h"
|
||||
#include "openfpga_naming.h"
|
||||
#include "read_xml_fabric_key.h"
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_time.h"
|
||||
|
@ -237,10 +238,20 @@ int write_fabric_io_info_template(const T& openfpga_ctx, const Command& cmd,
|
|||
template <class T>
|
||||
int add_fpga_core_to_fabric_template(T& openfpga_ctx, const Command& cmd,
|
||||
const CommandContext& cmd_context) {
|
||||
CommandOptionId opt_frame_view = cmd.option("frame_view");
|
||||
bool frame_view = cmd_context.option_enable(cmd, opt_frame_view);
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
bool verbose_output = cmd_context.option_enable(cmd, opt_verbose);
|
||||
|
||||
return add_fpga_core_to_device_module_graph(openfpga_ctx.mutable_module_graph(), verbose_output);
|
||||
CommandOptionId opt_inst_name = cmd.option("instance_name");
|
||||
std::string core_inst_name = generate_fpga_core_instance_name();
|
||||
if (true == cmd_context.option_enable(cmd, opt_inst_name)) {
|
||||
core_inst_name = cmd_context.option_value(cmd, opt_inst_name);
|
||||
}
|
||||
|
||||
return add_fpga_core_to_device_module_graph(
|
||||
openfpga_ctx.mutable_module_graph(), core_inst_name, frame_view,
|
||||
verbose_output);
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -1399,6 +1399,22 @@ std::string generate_fpga_top_module_name() {
|
|||
return std::string(FPGA_TOP_MODULE_NAME);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate the module name for the fpga core module
|
||||
* We give a fixed name here, because it is independent from benchmark file
|
||||
********************************************************************/
|
||||
std::string generate_fpga_core_module_name() {
|
||||
return std::string(FPGA_CORE_MODULE_NAME);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate the module name for the fpga core module
|
||||
* We give a fixed name here, because it is independent from benchmark file
|
||||
********************************************************************/
|
||||
std::string generate_fpga_core_instance_name() {
|
||||
return std::string(FPGA_CORE_INSTANCE_NAME);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Generate the netlist name for the top-level module
|
||||
* The top-level module is actually the FPGA fabric
|
||||
|
|
|
@ -258,6 +258,10 @@ std::string generate_fpga_global_io_port_name(
|
|||
|
||||
std::string generate_fpga_top_module_name();
|
||||
|
||||
std::string generate_fpga_core_module_name();
|
||||
|
||||
std::string generate_fpga_core_instance_name();
|
||||
|
||||
std::string generate_fpga_top_netlist_name(const std::string& postfix);
|
||||
|
||||
std::string generate_const_value_module_name(const size_t& const_val);
|
||||
|
|
|
@ -703,13 +703,25 @@ ShellCommandId add_add_fpga_core_to_fabric_command_template(
|
|||
const std::vector<ShellCommandId>& dependent_cmds, const bool& hidden) {
|
||||
Command shell_cmd("add_fpga_core_to_fabric");
|
||||
|
||||
/* Add an option '--instance_name'*/
|
||||
CommandOptionId opt_inst_name = shell_cmd.add_option(
|
||||
"instance_name", false, "specify the instance of fpga_core under fpga_top");
|
||||
shell_cmd.set_option_require_value(opt_inst_name, openfpga::OPT_STRING);
|
||||
|
||||
/* Add an option '--verbose' */
|
||||
shell_cmd.add_option(
|
||||
"frame_view", false,
|
||||
"Build only frame view of the fabric (nets are skipped)");
|
||||
/* Add an option '--verbose' */
|
||||
shell_cmd.add_option("verbose", false, "Show verbose outputs");
|
||||
|
||||
/* Add command 'pb_pin_fixup' to the Shell */
|
||||
ShellCommandId shell_cmd_id = shell.add_command(
|
||||
shell_cmd,
|
||||
"Add fpga_core as an intermediate layer to FPGA fabric. After this command, the fpga_top will remain the top-level module while there is a new module fpga_core under it. Under fpga_core, there will be the detailed building blocks",
|
||||
"Add fpga_core as an intermediate layer to FPGA fabric. After this "
|
||||
"command, the fpga_top will remain the top-level module while there is a "
|
||||
"new module fpga_core under it. Under fpga_core, there will be the "
|
||||
"detailed building blocks",
|
||||
hidden);
|
||||
shell.set_command_class(shell_cmd_id, cmd_class_id);
|
||||
shell.set_command_execute_function(shell_cmd_id,
|
||||
|
@ -906,8 +918,10 @@ void add_setup_command_templates(openfpga::Shell<T>& shell,
|
|||
* 'build_fabric' */
|
||||
std::vector<ShellCommandId> add_fpga_core_to_fabric_dependent_cmds;
|
||||
add_fpga_core_to_fabric_dependent_cmds.push_back(build_fabric_cmd_id);
|
||||
ShellCommandId add_fpga_core_to_fabric_cmd_id = add_add_fpga_core_to_fabric_command_template<T>(
|
||||
shell, openfpga_setup_cmd_class, add_fpga_core_to_fabric_dependent_cmds, hidden);
|
||||
ShellCommandId add_fpga_core_to_fabric_cmd_id =
|
||||
add_add_fpga_core_to_fabric_command_template<T>(
|
||||
shell, openfpga_setup_cmd_class, add_fpga_core_to_fabric_dependent_cmds,
|
||||
hidden);
|
||||
|
||||
/********************************
|
||||
* Command 'write_fabric_hierarchy'
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "build_top_module.h"
|
||||
#include "build_wire_modules.h"
|
||||
#include "command_exit_codes.h"
|
||||
#include "openfpga_naming.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
@ -127,11 +128,15 @@ int build_device_module_graph(
|
|||
}
|
||||
|
||||
/********************************************************************
|
||||
* The main function to be called for adding the fpga_core wrapper to a FPGA fabric
|
||||
* The main function to be called for adding the fpga_core wrapper to a FPGA
|
||||
*fabric
|
||||
* - Rename existing fpga_top to fpga_core
|
||||
* - Create a wrapper module 'fpga_top' on the fpga_core
|
||||
*******************************************************************/
|
||||
int add_fpga_core_to_device_module_graph(ModuleManager& module_manager, const bool& verbose) {
|
||||
int add_fpga_core_to_device_module_graph(ModuleManager& module_manager,
|
||||
const std::string& core_inst_name,
|
||||
const bool& frame_view,
|
||||
const bool& verbose) {
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
|
||||
/* Execute the module graph api */
|
||||
|
@ -140,15 +145,24 @@ int add_fpga_core_to_device_module_graph(ModuleManager& module_manager, const bo
|
|||
if (!module_manager.valid_module_id(top_module)) {
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
/* TODO: Use a constant for the top_module name */
|
||||
|
||||
/* Rename existing top module to fpga_core */
|
||||
module_manager.set_module_name(top_module, "fpga_core");
|
||||
std::string core_module_name = generate_fpga_core_module_name();
|
||||
module_manager.set_module_name(top_module, core_module_name);
|
||||
VTR_LOGV(verbose, "Rename current top-level module '%s' to '%s'\n",
|
||||
top_module_name.c_str(), core_module_name.c_str());
|
||||
|
||||
/* Create a wrapper module under the existing fpga_top */
|
||||
ModuleId new_top_module = module_manager.create_wrapper(top_module, top_module_name),
|
||||
ModuleId new_top_module = module_manager.create_wrapper_module(
|
||||
top_module, top_module_name, core_inst_name, frame_view);
|
||||
if (!module_manager.valid_module_id(new_top_module)) {
|
||||
VTR_LOGV_ERROR(verbose,
|
||||
"Failed to create a wrapper module '%s' on top of '%s'!\n",
|
||||
top_module_name.c_str(), core_module_name.c_str());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
VTR_LOGV(verbose, "Created a wrapper module '%s' on top of '%s'\n",
|
||||
top_module_name.c_str(), core_module_name.c_str());
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,10 @@ int build_device_module_graph(
|
|||
const bool& duplicate_grid_pin, const FabricKey& fabric_key,
|
||||
const bool& generate_random_fabric_key, const bool& verbose);
|
||||
|
||||
int add_fpga_core_to_device_module_graph(ModuleManager& module_manager, const bool& verbose);
|
||||
int add_fpga_core_to_device_module_graph(ModuleManager& module_manager,
|
||||
const std::string& core_inst_name,
|
||||
const bool& frame_view,
|
||||
const bool& verbose);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -768,6 +768,14 @@ void ModuleManager::set_port_is_wire(const ModuleId& module,
|
|||
port_is_wire_[module][port] = is_wire;
|
||||
}
|
||||
|
||||
/* Set a port to be a wire */
|
||||
void ModuleManager::set_port_is_wire(const ModuleId& module,
|
||||
const ModulePortId& port_id,
|
||||
const bool& is_wire) {
|
||||
VTR_ASSERT(valid_module_port_id(module, port_id));
|
||||
port_is_wire_[module][port_id] = is_wire;
|
||||
}
|
||||
|
||||
/* Set a port to be a mappable I/O */
|
||||
void ModuleManager::set_port_is_mappable_io(const ModuleId& module,
|
||||
const ModulePortId& port_id,
|
||||
|
@ -788,6 +796,14 @@ void ModuleManager::set_port_is_register(const ModuleId& module,
|
|||
port_is_register_[module][port] = is_register;
|
||||
}
|
||||
|
||||
/* Set a port to be a register */
|
||||
void ModuleManager::set_port_is_register(const ModuleId& module,
|
||||
const ModulePortId& port_id,
|
||||
const bool& is_register) {
|
||||
VTR_ASSERT(valid_module_port_id(module, port_id));
|
||||
port_is_register_[module][port_id] = is_register;
|
||||
}
|
||||
|
||||
/* Set the preprocessing flag for a port */
|
||||
void ModuleManager::set_port_preproc_flag(const ModuleId& module,
|
||||
const ModulePortId& port,
|
||||
|
@ -1185,6 +1201,93 @@ ModuleNetSinkId ModuleManager::add_module_net_sink(
|
|||
return net_sink;
|
||||
}
|
||||
|
||||
ModuleId ModuleManager::create_wrapper_module(
|
||||
const ModuleId& existing_module, const std::string& wrapper_module_name,
|
||||
const std::string& instance_name, const bool& add_nets) {
|
||||
/* Create a new module with the given name */
|
||||
ModuleId wrapper_module = add_module(wrapper_module_name);
|
||||
if (!wrapper_module) {
|
||||
return wrapper_module;
|
||||
}
|
||||
/* Add the existing module as an instance */
|
||||
add_child_module(wrapper_module, existing_module, false);
|
||||
set_child_instance_name(wrapper_module, existing_module, 0, instance_name);
|
||||
|
||||
/* A fast-lookup on the port linking: wrapper_module port -> existing_module
|
||||
* port */
|
||||
std::map<ModulePortId, ModulePortId> port_map;
|
||||
/* Herit ports */
|
||||
for (ModulePortId existing_port : module_ports(existing_module)) {
|
||||
/* Create new port */
|
||||
BasicPort existing_port_info = module_port(existing_module, existing_port);
|
||||
ModuleManager::e_module_port_type existing_port_type =
|
||||
port_type(existing_module, existing_port);
|
||||
ModulePortId new_port =
|
||||
add_port(wrapper_module, existing_port_info, existing_port_type);
|
||||
/* Set port attributes */
|
||||
set_port_is_wire(wrapper_module, new_port,
|
||||
port_is_wire(existing_module, existing_port));
|
||||
set_port_is_mappable_io(
|
||||
wrapper_module, new_port,
|
||||
port_is_mappable_io(existing_module, existing_port));
|
||||
set_port_is_register(wrapper_module, new_port,
|
||||
port_is_register(existing_module, existing_port));
|
||||
set_port_preproc_flag(wrapper_module, new_port,
|
||||
port_preproc_flag(existing_module, existing_port));
|
||||
/* Register in port mapping */
|
||||
port_map[new_port] = existing_port;
|
||||
}
|
||||
|
||||
/* Add nets */
|
||||
if (!add_nets) {
|
||||
return wrapper_module;
|
||||
}
|
||||
/* The number of nets are the sum of input and output pins */
|
||||
size_t num_nets_to_reserve = 0;
|
||||
for (ModulePortId new_port : module_ports(wrapper_module)) {
|
||||
BasicPort new_port_info = module_port(wrapper_module, new_port);
|
||||
num_nets_to_reserve += new_port_info.get_width();
|
||||
}
|
||||
reserve_module_nets(wrapper_module, num_nets_to_reserve);
|
||||
for (ModulePortId new_port : module_ports(wrapper_module)) {
|
||||
BasicPort new_port_info = module_port(wrapper_module, new_port);
|
||||
/* Create new net */
|
||||
ModuleNetId new_net = create_module_net(wrapper_module);
|
||||
VTR_ASSERT(valid_module_net_id(wrapper_module, new_net));
|
||||
/* For each input pin, create a new source */
|
||||
ModuleManager::e_module_port_type new_port_type =
|
||||
port_type(wrapper_module, new_port);
|
||||
/* Check if the pin size are matching or not */
|
||||
ModulePortId existing_port = port_map[new_port];
|
||||
BasicPort existing_port_info = module_port(existing_module, existing_port);
|
||||
VTR_ASSERT(existing_port_info == new_port_info);
|
||||
reserve_module_net_sources(wrapper_module, new_net,
|
||||
new_port_info.pins().size());
|
||||
reserve_module_net_sinks(wrapper_module, new_net,
|
||||
new_port_info.pins().size());
|
||||
if (new_port_type !=
|
||||
ModuleManager::e_module_port_type::MODULE_OUTPUT_PORT) {
|
||||
for (auto pin : new_port_info.pins()) {
|
||||
add_module_net_source(wrapper_module, new_net, wrapper_module, 0,
|
||||
new_port, pin);
|
||||
add_module_net_sink(wrapper_module, new_net, existing_module, 0,
|
||||
existing_port, pin);
|
||||
}
|
||||
} else {
|
||||
VTR_ASSERT_SAFE(new_port_type ==
|
||||
ModuleManager::e_module_port_type::MODULE_OUTPUT_PORT);
|
||||
for (auto pin : new_port_info.pins()) {
|
||||
add_module_net_source(wrapper_module, new_net, existing_module, 0,
|
||||
existing_port, pin);
|
||||
add_module_net_sink(wrapper_module, new_net, wrapper_module, 0,
|
||||
new_port, pin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wrapper_module;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Public Deconstructor
|
||||
******************************************************************************/
|
||||
|
|
|
@ -317,6 +317,8 @@ class ModuleManager {
|
|||
/* Set a port to be a wire */
|
||||
void set_port_is_wire(const ModuleId& module, const std::string& port_name,
|
||||
const bool& is_wire);
|
||||
void set_port_is_wire(const ModuleId& module, const ModulePortId& port_id,
|
||||
const bool& is_wire);
|
||||
/* Set a port to be mappable to an I/O from users' implemenations */
|
||||
void set_port_is_mappable_io(const ModuleId& module,
|
||||
const ModulePortId& port_id,
|
||||
|
@ -325,6 +327,8 @@ class ModuleManager {
|
|||
void set_port_is_register(const ModuleId& module,
|
||||
const std::string& port_name,
|
||||
const bool& is_register);
|
||||
void set_port_is_register(const ModuleId& module, const ModulePortId& port_id,
|
||||
const bool& is_register);
|
||||
/* Set the preprocessing flag for a port */
|
||||
void set_port_preproc_flag(const ModuleId& module, const ModulePortId& port,
|
||||
const std::string& preproc_flag);
|
||||
|
@ -423,6 +427,26 @@ class ModuleManager {
|
|||
const ModulePortId& sink_port,
|
||||
const size_t& sink_pin);
|
||||
|
||||
/** @brief Create a wrapper module on an existing module. The wrapper module
|
||||
* will herit all the ports with the same direction, width and names from the
|
||||
* selected module. The wrapper module will contain the existing module. For
|
||||
* example,
|
||||
*
|
||||
* Wrapper module
|
||||
* +------------------------+
|
||||
* | existing module |
|
||||
* | +------------------+ |
|
||||
* | | | |
|
||||
* a ->+->+ a b-+--+-> b
|
||||
* | | | |
|
||||
* | +------------------+ |
|
||||
* +------------------------+
|
||||
*/
|
||||
ModuleId create_wrapper_module(const ModuleId& existing_module,
|
||||
const std::string& wrapper_module_name,
|
||||
const std::string& instance_name,
|
||||
const bool& add_nets);
|
||||
|
||||
public: /* Public deconstructors */
|
||||
/* This is a strong function which will remove all the configurable children
|
||||
* under a given parent module
|
||||
|
|
Loading…
Reference in New Issue