OpenFPGA/openfpga/src/fabric/build_fabric_global_port_in...

121 lines
5.0 KiB
C++

/********************************************************************
* This file includes functions that are used to build the global port
* information for the top-level module of the FPGA fabric
* It helps OpenFPGA to build testbenches with the attributes of the global
*ports
*******************************************************************/
#include <algorithm>
#include <map>
/* Headers from vtrutil library */
#include "build_fabric_global_port_info.h"
#include "circuit_library_utils.h"
#include "openfpga_naming.h"
#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_time.h"
/* begin namespace openfpga */
namespace openfpga {
/********************************************************************
* Find all the GPIO ports in the grid module
* and cache their port/pin index in the top-level module
*******************************************************************/
FabricGlobalPortInfo build_fabric_global_port_info(
const ModuleManager& module_manager, const ConfigProtocol& config_protocol,
const TileAnnotation& tile_annotation, const CircuitLibrary& circuit_lib) {
vtr::ScopedStartFinishTimer timer("Create global port info for top module");
FabricGlobalPortInfo fabric_global_port_info;
/* Find top-level module */
std::string top_module_name = generate_fpga_top_module_name();
ModuleId top_module = module_manager.find_module(top_module_name);
if (true != module_manager.valid_module_id(top_module)) {
VTR_LOG_ERROR("Unable to find the top-level module '%s'!\n",
top_module_name.c_str());
exit(1);
}
/* Add the global ports from circuit library */
for (const CircuitPortId& global_port :
find_circuit_library_global_ports(circuit_lib)) {
/* We should find a port in the top module */
ModulePortId module_port = module_manager.find_module_port(
top_module, circuit_lib.port_prefix(global_port));
/* Only add those ports have been defined in top-level module */
if (false == module_manager.valid_module_port_id(top_module, module_port)) {
continue;
}
/* Add the port information */
FabricGlobalPortId fabric_port =
fabric_global_port_info.create_global_port(module_port);
fabric_global_port_info.set_global_port_is_clock(
fabric_port,
CIRCUIT_MODEL_PORT_CLOCK == circuit_lib.port_type(global_port));
fabric_global_port_info.set_global_port_is_reset(
fabric_port, circuit_lib.port_is_reset(global_port));
fabric_global_port_info.set_global_port_is_set(
fabric_port, circuit_lib.port_is_set(global_port));
fabric_global_port_info.set_global_port_is_prog(
fabric_port, circuit_lib.port_is_prog(global_port));
fabric_global_port_info.set_global_port_is_shift_register(
fabric_port, circuit_lib.port_is_shift_register(global_port));
fabric_global_port_info.set_global_port_is_config_enable(
fabric_port, circuit_lib.port_is_config_enable(global_port));
fabric_global_port_info.set_global_port_default_value(
fabric_port, circuit_lib.port_default_value(global_port));
/* Special for BL/WL shift register models: we should identify which clock
* belongs to BL and which clock belongs to WL */
if (config_protocol.bl_memory_model() ==
circuit_lib.port_parent_model(global_port)) {
fabric_global_port_info.set_global_port_is_bl(fabric_port, true);
}
if (config_protocol.wl_memory_model() ==
circuit_lib.port_parent_model(global_port)) {
fabric_global_port_info.set_global_port_is_wl(fabric_port, true);
}
}
/* Add the global ports from tile annotation */
for (const TileGlobalPortId& global_port : tile_annotation.global_ports()) {
/* We should find a port in the top module */
ModulePortId module_port = module_manager.find_module_port(
top_module, tile_annotation.global_port_name(global_port));
/* Only add those ports have been defined in top-level module */
if (false == module_manager.valid_module_port_id(top_module, module_port)) {
continue;
}
/* Avoid adding redundant ports */
bool already_in_list = false;
for (const FabricGlobalPortId& port :
fabric_global_port_info.global_ports()) {
if (module_port == fabric_global_port_info.global_module_port(port)) {
already_in_list = true;
break;
}
}
if (true == already_in_list) {
continue;
}
/* Add the port information */
FabricGlobalPortId fabric_port =
fabric_global_port_info.create_global_port(module_port);
fabric_global_port_info.set_global_port_is_clock(
fabric_port, tile_annotation.global_port_is_clock(global_port));
fabric_global_port_info.set_global_port_is_reset(
fabric_port, tile_annotation.global_port_is_reset(global_port));
fabric_global_port_info.set_global_port_is_set(
fabric_port, tile_annotation.global_port_is_set(global_port));
fabric_global_port_info.set_global_port_default_value(
fabric_port, tile_annotation.global_port_default_value(global_port));
}
return fabric_global_port_info;
}
} /* end namespace openfpga */