121 lines
5.0 KiB
C++
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 */
|