diff --git a/libopenfpga/libarchopenfpga/src/check_circuit_library.cpp b/libopenfpga/libarchopenfpga/src/check_circuit_library.cpp index e438ba5f8..89379b2dd 100644 --- a/libopenfpga/libarchopenfpga/src/check_circuit_library.cpp +++ b/libopenfpga/libarchopenfpga/src/check_circuit_library.cpp @@ -562,6 +562,67 @@ int check_power_gated_circuit_models(const CircuitLibrary& circuit_lib) { return num_err; } +/************************************************************************ + * Check io has been defined and has input and output ports + * - We must have global I/O port, either its type is inout, input or output + * - For each IOPAD, we must have at least an input an output + ***********************************************************************/ +static +size_t check_io_circuit_model(const CircuitLibrary& circuit_lib) { + size_t num_err = 0; + + /* Embedded I/O interface may not have inout port + * iopad_port_types_required.push_back(CIRCUIT_MODEL_PORT_INOUT); + * Some I/Os may not have SRAM port, such as AIB interface + * iopad_port_types_required.push_back(CIRCUIT_MODEL_PORT_SRAM); + */ + std::vector iopad_port_types_required; + iopad_port_types_required.push_back(CIRCUIT_MODEL_PORT_INPUT); + iopad_port_types_required.push_back(CIRCUIT_MODEL_PORT_OUTPUT); + num_err += check_circuit_model_port_required(circuit_lib, CIRCUIT_MODEL_IOPAD, iopad_port_types_required); + + /* Each I/O cell must have + * - One of the following ports + * - At least 1 ASIC-to-FPGA (A2F) port that is defined as global I/O + * - At least 1 FPGA-to-ASIC (F2A) port that is defined as global I/O! + * - At least 1 regular port that is non-global which is connected to global routing architecture + */ + for (const auto& io_model : circuit_lib.models_by_type(CIRCUIT_MODEL_IOPAD)) { + bool has_global_io = false; + bool has_internal_connection = false; + + for (const auto& port : circuit_lib.model_ports(io_model)) { + if ( (true == circuit_lib.port_is_io(port) + && (true == circuit_lib.port_is_global(port)))) { + has_global_io = true; + continue; /* Go to next */ + } + if ( (false == circuit_lib.port_is_io(port) + && (false == circuit_lib.port_is_global(port))) + && (CIRCUIT_MODEL_PORT_SRAM != circuit_lib.port_type(port))) { + has_internal_connection = true; + continue; /* Go to next */ + } + } + + if (false == has_global_io) { + VTR_LOGF_ERROR(__FILE__, __LINE__, + "I/O circuit model '%s' does not have any I/O port defined!\n", + circuit_lib.model_name(io_model).c_str()); + num_err++; + } + + if (false == has_internal_connection) { + VTR_LOGF_ERROR(__FILE__, __LINE__, + "I/O circuit model '%s' does not have any port connected to FPGA core!\n", + circuit_lib.model_name(io_model).c_str()); + num_err++; + } + } + + return num_err; +} + /************************************************************************ * Check points to make sure we have a valid circuit library * Detailed checkpoints: @@ -575,6 +636,10 @@ int check_power_gated_circuit_models(const CircuitLibrary& circuit_lib) { * 8. FF must have at least a clock, an input and an output ports * 9. LUT must have at least an input, an output and a SRAM ports * 10. We must have default circuit models for these types: MUX, channel wires and wires + * + * Note: + * - NO modification on the circuit library is allowed! + * The circuit library should be read-only!!! ***********************************************************************/ bool check_circuit_library(const CircuitLibrary& circuit_lib) { size_t num_err = 0; @@ -595,20 +660,11 @@ bool check_circuit_library(const CircuitLibrary& circuit_lib) { num_err += check_circuit_library_ports(circuit_lib); /* 3. Check io has been defined and has input and output ports - * [a] We must have an IOPAD! - * [b] For each IOPAD, we must have at least an input, an output, an INOUT and an SRAM port + * [a] We must have global I/O port, either its type is inout, input or output + * [b] For each IOPAD, we must have at least an input an output */ num_err += check_circuit_model_required(circuit_lib, CIRCUIT_MODEL_IOPAD); - - std::vector iopad_port_types_required; - iopad_port_types_required.push_back(CIRCUIT_MODEL_PORT_INPUT); - iopad_port_types_required.push_back(CIRCUIT_MODEL_PORT_OUTPUT); - iopad_port_types_required.push_back(CIRCUIT_MODEL_PORT_INOUT); - /* Some I/Os may not have SRAM port, such as AIB interface - * iopad_port_types_required.push_back(CIRCUIT_MODEL_PORT_SRAM); - */ - - num_err += check_circuit_model_port_required(circuit_lib, CIRCUIT_MODEL_IOPAD, iopad_port_types_required); + num_err += check_io_circuit_model(circuit_lib); /* 4. Check mux has been defined and has input and output ports * [a] We must have a MUX!