From dcb50e4f19e3022066dcac00511975e7966bc5da Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 10 Nov 2020 19:07:28 -0700 Subject: [PATCH] [Tool] Use use standard data structure to store global port information --- openfpga/src/base/openfpga_build_fabric.cpp | 6 + openfpga/src/base/openfpga_context.h | 4 + openfpga/src/base/openfpga_verilog.cpp | 1 + .../fabric/build_fabric_global_port_info.cpp | 90 +++++++++++ .../fabric/build_fabric_global_port_info.h | 27 ++++ .../src/fabric/fabric_global_port_info.cpp | 137 ++++++++++++++++ openfpga/src/fabric/fabric_global_port_info.h | 79 ++++++++++ .../src/fabric/fabric_global_port_info_fwd.h | 22 +++ openfpga/src/fpga_verilog/verilog_api.cpp | 10 +- openfpga/src/fpga_verilog/verilog_api.h | 2 + .../verilog_preconfig_top_module.cpp | 49 ++---- .../verilog_preconfig_top_module.h | 3 +- .../fpga_verilog/verilog_top_testbench.cpp | 149 ++++++------------ .../src/fpga_verilog/verilog_top_testbench.h | 5 +- .../utils/fabric_global_port_info_utils.cpp | 61 +++++++ .../src/utils/fabric_global_port_info_utils.h | 23 +++ 16 files changed, 518 insertions(+), 150 deletions(-) create mode 100644 openfpga/src/fabric/build_fabric_global_port_info.cpp create mode 100644 openfpga/src/fabric/build_fabric_global_port_info.h create mode 100644 openfpga/src/fabric/fabric_global_port_info.cpp create mode 100644 openfpga/src/fabric/fabric_global_port_info.h create mode 100644 openfpga/src/fabric/fabric_global_port_info_fwd.h create mode 100644 openfpga/src/utils/fabric_global_port_info_utils.cpp create mode 100644 openfpga/src/utils/fabric_global_port_info_utils.h diff --git a/openfpga/src/base/openfpga_build_fabric.cpp b/openfpga/src/base/openfpga_build_fabric.cpp index b5793cdb6..08e9ef4f8 100644 --- a/openfpga/src/base/openfpga_build_fabric.cpp +++ b/openfpga/src/base/openfpga_build_fabric.cpp @@ -17,6 +17,7 @@ #include "fabric_hierarchy_writer.h" #include "fabric_key_writer.h" #include "build_fabric_io_location_map.h" +#include "build_fabric_global_port_info.h" #include "openfpga_build_fabric.h" /* Include global variables of VPR */ @@ -120,6 +121,11 @@ int build_fabric(OpenfpgaContext& openfpga_ctx, openfpga_ctx.mutable_io_location_map() = build_fabric_io_location_map(openfpga_ctx.module_graph(), g_vpr_ctx.device().grid); + /* Build fabric global port information */ + openfpga_ctx.mutable_fabric_global_port_info() = build_fabric_global_port_info(openfpga_ctx.module_graph(), + openfpga_ctx.arch().tile_annotations, + openfpga_ctx.arch().circuit_lib); + /* 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); diff --git a/openfpga/src/base/openfpga_context.h b/openfpga/src/base/openfpga_context.h index 47427a452..c59219ed2 100644 --- a/openfpga/src/base/openfpga_context.h +++ b/openfpga/src/base/openfpga_context.h @@ -19,6 +19,7 @@ #include "fabric_bitstream.h" #include "device_rr_gsb.h" #include "io_location_map.h" +#include "fabric_global_port_info.h" /******************************************************************** * This file includes the declaration of the date structure @@ -65,6 +66,7 @@ class OpenfpgaContext : public Context { const openfpga::BitstreamManager& bitstream_manager() const { return bitstream_manager_; } const openfpga::FabricBitstream& fabric_bitstream() const { return fabric_bitstream_; } const openfpga::IoLocationMap& io_location_map() const { return io_location_map_; } + const openfpga::FabricGlobalPortInfo& fabric_global_port_info() const { return fabric_global_port_info_; } const std::unordered_map& net_activity() const { return net_activity_; } const openfpga::NetlistManager& verilog_netlists() const { return verilog_netlists_; } const openfpga::NetlistManager& spice_netlists() const { return spice_netlists_; } @@ -85,6 +87,7 @@ class OpenfpgaContext : public Context { openfpga::BitstreamManager& mutable_bitstream_manager() { return bitstream_manager_; } openfpga::FabricBitstream& mutable_fabric_bitstream() { return fabric_bitstream_; } openfpga::IoLocationMap& mutable_io_location_map() { return io_location_map_; } + openfpga::FabricGlobalPortInfo& mutable_fabric_global_port_info() { return fabric_global_port_info_; } std::unordered_map& mutable_net_activity() { return net_activity_; } openfpga::NetlistManager& mutable_verilog_netlists() { return verilog_netlists_; } openfpga::NetlistManager& mutable_spice_netlists() { return spice_netlists_; } @@ -123,6 +126,7 @@ class OpenfpgaContext : public Context { /* Fabric module graph */ openfpga::ModuleManager module_graph_; openfpga::IoLocationMap io_location_map_; + openfpga::FabricGlobalPortInfo fabric_global_port_info_; /* Bitstream database */ openfpga::BitstreamManager bitstream_manager_; diff --git a/openfpga/src/base/openfpga_verilog.cpp b/openfpga/src/base/openfpga_verilog.cpp index 69c0b60d4..efa77aaf7 100644 --- a/openfpga/src/base/openfpga_verilog.cpp +++ b/openfpga/src/base/openfpga_verilog.cpp @@ -96,6 +96,7 @@ int write_verilog_testbench(OpenfpgaContext& openfpga_ctx, g_vpr_ctx.atom(), g_vpr_ctx.placement(), openfpga_ctx.io_location_map(), + openfpga_ctx.fabric_global_port_info(), openfpga_ctx.vpr_netlist_annotation(), openfpga_ctx.arch().circuit_lib, openfpga_ctx.simulation_setting(), diff --git a/openfpga/src/fabric/build_fabric_global_port_info.cpp b/openfpga/src/fabric/build_fabric_global_port_info.cpp new file mode 100644 index 000000000..44a09d199 --- /dev/null +++ b/openfpga/src/fabric/build_fabric_global_port_info.cpp @@ -0,0 +1,90 @@ +/******************************************************************** + * 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 +#include + +/* Headers from vtrutil library */ +#include "vtr_assert.h" +#include "vtr_time.h" +#include "vtr_log.h" + +#include "openfpga_naming.h" + +#include "circuit_library_utils.h" +#include "build_fabric_global_port_info.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 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_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)); + } + + /* 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 */ diff --git a/openfpga/src/fabric/build_fabric_global_port_info.h b/openfpga/src/fabric/build_fabric_global_port_info.h new file mode 100644 index 000000000..5625d379f --- /dev/null +++ b/openfpga/src/fabric/build_fabric_global_port_info.h @@ -0,0 +1,27 @@ +#ifndef BUILD_FABRIC_GLOBAL_PORT_INFO_H +#define BUILD_FABRIC_GLOBAL_PORT_INFO_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ + +#include +#include "tile_annotation.h" +#include "circuit_library.h" +#include "fabric_global_port_info.h" +#include "module_manager.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +FabricGlobalPortInfo build_fabric_global_port_info(const ModuleManager& module_manager, + const TileAnnotation& tile_annotation, + const CircuitLibrary& circuit_lib); + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/fabric/fabric_global_port_info.cpp b/openfpga/src/fabric/fabric_global_port_info.cpp new file mode 100644 index 000000000..08ea8444d --- /dev/null +++ b/openfpga/src/fabric/fabric_global_port_info.cpp @@ -0,0 +1,137 @@ +/************************************************************************ + * Member functions for class FabricGlobalPortInfo + ***********************************************************************/ +#include "vtr_assert.h" + +#include "fabric_global_port_info.h" + +/* namespace openfpga begins */ +namespace openfpga { + +/************************************************************************ + * Constructors + ***********************************************************************/ +FabricGlobalPortInfo::FabricGlobalPortInfo() { + return; +} + +/************************************************************************ + * Public Accessors : aggregates + ***********************************************************************/ +FabricGlobalPortInfo::global_port_range FabricGlobalPortInfo::global_ports() const { + return vtr::make_range(global_port_ids_.begin(), global_port_ids_.end()); +} + +/************************************************************************ + * Public Accessors + ***********************************************************************/ +ModulePortId FabricGlobalPortInfo::global_module_port(const FabricGlobalPortId& global_port_id) const { + VTR_ASSERT(valid_global_port_id(global_port_id)); + return global_module_ports_[global_port_id]; +} + +bool FabricGlobalPortInfo::global_port_is_clock(const FabricGlobalPortId& global_port_id) const { + VTR_ASSERT(valid_global_port_id(global_port_id)); + return global_port_is_clock_[global_port_id]; +} + +bool FabricGlobalPortInfo::global_port_is_set(const FabricGlobalPortId& global_port_id) const { + VTR_ASSERT(valid_global_port_id(global_port_id)); + return global_port_is_set_[global_port_id]; +} + +bool FabricGlobalPortInfo::global_port_is_reset(const FabricGlobalPortId& global_port_id) const { + VTR_ASSERT(valid_global_port_id(global_port_id)); + return global_port_is_reset_[global_port_id]; +} + +bool FabricGlobalPortInfo::global_port_is_prog(const FabricGlobalPortId& global_port_id) const { + VTR_ASSERT(valid_global_port_id(global_port_id)); + return global_port_is_prog_[global_port_id]; +} + +bool FabricGlobalPortInfo::global_port_is_config_enable(const FabricGlobalPortId& global_port_id) const { + VTR_ASSERT(valid_global_port_id(global_port_id)); + return global_port_is_config_enable_[global_port_id]; +} + +bool FabricGlobalPortInfo::global_port_is_io(const FabricGlobalPortId& global_port_id) const { + VTR_ASSERT(valid_global_port_id(global_port_id)); + return global_port_is_io_[global_port_id]; +} + +size_t FabricGlobalPortInfo::global_port_default_value(const FabricGlobalPortId& global_port_id) const { + VTR_ASSERT(valid_global_port_id(global_port_id)); + return global_port_default_values_[global_port_id]; +} + +/************************************************************************ + * Public Mutators + ***********************************************************************/ +FabricGlobalPortId FabricGlobalPortInfo::create_global_port(const ModulePortId& module_port) { + /* This is a legal name. we can create a new id */ + FabricGlobalPortId port_id = FabricGlobalPortId(global_port_ids_.size()); + global_port_ids_.push_back(port_id); + global_module_ports_.push_back(module_port); + global_port_is_clock_.push_back(false); + global_port_is_set_.push_back(false); + global_port_is_reset_.push_back(false); + global_port_is_prog_.push_back(false); + global_port_is_io_.push_back(false); + global_port_is_config_enable_.push_back(false); + global_port_default_values_.push_back(0); + + return port_id; +} + +void FabricGlobalPortInfo::set_global_port_is_clock(const FabricGlobalPortId& global_port_id, + const bool& is_clock) { + VTR_ASSERT(valid_global_port_id(global_port_id)); + global_port_is_clock_[global_port_id] = is_clock; +} + +void FabricGlobalPortInfo::set_global_port_is_set(const FabricGlobalPortId& global_port_id, + const bool& is_set) { + VTR_ASSERT(valid_global_port_id(global_port_id)); + global_port_is_set_[global_port_id] = is_set; +} + +void FabricGlobalPortInfo::set_global_port_is_reset(const FabricGlobalPortId& global_port_id, + const bool& is_reset) { + VTR_ASSERT(valid_global_port_id(global_port_id)); + global_port_is_reset_[global_port_id] = is_reset; +} + +void FabricGlobalPortInfo::set_global_port_is_prog(const FabricGlobalPortId& global_port_id, + const bool& is_prog) { + VTR_ASSERT(valid_global_port_id(global_port_id)); + global_port_is_prog_[global_port_id] = is_prog; +} + +void FabricGlobalPortInfo::set_global_port_is_config_enable(const FabricGlobalPortId& global_port_id, + const bool& is_config_enable) { + VTR_ASSERT(valid_global_port_id(global_port_id)); + global_port_is_config_enable_[global_port_id] = is_config_enable; +} + +void FabricGlobalPortInfo::set_global_port_is_io(const FabricGlobalPortId& global_port_id, + const bool& is_io) { + VTR_ASSERT(valid_global_port_id(global_port_id)); + global_port_is_io_[global_port_id] = is_io; +} + +void FabricGlobalPortInfo::set_global_port_default_value(const FabricGlobalPortId& global_port_id, + const size_t& default_value) { + VTR_ASSERT(valid_global_port_id(global_port_id)); + global_port_default_values_[global_port_id] = default_value; +} + +/************************************************************************ + * Internal invalidators/validators + ***********************************************************************/ +/* Validators */ +bool FabricGlobalPortInfo::valid_global_port_id(const FabricGlobalPortId& global_port_id) const { + return ( size_t(global_port_id) < global_port_ids_.size() ) && ( global_port_id == global_port_ids_[global_port_id] ); +} + +} /* namespace openfpga ends */ diff --git a/openfpga/src/fabric/fabric_global_port_info.h b/openfpga/src/fabric/fabric_global_port_info.h new file mode 100644 index 000000000..31c67583e --- /dev/null +++ b/openfpga/src/fabric/fabric_global_port_info.h @@ -0,0 +1,79 @@ +#ifndef FABRIC_GLOBAL_PORT_INFO_H +#define FABRIC_GLOBAL_PORT_INFO_H + +/******************************************************************** + * Include header files required by the data structure definition + *******************************************************************/ +#include +#include + +#include "vtr_vector.h" +#include "module_manager_fwd.h" + +#include "fabric_global_port_info_fwd.h" + +/* namespace openfpga begins */ +namespace openfpga { + +/******************************************************************** + * A data structure to store necessary information for the global + * ports that have been defined for the FPGA fabric + * + * Currently the global port information is mainly used for testbench generation + *******************************************************************/ +class FabricGlobalPortInfo { + public: /* Types */ + typedef vtr::vector::const_iterator global_port_iterator; + /* Create range */ + typedef vtr::Range global_port_range; + public: /* Constructor */ + FabricGlobalPortInfo(); + public: /* Public accessors: aggregators */ + global_port_range global_ports() const; + public: /* Public accessors */ + ModulePortId global_module_port(const FabricGlobalPortId& global_port_id) const; + bool global_port_is_clock(const FabricGlobalPortId& global_port_id) const; + bool global_port_is_set(const FabricGlobalPortId& global_port_id) const; + bool global_port_is_reset(const FabricGlobalPortId& global_port_id) const; + bool global_port_is_prog(const FabricGlobalPortId& global_port_id) const; + bool global_port_is_config_enable(const FabricGlobalPortId& global_port_id) const; + bool global_port_is_io(const FabricGlobalPortId& global_port_id) const; + size_t global_port_default_value(const FabricGlobalPortId& global_port_id) const; + public: /* Public mutators */ + /* By default, we do not set it as a clock. + * Users should set it through the set_global_port_is_clock() function + */ + FabricGlobalPortId create_global_port(const ModulePortId& module_port); + void set_global_port_is_clock(const FabricGlobalPortId& global_port_id, + const bool& is_clock); + void set_global_port_is_set(const FabricGlobalPortId& global_port_id, + const bool& is_set); + void set_global_port_is_reset(const FabricGlobalPortId& global_port_id, + const bool& is_reset); + void set_global_port_is_prog(const FabricGlobalPortId& global_port_id, + const bool& is_prog); + void set_global_port_is_config_enable(const FabricGlobalPortId& global_port_id, + const bool& is_config_enable); + void set_global_port_is_io(const FabricGlobalPortId& global_port_id, + const bool& is_io); + void set_global_port_default_value(const FabricGlobalPortId& global_port_id, + const size_t& default_value); + public: /* Public validator */ + bool valid_global_port_id(const FabricGlobalPortId& global_port_id) const; + private: /* Internal data */ + /* Global port information for tiles */ + vtr::vector global_port_ids_; + vtr::vector global_module_ports_; + vtr::vector global_port_is_clock_; + vtr::vector global_port_is_reset_; + vtr::vector global_port_is_set_; + vtr::vector global_port_is_prog_; + vtr::vector global_port_is_config_enable_; + vtr::vector global_port_is_io_; + vtr::vector global_port_default_values_; +}; + +} /* namespace openfpga ends */ + +#endif + diff --git a/openfpga/src/fabric/fabric_global_port_info_fwd.h b/openfpga/src/fabric/fabric_global_port_info_fwd.h new file mode 100644 index 000000000..35a7dcd04 --- /dev/null +++ b/openfpga/src/fabric/fabric_global_port_info_fwd.h @@ -0,0 +1,22 @@ +/************************************************************************ + * A header file for FabricGlobalPortList class, including critical data declaration + * Please include this file only for using any FabricGlobalPortList data structure + * Refer to fabric_global_port_list.h for more details + ***********************************************************************/ + +/************************************************************************ + * Create strong id for fabric global ports to avoid illegal type casting + ***********************************************************************/ +#ifndef FABRIC_GLOBAL_PORT_INFO_FWD_H +#define FABRIC_GLOBAL_PORT_INFO_FWD_H + +#include "vtr_strong_id.h" + +struct fabric_global_port_id_tag; + +typedef vtr::StrongId FabricGlobalPortId; + +/* Short declaration of class */ +class FabricGlobalPortInfo; + +#endif diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index 81ad7478f..29ecab1f7 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -153,6 +153,7 @@ void fpga_verilog_testbench(const ModuleManager &module_manager, const AtomContext &atom_ctx, const PlacementContext &place_ctx, const IoLocationMap &io_location_map, + const FabricGlobalPortInfo &fabric_global_port_info, const VprNetlistAnnotation &netlist_annotation, const CircuitLibrary &circuit_lib, const SimulationSetting &simulation_setting, @@ -172,17 +173,12 @@ void fpga_verilog_testbench(const ModuleManager &module_manager, print_verilog_simulation_preprocessing_flags(std::string(src_dir_path), options); - /* Collect global ports from the circuit library: - * TODO: should we place this in the OpenFPGA context? - */ - std::vector global_ports = find_circuit_library_global_ports(circuit_lib); - /* Generate wrapper module for FPGA fabric (mapped by the input benchmark and pre-configured testbench for verification */ if (true == options.print_formal_verification_top_netlist()) { std::string formal_verification_top_netlist_file_path = src_dir_path + netlist_name + std::string(FORMAL_VERIFICATION_VERILOG_FILE_POSTFIX); print_verilog_preconfig_top_module(module_manager, bitstream_manager, config_protocol, - circuit_lib, global_ports, + circuit_lib, fabric_global_port_info, atom_ctx, place_ctx, io_location_map, netlist_annotation, netlist_name, @@ -207,7 +203,7 @@ void fpga_verilog_testbench(const ModuleManager &module_manager, print_verilog_top_testbench(module_manager, bitstream_manager, fabric_bitstream, config_protocol, - circuit_lib, global_ports, + fabric_global_port_info, atom_ctx, place_ctx, io_location_map, netlist_annotation, netlist_name, diff --git a/openfpga/src/fpga_verilog/verilog_api.h b/openfpga/src/fpga_verilog/verilog_api.h index 1af656d7d..92a16ba8f 100644 --- a/openfpga/src/fpga_verilog/verilog_api.h +++ b/openfpga/src/fpga_verilog/verilog_api.h @@ -20,6 +20,7 @@ #include "fabric_bitstream.h" #include "simulation_setting.h" #include "io_location_map.h" +#include "fabric_global_port_info.h" #include "vpr_netlist_annotation.h" #include "fabric_verilog_options.h" #include "verilog_testbench_options.h" @@ -47,6 +48,7 @@ void fpga_verilog_testbench(const ModuleManager& module_manager, const AtomContext& atom_ctx, const PlacementContext& place_ctx, const IoLocationMap& io_location_map, + const FabricGlobalPortInfo &fabric_global_port_info, const VprNetlistAnnotation& netlist_annotation, const CircuitLibrary& circuit_lib, const SimulationSetting& simulation_parameters, diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp index 9500044be..033fcc346 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp @@ -118,8 +118,7 @@ namespace openfpga static void print_verilog_preconfig_top_module_connect_global_ports(std::fstream &fp, const ModuleManager &module_manager, const ModuleId &top_module, - const CircuitLibrary &circuit_lib, - const std::vector &global_ports, + const FabricGlobalPortInfo &fabric_global_ports, const std::vector &benchmark_clock_port_names) { /* Validate the file stream */ @@ -127,40 +126,16 @@ namespace openfpga print_verilog_comment(fp, std::string("----- Begin Connect Global ports of FPGA top module -----")); - /* Global ports of the top module in module manager do not carry any attributes, - * such as is_clock, is_set, etc. - * Therefore, for each global port in the top module, we find the circuit port in the circuit library - * which share the same name. We can access to the attributes. - * To gurantee the correct link between global ports in module manager and those in circuit library - * We have performed some critical check in check_circuit_library() for global ports, - * where we guarantee all the global ports share the same name must have the same attributes. - * So that each global port with the same name is unique! - */ - for (const BasicPort &module_global_port : module_manager.module_ports_by_type(top_module, ModuleManager::MODULE_GLOBAL_PORT)) - { - CircuitPortId linked_circuit_port_id = CircuitPortId::INVALID(); - /* Find the circuit port with the same name */ - for (const CircuitPortId &circuit_port_id : global_ports) - { - if (0 != module_global_port.get_name().compare(circuit_lib.port_prefix(circuit_port_id))) - { - continue; - } - linked_circuit_port_id = circuit_port_id; - break; - } - /* Must find one valid circuit port */ - VTR_ASSERT(CircuitPortId::INVALID() != linked_circuit_port_id); - /* Port size should match! */ - VTR_ASSERT(module_global_port.get_width() == circuit_lib.port_size(linked_circuit_port_id)); + for (const FabricGlobalPortId& global_port_id : fabric_global_ports.global_ports()) { + ModulePortId module_global_port_id = fabric_global_ports.global_module_port(global_port_id); + VTR_ASSERT(ModuleManager::MODULE_GLOBAL_PORT == module_manager.port_type(top_module, module_global_port_id)); + BasicPort module_global_port = module_manager.module_port(top_module, module_global_port_id); /* Now, for operating clock port, we should wire it to the clock of benchmark! */ - if ((CIRCUIT_MODEL_PORT_CLOCK == circuit_lib.port_type(linked_circuit_port_id)) && (false == circuit_lib.port_is_prog(linked_circuit_port_id))) - { + if ((true == fabric_global_ports.global_port_is_clock(global_port_id)) + && (false == fabric_global_ports.global_port_is_prog(global_port_id))) { /* Wiring to each pin of the global port: benchmark clock is always 1-bit */ - for (const size_t &pin : module_global_port.pins()) - { - for (const std::string &clock_port_name : benchmark_clock_port_names) - { + for (const size_t &pin : module_global_port.pins()) { + for (const std::string &clock_port_name : benchmark_clock_port_names) { BasicPort module_clock_pin(module_global_port.get_name(), pin, pin); BasicPort benchmark_clock_pin(clock_port_name + std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX), 1); print_verilog_wire_connection(fp, module_clock_pin, benchmark_clock_pin, false); @@ -171,7 +146,7 @@ namespace openfpga } /* For other ports, give an default value */ - std::vector default_values(module_global_port.get_width(), circuit_lib.port_default_value(linked_circuit_port_id)); + std::vector default_values(module_global_port.get_width(), fabric_global_ports.global_port_default_value(global_port_id)); print_verilog_wire_constant_values(fp, module_global_port, default_values); } @@ -430,7 +405,7 @@ namespace openfpga const BitstreamManager &bitstream_manager, const ConfigProtocol &config_protocol, const CircuitLibrary &circuit_lib, - const std::vector &global_ports, + const FabricGlobalPortInfo &global_ports, const AtomContext &atom_ctx, const PlacementContext &place_ctx, const IoLocationMap &io_location_map, @@ -475,7 +450,7 @@ namespace openfpga /* Connect FPGA top module global ports to constant or benchmark global signals! */ print_verilog_preconfig_top_module_connect_global_ports(fp, module_manager, top_module, - circuit_lib, global_ports, + global_ports, benchmark_clock_port_names); /* Connect I/Os to benchmark I/Os or constant driver */ diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h index 498c67628..878795bcb 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h @@ -11,6 +11,7 @@ #include "module_manager.h" #include "bitstream_manager.h" #include "io_location_map.h" +#include "fabric_global_port_info.h" #include "config_protocol.h" #include "vpr_netlist_annotation.h" @@ -25,7 +26,7 @@ void print_verilog_preconfig_top_module(const ModuleManager& module_manager, const BitstreamManager& bitstream_manager, const ConfigProtocol &config_protocol, const CircuitLibrary& circuit_lib, - const std::vector& global_ports, + const FabricGlobalPortInfo &global_ports, const AtomContext& atom_ctx, const PlacementContext& place_ctx, const IoLocationMap& io_location_map, diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index 6753f6626..dbcb737e0 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -6,7 +6,6 @@ #include #include - /* Headers from vtrutil library */ #include "vtr_log.h" #include "vtr_assert.h" @@ -24,6 +23,7 @@ #include "openfpga_atom_netlist_utils.h" #include "fabric_bitstream_utils.h" +#include "fabric_global_port_info_utils.h" #include "verilog_constants.h" #include "verilog_writer_utils.h" @@ -62,54 +62,6 @@ constexpr char* TOP_TB_CLOCK_REG_POSTFIX = "_reg"; constexpr char* AUTOCHECK_TOP_TESTBENCH_VERILOG_MODULE_POSTFIX = "_autocheck_top_tb"; -/******************************************************************** - * Identify global reset ports for programming - *******************************************************************/ -static -std::vector find_global_programming_reset_ports(const CircuitLibrary& circuit_lib, - const std::vector& global_ports) { - /* Try to find global reset ports for programming */ - std::vector global_prog_reset_ports; - for (const CircuitPortId& global_port : global_ports) { - VTR_ASSERT(true == circuit_lib.port_is_global(global_port)); - if (false == circuit_lib.port_is_prog(global_port)) { - continue; - } - VTR_ASSERT(true == circuit_lib.port_is_prog(global_port)); - VTR_ASSERT( (false == circuit_lib.port_is_reset(global_port)) - || (false == circuit_lib.port_is_set(global_port))); - if (true == circuit_lib.port_is_reset(global_port)) { - global_prog_reset_ports.push_back(global_port); - } - } - - return global_prog_reset_ports; -} - -/******************************************************************** - * Identify global set ports for programming - *******************************************************************/ -static -std::vector find_global_programming_set_ports(const CircuitLibrary& circuit_lib, - const std::vector& global_ports) { - /* Try to find global set ports for programming */ - std::vector global_prog_set_ports; - for (const CircuitPortId& global_port : global_ports) { - VTR_ASSERT(true == circuit_lib.port_is_global(global_port)); - if (false == circuit_lib.port_is_prog(global_port)) { - continue; - } - VTR_ASSERT(true == circuit_lib.port_is_prog(global_port)); - VTR_ASSERT( (false == circuit_lib.port_is_reset(global_port)) - || (false == circuit_lib.port_is_set(global_port))); - if (true == circuit_lib.port_is_set(global_port)) { - global_prog_set_ports.push_back(global_port); - } - } - - return global_prog_set_ports; -} - /******************************************************************** * Print local wires for flatten memory (standalone) configuration protocols *******************************************************************/ @@ -300,8 +252,7 @@ static void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp, const ModuleManager& module_manager, const ModuleId& top_module, - const CircuitLibrary& circuit_lib, - const std::vector& global_ports, + const FabricGlobalPortInfo& fabric_global_port_info, const bool& active_global_prog_reset, const bool& active_global_prog_set) { /* Validate the file stream */ @@ -310,8 +261,8 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp, print_verilog_comment(fp, std::string("----- Begin connecting global ports of FPGA fabric to stimuli -----")); /* Connect global clock ports to operating or programming clock signal */ - for (const CircuitPortId& model_global_port : global_ports) { - if (CIRCUIT_MODEL_PORT_CLOCK != circuit_lib.port_type(model_global_port)) { + for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) { + if (false == fabric_global_port_info.global_port_is_clock(fabric_global_port)) { continue; } /* Reach here, it means we have a global clock to deal with: @@ -321,15 +272,15 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp, * connect it to the local wire of operating clock */ /* Find the module port */ - ModulePortId module_global_port = module_manager.find_module_port(top_module, circuit_lib.port_prefix(model_global_port)); + ModulePortId module_global_port = fabric_global_port_info.global_module_port(fabric_global_port); VTR_ASSERT(true == module_manager.valid_module_port_id(top_module, module_global_port)); BasicPort stimuli_clock_port; - if (true == circuit_lib.port_is_prog(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_prog(fabric_global_port)) { stimuli_clock_port.set_name(std::string(TOP_TB_PROG_CLOCK_PORT_NAME)); stimuli_clock_port.set_width(1); } else { - VTR_ASSERT_SAFE(false == circuit_lib.port_is_prog(model_global_port)); + VTR_ASSERT_SAFE(false == fabric_global_port_info.global_port_is_prog(fabric_global_port)); stimuli_clock_port.set_name(std::string(TOP_TB_OP_CLOCK_PORT_NAME)); stimuli_clock_port.set_width(1); } @@ -339,21 +290,21 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp, */ print_verilog_wire_connection(fp, module_manager.module_port(top_module, module_global_port), stimuli_clock_port, - 1 == circuit_lib.port_default_value(model_global_port)); + 1 == fabric_global_port_info.global_port_default_value(fabric_global_port)); } /* Connect global configuration done ports to configuration done signal */ - for (const CircuitPortId& model_global_port : global_ports) { + for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) { /* Bypass clock signals, they have been processed */ - if (CIRCUIT_MODEL_PORT_CLOCK == circuit_lib.port_type(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_clock(fabric_global_port)) { continue; } - if (false == circuit_lib.port_is_config_enable(model_global_port)) { + if (false == fabric_global_port_info.global_port_is_config_enable(fabric_global_port)) { continue; } /* Reach here, it means we have a configuration done port to deal with */ /* Find the module port */ - ModulePortId module_global_port = module_manager.find_module_port(top_module, circuit_lib.port_prefix(model_global_port)); + ModulePortId module_global_port = fabric_global_port_info.global_module_port(fabric_global_port); VTR_ASSERT(true == module_manager.valid_module_port_id(top_module, module_global_port)); BasicPort stimuli_config_done_port(std::string(TOP_TB_CONFIG_DONE_PORT_NAME), 1); @@ -363,37 +314,37 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp, */ print_verilog_wire_connection(fp, module_manager.module_port(top_module, module_global_port), stimuli_config_done_port, - 1 == circuit_lib.port_default_value(model_global_port)); + 1 == fabric_global_port_info.global_port_default_value(fabric_global_port)); } /* Connect global reset ports to operating or programming reset signal */ - for (const CircuitPortId& model_global_port : global_ports) { + for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) { /* Bypass clock signals, they have been processed */ - if (CIRCUIT_MODEL_PORT_CLOCK == circuit_lib.port_type(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_clock(fabric_global_port)) { continue; } /* Bypass config_done signals, they have been processed */ - if (true == circuit_lib.port_is_config_enable(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_config_enable(fabric_global_port)) { continue; } - if (false == circuit_lib.port_is_reset(model_global_port)) { + if (false == fabric_global_port_info.global_port_is_reset(fabric_global_port)) { continue; } /* Reach here, it means we have a reset port to deal with */ /* Find the module port */ - ModulePortId module_global_port = module_manager.find_module_port(top_module, circuit_lib.port_prefix(model_global_port)); + ModulePortId module_global_port = fabric_global_port_info.global_module_port(fabric_global_port); VTR_ASSERT(true == module_manager.valid_module_port_id(top_module, module_global_port)); /* For global programming reset port, we will active only when specified */ BasicPort stimuli_reset_port; bool activate = true; - if (true == circuit_lib.port_is_prog(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_prog(fabric_global_port)) { stimuli_reset_port.set_name(std::string(TOP_TB_PROG_RESET_PORT_NAME)); stimuli_reset_port.set_width(1); activate = active_global_prog_reset; } else { - VTR_ASSERT_SAFE(false == circuit_lib.port_is_prog(model_global_port)); + VTR_ASSERT_SAFE(false == fabric_global_port_info.global_port_is_prog(fabric_global_port)); stimuli_reset_port.set_name(std::string(TOP_TB_RESET_PORT_NAME)); stimuli_reset_port.set_width(1); } @@ -404,47 +355,47 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp, if (true == activate) { print_verilog_wire_connection(fp, module_manager.module_port(top_module, module_global_port), stimuli_reset_port, - 1 == circuit_lib.port_default_value(model_global_port)); + 1 == fabric_global_port_info.global_port_default_value(fabric_global_port)); } else { VTR_ASSERT_SAFE(false == activate); print_verilog_wire_constant_values(fp, module_manager.module_port(top_module, module_global_port), - std::vector(1, circuit_lib.port_default_value(model_global_port))); + std::vector(1, fabric_global_port_info.global_port_default_value(fabric_global_port))); } } /* Connect global set ports to operating or programming set signal */ - for (const CircuitPortId& model_global_port : global_ports) { + for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) { /* Bypass clock signals, they have been processed */ - if (CIRCUIT_MODEL_PORT_CLOCK == circuit_lib.port_type(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_clock(fabric_global_port)) { continue; } /* Bypass config_done signals, they have been processed */ - if (true == circuit_lib.port_is_config_enable(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_config_enable(fabric_global_port)) { continue; } /* Bypass reset signals, they have been processed */ - if (true == circuit_lib.port_is_reset(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_reset(fabric_global_port)) { continue; } - if (false == circuit_lib.port_is_set(model_global_port)) { + if (false == fabric_global_port_info.global_port_is_set(fabric_global_port)) { continue; } /* Reach here, it means we have a set port to deal with */ /* Find the module port */ - ModulePortId module_global_port = module_manager.find_module_port(top_module, circuit_lib.port_prefix(model_global_port)); + ModulePortId module_global_port = fabric_global_port_info.global_module_port(fabric_global_port); VTR_ASSERT(true == module_manager.valid_module_port_id(top_module, module_global_port)); /* For global programming set port, we will active only when specified */ BasicPort stimuli_set_port; bool activate = true; - if (true == circuit_lib.port_is_prog(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_prog(fabric_global_port)) { stimuli_set_port.set_name(std::string(TOP_TB_PROG_SET_PORT_NAME)); stimuli_set_port.set_width(1); activate = active_global_prog_set; } else { - VTR_ASSERT_SAFE(false == circuit_lib.port_is_prog(model_global_port)); + VTR_ASSERT_SAFE(false == fabric_global_port_info.global_port_is_prog(fabric_global_port)); stimuli_set_port.set_name(std::string(TOP_TB_SET_PORT_NAME)); stimuli_set_port.set_width(1); } @@ -455,56 +406,51 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp, if (true == activate) { print_verilog_wire_connection(fp, module_manager.module_port(top_module, module_global_port), stimuli_set_port, - 1 == circuit_lib.port_default_value(model_global_port)); + 1 == fabric_global_port_info.global_port_default_value(fabric_global_port)); } else { VTR_ASSERT_SAFE(false == activate); print_verilog_wire_constant_values(fp, module_manager.module_port(top_module, module_global_port), - std::vector(1, circuit_lib.port_default_value(model_global_port))); + std::vector(1, fabric_global_port_info.global_port_default_value(fabric_global_port))); } } /* For the rest of global ports, wire them to constant signals */ - for (const CircuitPortId& model_global_port : global_ports) { + for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) { /* Bypass clock signals, they have been processed */ - if (CIRCUIT_MODEL_PORT_CLOCK == circuit_lib.port_type(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_clock(fabric_global_port)) { continue; } /* Bypass config_done signals, they have been processed */ - if (true == circuit_lib.port_is_config_enable(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_config_enable(fabric_global_port)) { continue; } /* Bypass reset signals, they have been processed */ - if (true == circuit_lib.port_is_reset(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_reset(fabric_global_port)) { continue; } /* Bypass set signals, they have been processed */ - if (true == circuit_lib.port_is_set(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_set(fabric_global_port)) { continue; } /* Bypass io signals, they do not need any drivers */ - if (true == circuit_lib.port_is_io(model_global_port)) { + if (true == fabric_global_port_info.global_port_is_io(fabric_global_port)) { continue; } /* Find the port name, gpio port has special names */ std::string port_name; - if (true == circuit_lib.port_is_io(model_global_port)) { - port_name = generate_fpga_global_io_port_name(std::string(GIO_INOUT_PREFIX), circuit_lib, circuit_lib.port_parent_model(model_global_port), model_global_port); - } else { - VTR_ASSERT_SAFE(false == circuit_lib.port_is_io(model_global_port)); - port_name = circuit_lib.port_prefix(model_global_port); - } + VTR_ASSERT_SAFE(false == fabric_global_port_info.global_port_is_io(fabric_global_port)); /* Reach here, it means we have a port to deal with */ /* Find the module port and wire it to constant values */ - ModulePortId module_global_port = module_manager.find_module_port(top_module, port_name); + ModulePortId module_global_port = fabric_global_port_info.global_module_port(fabric_global_port); VTR_ASSERT(true == module_manager.valid_module_port_id(top_module, module_global_port)); BasicPort module_port = module_manager.module_port(top_module, module_global_port); - std::vector default_values(module_port.get_width(), circuit_lib.port_default_value(model_global_port)); + std::vector default_values(module_port.get_width(), fabric_global_port_info.global_port_default_value(fabric_global_port)); print_verilog_wire_constant_values(fp, module_port, default_values); } @@ -1279,8 +1225,8 @@ void print_verilog_top_testbench_vanilla_bitstream(std::fstream& fp, static bool find_bit_value_to_skip_for_fast_configuration(const e_config_protocol_type& config_protocol_type, const bool& fast_configuration, - const std::vector& global_prog_reset_ports, - const std::vector& global_prog_set_ports, + const std::vector& global_prog_reset_ports, + const std::vector& global_prog_set_ports, const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream) { @@ -1824,8 +1770,7 @@ void print_verilog_top_testbench(const ModuleManager& module_manager, const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream, const ConfigProtocol& config_protocol, - const CircuitLibrary& circuit_lib, - const std::vector& global_ports, + const FabricGlobalPortInfo& global_ports, const AtomContext& atom_ctx, const PlacementContext& place_ctx, const IoLocationMap& io_location_map, @@ -1860,8 +1805,8 @@ void print_verilog_top_testbench(const ModuleManager& module_manager, std::vector clock_port_names = find_atom_netlist_clock_port_names(atom_ctx.nlist, netlist_annotation); /* Preparation: find all the reset/set ports for programming usage */ - std::vector global_prog_reset_ports = find_global_programming_reset_ports(circuit_lib, global_ports); - std::vector global_prog_set_ports = find_global_programming_set_ports(circuit_lib, global_ports); + std::vector global_prog_reset_ports = find_fabric_global_programming_reset_ports(global_ports); + std::vector global_prog_set_ports = find_fabric_global_programming_set_ports(global_ports); /* Identify if we can apply fast configuration */ bool apply_fast_configuration = fast_configuration; @@ -1935,7 +1880,7 @@ void print_verilog_top_testbench(const ModuleManager& module_manager, /* Generate stimuli for global ports or connect them to existed signals */ print_verilog_top_testbench_global_ports_stimuli(fp, module_manager, top_module, - circuit_lib, global_ports, + global_ports, active_global_prog_reset, active_global_prog_set); diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.h b/openfpga/src/fpga_verilog/verilog_top_testbench.h index 64d0e0b26..6aeb5578b 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.h +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.h @@ -9,10 +9,10 @@ #include "module_manager.h" #include "bitstream_manager.h" #include "fabric_bitstream.h" -#include "circuit_library.h" #include "config_protocol.h" #include "vpr_context.h" #include "io_location_map.h" +#include "fabric_global_port_info.h" #include "vpr_netlist_annotation.h" #include "simulation_setting.h" @@ -27,8 +27,7 @@ void print_verilog_top_testbench(const ModuleManager& module_manager, const BitstreamManager& bitstream_manager, const FabricBitstream& fabric_bitstream, const ConfigProtocol& config_protocol, - const CircuitLibrary& circuit_lib, - const std::vector& global_ports, + const FabricGlobalPortInfo& global_ports, const AtomContext& atom_ctx, const PlacementContext& place_ctx, const IoLocationMap& io_location_map, diff --git a/openfpga/src/utils/fabric_global_port_info_utils.cpp b/openfpga/src/utils/fabric_global_port_info_utils.cpp new file mode 100644 index 000000000..3200a8fbd --- /dev/null +++ b/openfpga/src/utils/fabric_global_port_info_utils.cpp @@ -0,0 +1,61 @@ +/************************************************************************ + * Function to perform fundamental operation for the fabric global ports + * These functions are not universal methods for the FabricGlobalPortInfo class + * They are made to ease the development in some specific purposes + * Please classify such functions in this file + ***********************************************************************/ + +#include + +/* Headers from vtrutil library */ +#include "vtr_assert.h" +#include "vtr_log.h" + +#include "fabric_global_port_info_utils.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * Identify global reset ports for programming + *******************************************************************/ +std::vector find_fabric_global_programming_reset_ports(const FabricGlobalPortInfo& fabric_global_port_info) { + /* Try to find global reset ports for programming */ + std::vector global_prog_reset_ports; + for (const FabricGlobalPortId& global_port : fabric_global_port_info.global_ports()) { + if (false == fabric_global_port_info.global_port_is_prog(global_port)) { + continue; + } + VTR_ASSERT(true == fabric_global_port_info.global_port_is_prog(global_port)); + VTR_ASSERT( (false == fabric_global_port_info.global_port_is_reset(global_port)) + || (false == fabric_global_port_info.global_port_is_set(global_port))); + if (true == fabric_global_port_info.global_port_is_reset(global_port)) { + global_prog_reset_ports.push_back(global_port); + } + } + + return global_prog_reset_ports; +} + +/******************************************************************** + * Identify global set ports for programming + *******************************************************************/ +std::vector find_fabric_global_programming_set_ports(const FabricGlobalPortInfo& fabric_global_port_info) { + /* Try to find global set ports for programming */ + std::vector global_prog_set_ports; + for (const FabricGlobalPortId& global_port : fabric_global_port_info.global_ports()) { + if (false == fabric_global_port_info.global_port_is_prog(global_port)) { + continue; + } + VTR_ASSERT(true == fabric_global_port_info.global_port_is_prog(global_port)); + VTR_ASSERT( (false == fabric_global_port_info.global_port_is_reset(global_port)) + || (false == fabric_global_port_info.global_port_is_set(global_port))); + if (true == fabric_global_port_info.global_port_is_set(global_port)) { + global_prog_set_ports.push_back(global_port); + } + } + + return global_prog_set_ports; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/utils/fabric_global_port_info_utils.h b/openfpga/src/utils/fabric_global_port_info_utils.h new file mode 100644 index 000000000..457c0018e --- /dev/null +++ b/openfpga/src/utils/fabric_global_port_info_utils.h @@ -0,0 +1,23 @@ +#ifndef FABRIC_GLOBAL_PORT_INFO_UTILS_H +#define FABRIC_GLOBAL_PORT_INFO_UTILS_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#include "fabric_global_port_info.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +std::vector find_fabric_global_programming_reset_ports(const FabricGlobalPortInfo& fabric_global_port_info); + +std::vector find_fabric_global_programming_set_ports(const FabricGlobalPortInfo& fabric_global_port_info); + +} /* end namespace openfpga */ + +#endif