From 392f5798368c40b2a685dab1e2090270a6144e1d Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 13 Aug 2019 13:25:23 -0600 Subject: [PATCH] add linking functions for circuit models and architecture, memory sanitizing is ongoing --- .../check_circuit_library.cpp | 249 +++++++- .../check_circuit_library.h | 26 + .../fpga_spice_include/circuit_library.cpp | 386 +++++++----- .../SRC/fpga_spice_include/circuit_library.h | 4 + .../SRC/fpga_spice_include/circuit_types.h | 3 + .../SRC/fpga_spice_include/spice_types.h | 1 + .../libarchfpga/SRC/include/physical_types.h | 6 + vpr7_x2p/libarchfpga/SRC/read_xml_spice.c | 5 +- vpr7_x2p/vpr/SRC/base/vpr_types.h | 1 + .../fpga_x2p/base/fpga_x2p_pbtypes_utils.c | 1 + .../fpga_x2p/base/fpga_x2p_pbtypes_utils.h | 1 - .../vpr/SRC/fpga_x2p/base/fpga_x2p_setup.c | 9 +- .../fpga_x2p/base/link_arch_circuit_lib.cpp | 592 ++++++++++++++++++ .../SRC/fpga_x2p/base/link_arch_circuit_lib.h | 68 ++ 14 files changed, 1166 insertions(+), 186 deletions(-) create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.cpp create mode 100644 vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.h diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/check_circuit_library.cpp b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/check_circuit_library.cpp index f136dba4c..98952927f 100644 --- a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/check_circuit_library.cpp +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/check_circuit_library.cpp @@ -33,13 +33,27 @@ * +-------------------------------------+ ***********************************************************************/ +/************************************************************************ + * Function to perform fundamental checking for the circuit library + * such as + * 1. if default circuit models are defined + * 2. if any circuit models shared the same name or prefix + * 3. if nay circuit model miss mandatory ports + ***********************************************************************/ + /* Header files should be included in a sequence */ /* Standard header files required go first */ +#include "vtr_assert.h" + #include "util.h" + #include "check_circuit_library.h" -/* 1. Circuit models have unique names, return the number of errors */ +/************************************************************************ + * Circuit models have unique names, return the number of errors + * If not found, we give an error + ***********************************************************************/ static size_t check_circuit_library_unique_names(const CircuitLibrary& circuit_lib) { size_t num_err = 0; @@ -70,7 +84,10 @@ size_t check_circuit_library_unique_names(const CircuitLibrary& circuit_lib) { } -/* 1. Circuit models have unique names, return the number of errors */ +/************************************************************************ + * Circuit models have unique names, return the number of errors + * If not found, we give an error + ***********************************************************************/ static size_t check_circuit_library_unique_prefix(const CircuitLibrary& circuit_lib) { size_t num_err = 0; @@ -102,7 +119,10 @@ size_t check_circuit_library_unique_prefix(const CircuitLibrary& circuit_lib) { return num_err; } -/* A generic function to check the port list of a circuit model in a given type */ +/************************************************************************ + * A generic function to check the port list of a circuit model in a given type + * If not found, we give an error + ***********************************************************************/ static size_t check_circuit_model_required(const CircuitLibrary& circuit_lib, const enum e_spice_model_type& circuit_model_type_to_check) { @@ -120,7 +140,92 @@ size_t check_circuit_model_required(const CircuitLibrary& circuit_lib, return num_err; } -/* A generic function to check the port list of a circuit model in a given type */ +/************************************************************************ + * A generic function to check the port list of a circuit model in a given type + * If not found, we give an error + ***********************************************************************/ +size_t check_one_circuit_model_port_required(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const std::vector& port_types_to_check) { + size_t num_err = 0; + + for (const auto& port_type: port_types_to_check) { + if (0 == circuit_lib.ports_by_type(circuit_model, port_type).size()) { + vpr_printf(TIO_MESSAGE_ERROR, + "%s circuit model(name=%s) does not have %s port\n", + CIRCUIT_MODEL_TYPE_STRING[size_t(circuit_lib.circuit_model_type(circuit_model))], + circuit_lib.circuit_model_name(circuit_model).c_str(), + CIRCUIT_MODEL_PORT_TYPE_STRING[size_t(port_type)]); + /* Incremental the counter for errors */ + num_err++; + } + } + + return num_err; +} + +/************************************************************************ + * A generic function to check the port size of a given circuit model + * if the port size does not match, we give an error + ***********************************************************************/ +size_t check_one_circuit_model_port_size_required(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const CircuitPortId& circuit_port, + const size_t& port_size_to_check) { + + size_t num_err = 0; + + if (port_size_to_check != circuit_lib.port_size(circuit_model, circuit_port)) { + vpr_printf(TIO_MESSAGE_ERROR, + "Port of circuit model(name=%s) does not have a port(type=%s) of size=%d.\n", + circuit_lib.circuit_model_name(circuit_model).c_str(), + CIRCUIT_MODEL_PORT_TYPE_STRING[size_t(circuit_lib.port_type(circuit_model, circuit_port))], + port_size_to_check); + /* Incremental the counter for errors */ + num_err++; + } + + return num_err; +} + +/************************************************************************ + * A generic function to check the port size of a given circuit model + * if the number of ports in the given type does not match, we give an error + * for each port, if the port size does not match, we give an error + ***********************************************************************/ +size_t check_one_circuit_model_port_type_and_size_required(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const enum e_spice_model_port_type& port_type_to_check, + const size_t& num_ports_to_check, + const size_t& port_size_to_check, + const bool& include_global_ports) { + + size_t num_err = 0; + + std::vector ports = circuit_lib.ports_by_type(circuit_model, port_type_to_check, include_global_ports); + if (num_ports_to_check != ports.size()) { + vpr_printf(TIO_MESSAGE_ERROR, + "Expect %d %s ports for a %s circuit model, but only have %d %s ports!\n", + num_ports_to_check, + CIRCUIT_MODEL_PORT_TYPE_STRING[size_t(port_type_to_check)], + CIRCUIT_MODEL_TYPE_STRING[size_t(circuit_lib.circuit_model_type(circuit_model))], + CIRCUIT_MODEL_PORT_TYPE_STRING[size_t(port_type_to_check)], + ports.size()); + num_err++; + } + for (const auto& port : ports) { + num_err += check_one_circuit_model_port_size_required(circuit_lib, + circuit_model, + port, port_size_to_check); + } + + return num_err; +} + +/************************************************************************ + * A generic function to check the port list of circuit models in a given type + * If not found, we give an error + ***********************************************************************/ static size_t check_circuit_model_port_required(const CircuitLibrary& circuit_lib, const enum e_spice_model_type& circuit_model_type_to_check, @@ -128,22 +233,119 @@ size_t check_circuit_model_port_required(const CircuitLibrary& circuit_lib, size_t num_err = 0; for (const auto& id : circuit_lib.circuit_models_by_type(circuit_model_type_to_check)) { - for (const auto& port_type: port_types_to_check) { - if (0 == circuit_lib.ports_by_type(id, port_type).size()) { - vpr_printf(TIO_MESSAGE_ERROR, - "%s circuit model(name=%s) does not have %s port\n", - CIRCUIT_MODEL_TYPE_STRING[size_t(circuit_model_type_to_check)], - circuit_lib.circuit_model_name(id).c_str(), - CIRCUIT_MODEL_PORT_TYPE_STRING[size_t(port_type)]); - /* Incremental the counter for errors */ - num_err++; - } - } + num_err += check_one_circuit_model_port_required(circuit_lib, id, port_types_to_check); } return num_err; } +/************************************************************************ + * A generic function to find the default circuit model with a given type + * If not found, we give an error + ***********************************************************************/ +static +size_t check_required_default_circuit_model(const CircuitLibrary& circuit_lib, + const enum e_spice_model_type& circuit_model_type) { + size_t num_err = 0; + + if (CIRCUIT_MODEL_OPEN_ID == circuit_lib.default_circuit_model(circuit_model_type)) { + vpr_printf(TIO_MESSAGE_ERROR, + "A default circuit model for the type %s! Try to define it in your architecture file!\n", + CIRCUIT_MODEL_TYPE_STRING[size_t(circuit_model_type)]); + exit(1); + } + + return num_err; +} + +/************************************************************************ + * A function to check the port map of FF circuit model + ***********************************************************************/ +size_t check_ff_circuit_model_ports(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model) { + size_t num_err = 0; + + /* Check the type of circuit model */ + VTR_ASSERT(SPICE_MODEL_FF == circuit_lib.circuit_model_type(circuit_model)); + /* Check if we have D, Set and Reset */ + num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model, + SPICE_MODEL_PORT_INPUT, + 3, 1, false); + /* Check if we have a clock */ + num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model, + SPICE_MODEL_PORT_CLOCK, + 1, 1, false); + + + /* Check if we have output */ + num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model, + SPICE_MODEL_PORT_OUTPUT, + 1, 1, false); + + return num_err; +} + +/************************************************************************ + * A function to check the port map of SCFF circuit model + ***********************************************************************/ +size_t check_scff_circuit_model_ports(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model) { + size_t num_err = 0; + + /* Check the type of circuit model */ + VTR_ASSERT(SPICE_MODEL_SCFF == circuit_lib.circuit_model_type(circuit_model)); + + /* Check if we have D, Set and Reset */ + num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model, + SPICE_MODEL_PORT_INPUT, + 1, 1, false); + /* Check if we have a clock */ + num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model, + SPICE_MODEL_PORT_CLOCK, + 1, 1, true); + + + /* Check if we have output */ + num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model, + SPICE_MODEL_PORT_OUTPUT, + 2, 1, false); + + return num_err; +} + +/************************************************************************ + * A function to check the port map of SRAM circuit model + ***********************************************************************/ +size_t check_sram_circuit_model_ports(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const bool& check_blwl) { + size_t num_err = 0; + + /* Check the type of circuit model */ + VTR_ASSERT(SPICE_MODEL_SRAM == circuit_lib.circuit_model_type(circuit_model)); + + /* Check if we has 1 output with size 2 */ + num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model, + SPICE_MODEL_PORT_OUTPUT, + 1, 2, false); + /* basic check finished here */ + if (false == check_blwl) { + return num_err; + } + + /* If bl and wl are required, check their existence */ + num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model, + SPICE_MODEL_PORT_BL, + 1, 1, false); + + num_err += check_one_circuit_model_port_type_and_size_required(circuit_lib, circuit_model, + SPICE_MODEL_PORT_WL, + 1, 1, false); + + return num_err; +} + + /************************************************************************ * Check points to make sure we have a valid circuit library * Detailed checkpoints: @@ -151,6 +353,12 @@ size_t check_circuit_model_port_required(const CircuitLibrary& circuit_lib, * 2. Circuit models have unique prefix * 3. Check IOPADs have input and output ports * 4. Check MUXes has been defined and has input and output ports + * 5. We must have at least one SRAM or SCFF + * 6. SRAM must have at least an input and an output ports + * 7. SCFF must have at least a clock, an input and an output ports + * 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 ***********************************************************************/ void check_circuit_library(const CircuitLibrary& circuit_lib) { size_t num_err = 0; @@ -212,7 +420,7 @@ void check_circuit_library(const CircuitLibrary& circuit_lib) { num_err += check_circuit_model_port_required(circuit_lib, SPICE_MODEL_SRAM, sram_port_types_required); - /* 7. SCFF must have at least an input and an output ports*/ + /* 7. SCFF must have at least a clock, an input and an output ports*/ std::vector scff_port_types_required; scff_port_types_required.push_back(SPICE_MODEL_PORT_CLOCK); scff_port_types_required.push_back(SPICE_MODEL_PORT_INPUT); @@ -220,7 +428,7 @@ void check_circuit_library(const CircuitLibrary& circuit_lib) { num_err += check_circuit_model_port_required(circuit_lib, SPICE_MODEL_SCFF, scff_port_types_required); - /* 8. FF must have at least an input and an output ports*/ + /* 8. FF must have at least a clock, an input and an output ports*/ std::vector ff_port_types_required; ff_port_types_required.push_back(SPICE_MODEL_PORT_CLOCK); ff_port_types_required.push_back(SPICE_MODEL_PORT_INPUT); @@ -228,7 +436,7 @@ void check_circuit_library(const CircuitLibrary& circuit_lib) { num_err += check_circuit_model_port_required(circuit_lib, SPICE_MODEL_FF, ff_port_types_required); - /* 9. LUY must have at least an input, an output and a SRAM ports*/ + /* 9. LUT must have at least an input, an output and a SRAM ports*/ std::vector lut_port_types_required; lut_port_types_required.push_back(SPICE_MODEL_PORT_SRAM); lut_port_types_required.push_back(SPICE_MODEL_PORT_INPUT); @@ -236,6 +444,11 @@ void check_circuit_library(const CircuitLibrary& circuit_lib) { num_err += check_circuit_model_port_required(circuit_lib, SPICE_MODEL_LUT, lut_port_types_required); + /* 10. We must have default circuit models for these types: MUX, channel wires and wires */ + num_err += check_required_default_circuit_model(circuit_lib, SPICE_MODEL_MUX); + num_err += check_required_default_circuit_model(circuit_lib, SPICE_MODEL_CHAN_WIRE); + num_err += check_required_default_circuit_model(circuit_lib, SPICE_MODEL_WIRE); + /* If we have any errors, exit */ vpr_printf(TIO_MESSAGE_ERROR, "Finished checking circuit library with %d errors!\n", diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/check_circuit_library.h b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/check_circuit_library.h index 4dd9d1307..f70133697 100644 --- a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/check_circuit_library.h +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/check_circuit_library.h @@ -50,6 +50,32 @@ #include "circuit_library.h" /* Check points to make sure we have a valid circuit library */ +size_t check_one_circuit_model_port_required(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const std::vector& port_types_to_check); + +size_t check_one_circuit_model_port_size_required(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const CircuitPortId& circuit_port, + const size_t& port_size_to_check); + +size_t check_one_circuit_model_port_type_and_size_required(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const enum e_spice_model_port_type& port_type_to_check, + const size_t& num_ports_to_check, + const size_t& port_size_to_check, + const bool& include_global_ports); + +size_t check_ff_circuit_model_ports(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model); + +size_t check_scff_circuit_model_ports(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model); + +size_t check_sram_circuit_model_ports(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const bool& check_blwl); + void check_circuit_library(const CircuitLibrary& circuit_lib); #endif diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.cpp b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.cpp index e8487bdff..6bd5aab07 100644 --- a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.cpp +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.cpp @@ -88,6 +88,29 @@ std::vector CircuitLibrary::ports_by_type(const CircuitModelId& c return port_ids; } +/* Find the ports of a circuit model by a given type, return a list of qualified ports + * with an option to include/exclude global ports + */ +std::vector CircuitLibrary::ports_by_type(const CircuitModelId& circuit_model_id, + const enum e_spice_model_port_type& type, + const bool& include_global_port) const { + std::vector port_ids; + for (const auto& port_id : ports(circuit_model_id)) { + /* We skip unmatched ports */ + if ( type != port_type(circuit_model_id, port_id) ) { + continue; + } + /* We skip global ports if specified */ + if ( (false == include_global_port) + && (true == port_is_global(circuit_model_id, port_id)) ) { + continue; + } + port_ids.push_back(port_id); + } + return port_ids; +} + + /* Create a vector for all the ports whose directionality is input * This includes all the ports other than whose types are OUPUT or INOUT */ @@ -140,96 +163,106 @@ size_t CircuitLibrary::num_circuit_models() const { /* Access the type of a circuit model */ enum e_spice_model_type CircuitLibrary::circuit_model_type(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return circuit_model_types_[circuit_model_id]; } /* Access the name of a circuit model */ std::string CircuitLibrary::circuit_model_name(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return circuit_model_names_[circuit_model_id]; } /* Access the prefix of a circuit model */ std::string CircuitLibrary::circuit_model_prefix(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return circuit_model_prefix_[circuit_model_id]; } /* Access the path + file of user-defined verilog netlist of a circuit model */ std::string CircuitLibrary::circuit_model_verilog_netlist(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return circuit_model_verilog_netlists_[circuit_model_id]; } /* Access the path + file of user-defined spice netlist of a circuit model */ std::string CircuitLibrary::circuit_model_spice_netlist(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return circuit_model_spice_netlists_[circuit_model_id]; } /* Access the is_default flag (check if this is the default circuit model in the type) of a circuit model */ bool CircuitLibrary::circuit_model_is_default(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return circuit_model_is_default_[circuit_model_id]; } /* Access the dump_structural_verilog flag of a circuit model */ bool CircuitLibrary::dump_structural_verilog(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return dump_structural_verilog_[circuit_model_id]; } /* Access the dump_explicit_port_map flag of a circuit model */ bool CircuitLibrary::dump_explicit_port_map(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return dump_explicit_port_map_[circuit_model_id]; } /* Access the design technology type of a circuit model */ enum e_spice_model_design_tech CircuitLibrary::design_tech_type(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return design_tech_types_[circuit_model_id]; } /* Access the is_power_gated flag of a circuit model */ bool CircuitLibrary::is_power_gated(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return is_power_gated_[circuit_model_id]; } /* Return a flag showing if inputs are buffered for a circuit model */ bool CircuitLibrary::is_input_buffered(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return buffer_existence_[circuit_model_id][INPUT]; } /* Return a flag showing if outputs are buffered for a circuit model */ bool CircuitLibrary::is_output_buffered(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return buffer_existence_[circuit_model_id][OUTPUT]; } /* Return a flag showing if intermediate stages of a LUT are buffered for a circuit model */ bool CircuitLibrary::is_lut_intermediate_buffered(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate the circuit model type is LUT */ - VTR_ASSERT_SAFE(SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)); return buffer_existence_[circuit_model_id][LUT_INTER_BUFFER]; } +/* Return the multiplex structure of a circuit model */ +enum e_spice_model_structure CircuitLibrary::mux_structure(const CircuitModelId& circuit_model_id) const { + /* validate the circuit_model_id */ + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); + /* validate the circuit model type is MUX */ + VTR_ASSERT( (SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)) + || (SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)) ); + return mux_structure_[circuit_model_id]; +} + /************************************************************************ * Public Accessors : Basic data query on Circuit Porst ***********************************************************************/ @@ -237,7 +270,7 @@ bool CircuitLibrary::is_lut_intermediate_buffered(const CircuitModelId& circuit_ /* identify if this port is an input port */ bool CircuitLibrary::is_input_port(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_model_id and circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); /* Only SPICE_MODEL_OUTPUT AND INOUT are considered as outputs */ return ( (SPICE_MODEL_PORT_OUTPUT != port_type(circuit_model_id, circuit_port_id)) && (SPICE_MODEL_PORT_INOUT != port_type(circuit_model_id, circuit_port_id)) ); @@ -246,7 +279,7 @@ bool CircuitLibrary::is_input_port(const CircuitModelId& circuit_model_id, const /* identify if this port is an output port */ bool CircuitLibrary::is_output_port(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_model_id and circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); /* Only SPICE_MODEL_OUTPUT AND INOUT are considered as outputs */ return ( (SPICE_MODEL_PORT_OUTPUT == port_type(circuit_model_id, circuit_port_id)) || (SPICE_MODEL_PORT_INOUT == port_type(circuit_model_id, circuit_port_id)) ); @@ -255,7 +288,7 @@ bool CircuitLibrary::is_output_port(const CircuitModelId& circuit_model_id, cons /* Given a name and return the port id */ CircuitPortId CircuitLibrary::port(const CircuitModelId& circuit_model_id, const std::string& name) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Walk through the ports and try to find a matched name */ CircuitPortId ret = CIRCUIT_PORT_OPEN_ID; size_t num_found = 0; @@ -267,22 +300,34 @@ CircuitPortId CircuitLibrary::port(const CircuitModelId& circuit_model_id, const num_found++; } /* Make sure we will not find two ports with the same name */ - VTR_ASSERT_SAFE( (0 == num_found) || (1 == num_found) ); + VTR_ASSERT( (0 == num_found) || (1 == num_found) ); return ret; } /* Access the type of a port of a circuit model */ size_t CircuitLibrary::num_ports(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return port_ids_[circuit_model_id].size(); } +/* Access the type of a port of a circuit model + * with an option to include/exclude global ports + * when counting + */ +size_t CircuitLibrary::num_ports_by_type(const CircuitModelId& circuit_model_id, + const enum e_spice_model_port_type& port_type, + const bool& include_global_port) const { + /* validate the circuit_model_id */ + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); + return ports_by_type(circuit_model_id, port_type, include_global_port).size(); +} + /* Access the type of a port of a circuit model */ enum e_spice_model_port_type CircuitLibrary::port_type(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return port_types_[circuit_model_id][circuit_port_id]; } @@ -290,7 +335,7 @@ enum e_spice_model_port_type CircuitLibrary::port_type(const CircuitModelId& cir size_t CircuitLibrary::port_size(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return port_sizes_[circuit_model_id][circuit_port_id]; } @@ -298,7 +343,7 @@ size_t CircuitLibrary::port_size(const CircuitModelId& circuit_model_id, std::string CircuitLibrary::port_prefix(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return port_prefix_[circuit_model_id][circuit_port_id]; } @@ -306,7 +351,7 @@ std::string CircuitLibrary::port_prefix(const CircuitModelId& circuit_model_id, std::string CircuitLibrary::port_lib_name(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return port_lib_names_[circuit_model_id][circuit_port_id]; } @@ -314,7 +359,7 @@ std::string CircuitLibrary::port_lib_name(const CircuitModelId& circuit_model_id std::string CircuitLibrary::port_inv_prefix(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return port_inv_prefix_[circuit_model_id][circuit_port_id]; } @@ -322,7 +367,7 @@ std::string CircuitLibrary::port_inv_prefix(const CircuitModelId& circuit_model_ size_t CircuitLibrary::port_default_value(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return port_default_values_[circuit_model_id][circuit_port_id]; } @@ -331,7 +376,7 @@ size_t CircuitLibrary::port_default_value(const CircuitModelId& circuit_model_id bool CircuitLibrary::port_is_mode_select(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return port_is_mode_select_[circuit_model_id][circuit_port_id]; } @@ -339,7 +384,7 @@ bool CircuitLibrary::port_is_mode_select(const CircuitModelId& circuit_model_id, bool CircuitLibrary::port_is_global(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return port_is_global_[circuit_model_id][circuit_port_id]; } @@ -347,7 +392,7 @@ bool CircuitLibrary::port_is_global(const CircuitModelId& circuit_model_id, bool CircuitLibrary::port_is_reset(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return port_is_reset_[circuit_model_id][circuit_port_id]; } @@ -355,7 +400,7 @@ bool CircuitLibrary::port_is_reset(const CircuitModelId& circuit_model_id, bool CircuitLibrary::port_is_set(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return port_is_set_[circuit_model_id][circuit_port_id]; } @@ -363,7 +408,7 @@ bool CircuitLibrary::port_is_set(const CircuitModelId& circuit_model_id, bool CircuitLibrary::port_is_config_enable(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return port_is_config_enable_[circuit_model_id][circuit_port_id]; } @@ -371,7 +416,7 @@ bool CircuitLibrary::port_is_config_enable(const CircuitModelId& circuit_model_i bool CircuitLibrary::port_is_prog(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return port_is_prog_[circuit_model_id][circuit_port_id]; } @@ -379,6 +424,12 @@ bool CircuitLibrary::port_is_prog(const CircuitModelId& circuit_model_id, /************************************************************************ * Public Accessors : Methods to find circuit model ***********************************************************************/ +/* Find a circuit model by a given name and return its id */ +CircuitModelId CircuitLibrary::circuit_model(const char* name) const { + std::string name_str(name); + return circuit_model(name_str); +} + /* Find a circuit model by a given name and return its id */ CircuitModelId CircuitLibrary::circuit_model(const std::string& name) const { CircuitModelId ret = CIRCUIT_MODEL_OPEN_ID; @@ -403,7 +454,9 @@ CircuitModelId CircuitLibrary::circuit_model(const std::string& name) const { /* Get the CircuitModelId of a default circuit model with a given type */ CircuitModelId CircuitLibrary::default_circuit_model(const enum e_spice_model_type& type) const { /* Default circuit model id is the first element by type in the fast look-up */ - return circuit_model_lookup_[size_t(type)].front(); + CircuitModelId default_id = circuit_model_lookup_[size_t(type)].front(); + VTR_ASSERT(true == circuit_model_is_default(default_id)); + return default_id; } /************************************************************************ @@ -414,8 +467,8 @@ CircuitEdgeId CircuitLibrary::edge(const CircuitModelId& circuit_model_id, const CircuitPortId& from_port, const size_t from_pin, const CircuitPortId& to_port, const size_t to_pin) { /* validate the circuit_pin_id */ - VTR_ASSERT_SAFE(valid_circuit_pin_id(circuit_model_id, from_port, from_pin)); - VTR_ASSERT_SAFE(valid_circuit_pin_id(circuit_model_id, to_port, to_pin)); + VTR_ASSERT(valid_circuit_pin_id(circuit_model_id, from_port, from_pin)); + VTR_ASSERT(valid_circuit_pin_id(circuit_model_id, to_port, to_pin)); /* Walk through the edge list until we find the one */ for (auto edge : edge_ids_[circuit_model_id]) { if ( (from_port == edge_src_port_ids_[circuit_model_id][edge]) @@ -551,7 +604,7 @@ CircuitModelId CircuitLibrary::add_circuit_model() { void CircuitLibrary::set_circuit_model_type(const CircuitModelId& circuit_model_id, const enum e_spice_model_type& type) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); circuit_model_types_[circuit_model_id] = type; /* Build the fast look-up for circuit models */ build_circuit_model_lookup(); @@ -561,7 +614,7 @@ void CircuitLibrary::set_circuit_model_type(const CircuitModelId& circuit_model_ /* Set the name of a Circuit Model */ void CircuitLibrary::set_circuit_model_name(const CircuitModelId& circuit_model_id, const std::string& name) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); circuit_model_names_[circuit_model_id] = name; return; } @@ -569,7 +622,7 @@ void CircuitLibrary::set_circuit_model_name(const CircuitModelId& circuit_model_ /* Set the prefix of a Circuit Model */ void CircuitLibrary::set_circuit_model_prefix(const CircuitModelId& circuit_model_id, const std::string& prefix) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); circuit_model_prefix_[circuit_model_id] = prefix; return; } @@ -577,7 +630,7 @@ void CircuitLibrary::set_circuit_model_prefix(const CircuitModelId& circuit_mode /* Set the verilog_netlist of a Circuit Model */ void CircuitLibrary::set_circuit_model_verilog_netlist(const CircuitModelId& circuit_model_id, const std::string& verilog_netlist) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); circuit_model_verilog_netlists_[circuit_model_id] = verilog_netlist; return; } @@ -585,7 +638,7 @@ void CircuitLibrary::set_circuit_model_verilog_netlist(const CircuitModelId& cir /* Set the spice_netlist of a Circuit Model */ void CircuitLibrary::set_circuit_model_spice_netlist(const CircuitModelId& circuit_model_id, const std::string& spice_netlist) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); circuit_model_spice_netlists_[circuit_model_id] = spice_netlist; return; } @@ -593,7 +646,7 @@ void CircuitLibrary::set_circuit_model_spice_netlist(const CircuitModelId& circu /* Set the is_default of a Circuit Model */ void CircuitLibrary::set_circuit_model_is_default(const CircuitModelId& circuit_model_id, const bool& is_default) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); circuit_model_is_default_[circuit_model_id] = is_default; return; } @@ -601,7 +654,7 @@ void CircuitLibrary::set_circuit_model_is_default(const CircuitModelId& circuit_ /* Set the dump_structural_verilog of a Circuit Model */ void CircuitLibrary::set_circuit_model_dump_structural_verilog(const CircuitModelId& circuit_model_id, const bool& dump_structural_verilog) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); dump_structural_verilog_[circuit_model_id] = dump_structural_verilog; return; } @@ -609,7 +662,7 @@ void CircuitLibrary::set_circuit_model_dump_structural_verilog(const CircuitMode /* Set the dump_explicit_port_map of a Circuit Model */ void CircuitLibrary::set_circuit_model_dump_explicit_port_map(const CircuitModelId& circuit_model_id, const bool& dump_explicit_port_map) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); dump_explicit_port_map_[circuit_model_id] = dump_explicit_port_map; return; } @@ -617,7 +670,7 @@ void CircuitLibrary::set_circuit_model_dump_explicit_port_map(const CircuitModel /* Set the type of design technology of a Circuit Model */ void CircuitLibrary::set_circuit_model_design_tech_type(const CircuitModelId& circuit_model_id, const enum e_spice_model_design_tech& design_tech_type) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); design_tech_types_[circuit_model_id] = design_tech_type; return; } @@ -625,7 +678,7 @@ void CircuitLibrary::set_circuit_model_design_tech_type(const CircuitModelId& ci /* Set the power-gated flag of a Circuit Model */ void CircuitLibrary::set_circuit_model_is_power_gated(const CircuitModelId& circuit_model_id, const bool& is_power_gated) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); is_power_gated_[circuit_model_id] = is_power_gated; return; } @@ -650,9 +703,9 @@ void CircuitLibrary::set_circuit_model_output_buffer(const CircuitModelId& circu void CircuitLibrary::set_circuit_model_lut_input_buffer(const CircuitModelId& circuit_model_id, const bool& existence, const std::string& circuit_model_name) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Make sure the circuit model is a LUT! */ - VTR_ASSERT_SAFE(SPICE_MODEL_LUT == circuit_model_types_[circuit_model_id]); + VTR_ASSERT(SPICE_MODEL_LUT == circuit_model_types_[circuit_model_id]); /* Just call the base function and give the proper type */ set_circuit_model_buffer(circuit_model_id, LUT_INPUT_BUFFER, existence, circuit_model_name); return; @@ -662,9 +715,9 @@ void CircuitLibrary::set_circuit_model_lut_input_buffer(const CircuitModelId& ci void CircuitLibrary::set_circuit_model_lut_input_inverter(const CircuitModelId& circuit_model_id, const bool& existence, const std::string& circuit_model_name) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Make sure the circuit model is a LUT! */ - VTR_ASSERT_SAFE(SPICE_MODEL_LUT == circuit_model_types_[circuit_model_id]); + VTR_ASSERT(SPICE_MODEL_LUT == circuit_model_types_[circuit_model_id]); /* Just call the base function and give the proper type */ set_circuit_model_buffer(circuit_model_id, LUT_INPUT_INVERTER, existence, circuit_model_name); return; @@ -674,9 +727,9 @@ void CircuitLibrary::set_circuit_model_lut_input_inverter(const CircuitModelId& void CircuitLibrary::set_circuit_model_lut_intermediate_buffer(const CircuitModelId& circuit_model_id, const bool& existence, const std::string& circuit_model_name) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Make sure the circuit model is a LUT! */ - VTR_ASSERT_SAFE(SPICE_MODEL_LUT == circuit_model_types_[circuit_model_id]); + VTR_ASSERT(SPICE_MODEL_LUT == circuit_model_types_[circuit_model_id]); /* Just call the base function and give the proper type */ set_circuit_model_buffer(circuit_model_id, LUT_INTER_BUFFER, existence, circuit_model_name); return; @@ -685,7 +738,7 @@ void CircuitLibrary::set_circuit_model_lut_intermediate_buffer(const CircuitMode void CircuitLibrary::set_circuit_model_lut_intermediate_buffer_location_map(const CircuitModelId& circuit_model_id, const std::string& location_map) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); buffer_location_maps_[circuit_model_id][LUT_INTER_BUFFER] = location_map; return; } @@ -694,7 +747,7 @@ void CircuitLibrary::set_circuit_model_lut_intermediate_buffer_location_map(cons /* Set pass-gate logic information of a circuit model */ void CircuitLibrary::set_circuit_model_pass_gate_logic(const CircuitModelId& circuit_model_id, const std::string& circuit_model_name) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); pass_gate_logic_circuit_model_names_[circuit_model_id] = circuit_model_name; return; } @@ -702,7 +755,7 @@ void CircuitLibrary::set_circuit_model_pass_gate_logic(const CircuitModelId& cir /* Add a port to a circuit model */ CircuitPortId CircuitLibrary::add_circuit_model_port(const CircuitModelId& circuit_model_id) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Create a port id */ CircuitPortId circuit_port_id = CircuitPortId(port_ids_[circuit_model_id].size()); /* Update the id list */ @@ -742,7 +795,7 @@ void CircuitLibrary::set_port_type(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const enum e_spice_model_port_type& port_type) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_types_[circuit_model_id][circuit_port_id] = port_type; /* Build the fast look-up for circuit model ports */ build_circuit_model_port_lookup(circuit_model_id); @@ -754,7 +807,7 @@ void CircuitLibrary::set_port_size(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const size_t& port_size) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_sizes_[circuit_model_id][circuit_port_id] = port_size; return; } @@ -764,7 +817,7 @@ void CircuitLibrary::set_port_prefix(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const std::string& port_prefix) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_prefix_[circuit_model_id][circuit_port_id] = port_prefix; return; } @@ -774,7 +827,7 @@ void CircuitLibrary::set_port_lib_name(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const std::string& lib_name) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_lib_names_[circuit_model_id][circuit_port_id] = lib_name; return; } @@ -784,7 +837,7 @@ void CircuitLibrary::set_port_inv_prefix(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const std::string& inv_prefix) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_inv_prefix_[circuit_model_id][circuit_port_id] = inv_prefix; return; } @@ -794,7 +847,7 @@ void CircuitLibrary::set_port_default_value(const CircuitModelId& circuit_model_ const CircuitPortId& circuit_port_id, const size_t& default_value) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_default_values_[circuit_model_id][circuit_port_id] = default_value; return; } @@ -804,7 +857,7 @@ void CircuitLibrary::set_port_is_mode_select(const CircuitModelId& circuit_model const CircuitPortId& circuit_port_id, const bool& is_mode_select) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_is_mode_select_[circuit_model_id][circuit_port_id] = is_mode_select; return; } @@ -814,7 +867,7 @@ void CircuitLibrary::set_port_is_global(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const bool& is_global) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_is_global_[circuit_model_id][circuit_port_id] = is_global; return; } @@ -824,7 +877,7 @@ void CircuitLibrary::set_port_is_reset(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const bool& is_reset) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_is_reset_[circuit_model_id][circuit_port_id] = is_reset; return; } @@ -834,7 +887,7 @@ void CircuitLibrary::set_port_is_set(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const bool& is_set) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_is_set_[circuit_model_id][circuit_port_id] = is_set; return; } @@ -844,7 +897,7 @@ void CircuitLibrary::set_port_is_config_enable(const CircuitModelId& circuit_mod const CircuitPortId& circuit_port_id, const bool& is_config_enable) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_is_config_enable_[circuit_model_id][circuit_port_id] = is_config_enable; return; } @@ -854,7 +907,7 @@ void CircuitLibrary::set_port_is_prog(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const bool& is_prog) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_is_prog_[circuit_model_id][circuit_port_id] = is_prog; return; } @@ -864,7 +917,7 @@ void CircuitLibrary::set_port_circuit_model_name(const CircuitModelId& circuit_m const CircuitPortId& circuit_port_id, const std::string& circuit_model_name) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_circuit_model_names_[circuit_model_id][circuit_port_id] = circuit_model_name; return; } @@ -874,7 +927,7 @@ void CircuitLibrary::set_port_circuit_model_id(const CircuitModelId& circuit_mod const CircuitPortId& circuit_port_id, const CircuitModelId& port_circuit_model_id) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_circuit_model_ids_[circuit_model_id][circuit_port_id] = port_circuit_model_id; return; } @@ -884,7 +937,7 @@ void CircuitLibrary::set_port_inv_circuit_model_name(const CircuitModelId& circu const CircuitPortId& circuit_port_id, const std::string& inv_circuit_model_name) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_inv_circuit_model_names_[circuit_model_id][circuit_port_id] = inv_circuit_model_name; return; } @@ -894,7 +947,7 @@ void CircuitLibrary::set_port_inv_circuit_model_id(const CircuitModelId& circuit const CircuitPortId& circuit_port_id, const CircuitModelId& inv_circuit_model_id) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_inv_circuit_model_ids_[circuit_model_id][circuit_port_id] = inv_circuit_model_id; return; } @@ -904,7 +957,7 @@ void CircuitLibrary::set_port_tri_state_map(const CircuitModelId& circuit_model_ const CircuitPortId& circuit_port_id, const std::string& tri_state_map) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); port_tri_state_maps_[circuit_model_id][circuit_port_id] = tri_state_map; return; } @@ -914,9 +967,9 @@ void CircuitLibrary::set_port_lut_frac_level(const CircuitModelId& circuit_model const CircuitPortId& circuit_port_id, const size_t& lut_frac_level) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); /* Make sure this is a LUT */ - VTR_ASSERT_SAFE(SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)); port_lut_frac_level_[circuit_model_id][circuit_port_id] = lut_frac_level; return; } @@ -926,9 +979,9 @@ void CircuitLibrary::set_port_lut_output_mask(const CircuitModelId& circuit_mode const CircuitPortId& circuit_port_id, const std::vector& lut_output_masks) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); /* Make sure this is a LUT */ - VTR_ASSERT_SAFE(SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)); port_lut_output_masks_[circuit_model_id][circuit_port_id] = lut_output_masks; return; } @@ -938,9 +991,9 @@ void CircuitLibrary::set_port_sram_orgz(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const enum e_sram_orgz& sram_orgz) { /* validate the circuit_port_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); /* Make sure this is a SRAM port */ - VTR_ASSERT_SAFE(SPICE_MODEL_PORT_SRAM == port_type(circuit_model_id, circuit_port_id)); + VTR_ASSERT(SPICE_MODEL_PORT_SRAM == port_type(circuit_model_id, circuit_port_id)); port_sram_orgz_[circuit_model_id][circuit_port_id] = sram_orgz; return; } @@ -954,7 +1007,7 @@ void CircuitLibrary::set_port_sram_orgz(const CircuitModelId& circuit_model_id, void CircuitLibrary::add_delay_info(const CircuitModelId& circuit_model_id, const enum spice_model_delay_type& delay_type) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Check the range of vector */ if (size_t(delay_type) >= delay_types_[circuit_model_id].size()) { /* Resize */ @@ -971,9 +1024,9 @@ void CircuitLibrary::set_delay_in_port_names(const CircuitModelId& circuit_model const enum spice_model_delay_type& delay_type, const std::string& in_port_names) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Validate delay_type */ - VTR_ASSERT_SAFE(valid_delay_type(circuit_model_id, delay_type)); + VTR_ASSERT(valid_delay_type(circuit_model_id, delay_type)); delay_in_port_names_[circuit_model_id][size_t(delay_type)] = in_port_names; return; } @@ -982,9 +1035,9 @@ void CircuitLibrary::set_delay_out_port_names(const CircuitModelId& circuit_mode const enum spice_model_delay_type& delay_type, const std::string& out_port_names) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Validate delay_type */ - VTR_ASSERT_SAFE(valid_delay_type(circuit_model_id, delay_type)); + VTR_ASSERT(valid_delay_type(circuit_model_id, delay_type)); delay_out_port_names_[circuit_model_id][size_t(delay_type)] = out_port_names; return; } @@ -993,9 +1046,9 @@ void CircuitLibrary::set_delay_values(const CircuitModelId& circuit_model_id, const enum spice_model_delay_type& delay_type, const std::string& delay_values) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Validate delay_type */ - VTR_ASSERT_SAFE(valid_delay_type(circuit_model_id, delay_type)); + VTR_ASSERT(valid_delay_type(circuit_model_id, delay_type)); delay_values_[circuit_model_id][size_t(delay_type)] = delay_values; return; } @@ -1004,9 +1057,9 @@ void CircuitLibrary::set_delay_values(const CircuitModelId& circuit_model_id, void CircuitLibrary::set_buffer_type(const CircuitModelId& circuit_model_id, const enum e_spice_model_buffer_type& buffer_type) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be BUFFER or INVERTER */ - VTR_ASSERT_SAFE(SPICE_MODEL_INVBUF == circuit_model_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_INVBUF == circuit_model_type(circuit_model_id)); buffer_types_[circuit_model_id] = buffer_type; return; } @@ -1014,9 +1067,9 @@ void CircuitLibrary::set_buffer_type(const CircuitModelId& circuit_model_id, void CircuitLibrary::set_buffer_size(const CircuitModelId& circuit_model_id, const float& buffer_size) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be BUFFER or INVERTER */ - VTR_ASSERT_SAFE(SPICE_MODEL_INVBUF == circuit_model_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_INVBUF == circuit_model_type(circuit_model_id)); buffer_sizes_[circuit_model_id] = buffer_size; return; } @@ -1024,9 +1077,9 @@ void CircuitLibrary::set_buffer_size(const CircuitModelId& circuit_model_id, void CircuitLibrary::set_buffer_num_levels(const CircuitModelId& circuit_model_id, const size_t& num_levels) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be BUFFER or INVERTER */ - VTR_ASSERT_SAFE(SPICE_MODEL_INVBUF == circuit_model_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_INVBUF == circuit_model_type(circuit_model_id)); buffer_num_levels_[circuit_model_id] = num_levels; return; } @@ -1034,9 +1087,9 @@ void CircuitLibrary::set_buffer_num_levels(const CircuitModelId& circuit_model_i void CircuitLibrary::set_buffer_f_per_stage(const CircuitModelId& circuit_model_id, const size_t& f_per_stage) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be BUFFER or INVERTER */ - VTR_ASSERT_SAFE(SPICE_MODEL_INVBUF == circuit_model_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_INVBUF == circuit_model_type(circuit_model_id)); buffer_f_per_stage_[circuit_model_id] = f_per_stage; return; } @@ -1045,9 +1098,9 @@ void CircuitLibrary::set_buffer_f_per_stage(const CircuitModelId& circuit_model_ void CircuitLibrary::set_pass_gate_logic_type(const CircuitModelId& circuit_model_id, const enum e_spice_model_pass_gate_logic_type& pass_gate_logic_type) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be BUFFER or INVERTER */ - VTR_ASSERT_SAFE(SPICE_MODEL_PASSGATE == circuit_model_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_PASSGATE == circuit_model_type(circuit_model_id)); pass_gate_logic_types_[circuit_model_id] = pass_gate_logic_type; return; } @@ -1055,9 +1108,9 @@ void CircuitLibrary::set_pass_gate_logic_type(const CircuitModelId& circuit_mode void CircuitLibrary::set_pass_gate_logic_nmos_size(const CircuitModelId& circuit_model_id, const float& nmos_size) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be BUFFER or INVERTER */ - VTR_ASSERT_SAFE(SPICE_MODEL_PASSGATE == circuit_model_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_PASSGATE == circuit_model_type(circuit_model_id)); pass_gate_logic_sizes_[circuit_model_id].set_x(nmos_size); return; } @@ -1065,9 +1118,9 @@ void CircuitLibrary::set_pass_gate_logic_nmos_size(const CircuitModelId& circuit void CircuitLibrary::set_pass_gate_logic_pmos_size(const CircuitModelId& circuit_model_id, const float& pmos_size) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be BUFFER or INVERTER */ - VTR_ASSERT_SAFE(SPICE_MODEL_PASSGATE == circuit_model_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_PASSGATE == circuit_model_type(circuit_model_id)); pass_gate_logic_sizes_[circuit_model_id].set_y(pmos_size); return; } @@ -1076,9 +1129,10 @@ void CircuitLibrary::set_pass_gate_logic_pmos_size(const CircuitModelId& circuit void CircuitLibrary::set_mux_structure(const CircuitModelId& circuit_model_id, const enum e_spice_model_structure& mux_structure) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); - /* validate that the type of this circuit_model should be MUX */ - VTR_ASSERT_SAFE(SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); + /* validate that the type of this circuit_model should be MUX or LUT */ + VTR_ASSERT( (SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)) + || (SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)) ); mux_structure_[circuit_model_id] = mux_structure; return; } @@ -1086,9 +1140,10 @@ void CircuitLibrary::set_mux_structure(const CircuitModelId& circuit_model_id, void CircuitLibrary::set_mux_num_levels(const CircuitModelId& circuit_model_id, const size_t& num_levels) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); - /* validate that the type of this circuit_model should be MUX */ - VTR_ASSERT_SAFE(SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); + /* validate that the type of this circuit_model should be MUX or LUT */ + VTR_ASSERT( (SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)) + || (SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)) ); mux_num_levels_[circuit_model_id] = num_levels; return; } @@ -1096,9 +1151,10 @@ void CircuitLibrary::set_mux_num_levels(const CircuitModelId& circuit_model_id, void CircuitLibrary::set_mux_const_input_value(const CircuitModelId& circuit_model_id, const size_t& const_input_value) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); - /* validate that the type of this circuit_model should be MUX */ - VTR_ASSERT_SAFE(SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); + /* validate that the type of this circuit_model should be MUX or LUT */ + VTR_ASSERT( (SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)) + || (SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)) ); mux_const_input_values_[circuit_model_id] = const_input_value; return; } @@ -1106,9 +1162,10 @@ void CircuitLibrary::set_mux_const_input_value(const CircuitModelId& circuit_mod void CircuitLibrary::set_mux_use_local_encoder(const CircuitModelId& circuit_model_id, const bool& use_local_encoder) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); - /* validate that the type of this circuit_model should be MUX */ - VTR_ASSERT_SAFE(SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); + /* validate that the type of this circuit_model should be MUX or LUT */ + VTR_ASSERT( (SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)) + || (SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)) ); mux_use_local_encoder_[circuit_model_id] = use_local_encoder; return; } @@ -1116,9 +1173,10 @@ void CircuitLibrary::set_mux_use_local_encoder(const CircuitModelId& circuit_mod void CircuitLibrary::set_mux_use_advanced_rram_design(const CircuitModelId& circuit_model_id, const bool& use_advanced_rram_design) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); - /* validate that the type of this circuit_model should be MUX */ - VTR_ASSERT_SAFE(SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); + /* validate that the type of this circuit_model should be MUX or LUT */ + VTR_ASSERT( (SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)) + || (SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)) ); mux_use_advanced_rram_design_[circuit_model_id] = use_advanced_rram_design; return; } @@ -1127,9 +1185,9 @@ void CircuitLibrary::set_mux_use_advanced_rram_design(const CircuitModelId& circ void CircuitLibrary::set_lut_is_fracturable(const CircuitModelId& circuit_model_id, const bool& is_fracturable) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be LUT */ - VTR_ASSERT_SAFE(SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)); lut_is_fracturable_[circuit_model_id] = is_fracturable; return; } @@ -1138,9 +1196,9 @@ void CircuitLibrary::set_lut_is_fracturable(const CircuitModelId& circuit_model_ void CircuitLibrary::set_gate_type(const CircuitModelId& circuit_model_id, const enum e_spice_model_gate_type& gate_type) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be GATE */ - VTR_ASSERT_SAFE(SPICE_MODEL_GATE == circuit_model_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_GATE == circuit_model_type(circuit_model_id)); gate_types_[circuit_model_id] = gate_type; return; } @@ -1150,9 +1208,9 @@ void CircuitLibrary::set_gate_type(const CircuitModelId& circuit_model_id, void CircuitLibrary::set_rram_rlrs(const CircuitModelId& circuit_model_id, const float& rlrs) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the design_tech of this circuit_model should be RRAM */ - VTR_ASSERT_SAFE(SPICE_MODEL_DESIGN_RRAM == design_tech_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_DESIGN_RRAM == design_tech_type(circuit_model_id)); rram_res_[circuit_model_id].set_x(rlrs); return; } @@ -1160,9 +1218,9 @@ void CircuitLibrary::set_rram_rlrs(const CircuitModelId& circuit_model_id, void CircuitLibrary::set_rram_rhrs(const CircuitModelId& circuit_model_id, const float& rhrs) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the design_tech of this circuit_model should be RRAM */ - VTR_ASSERT_SAFE(SPICE_MODEL_DESIGN_RRAM == design_tech_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_DESIGN_RRAM == design_tech_type(circuit_model_id)); rram_res_[circuit_model_id].set_y(rhrs); return; } @@ -1170,9 +1228,9 @@ void CircuitLibrary::set_rram_rhrs(const CircuitModelId& circuit_model_id, void CircuitLibrary::set_rram_wprog_set_nmos(const CircuitModelId& circuit_model_id, const float& wprog_set_nmos) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the design_tech of this circuit_model should be RRAM */ - VTR_ASSERT_SAFE(SPICE_MODEL_DESIGN_RRAM == design_tech_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_DESIGN_RRAM == design_tech_type(circuit_model_id)); wprog_set_[circuit_model_id].set_x(wprog_set_nmos); return; } @@ -1180,9 +1238,9 @@ void CircuitLibrary::set_rram_wprog_set_nmos(const CircuitModelId& circuit_model void CircuitLibrary::set_rram_wprog_set_pmos(const CircuitModelId& circuit_model_id, const float& wprog_set_pmos) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the design_tech of this circuit_model should be RRAM */ - VTR_ASSERT_SAFE(SPICE_MODEL_DESIGN_RRAM == design_tech_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_DESIGN_RRAM == design_tech_type(circuit_model_id)); wprog_set_[circuit_model_id].set_y(wprog_set_pmos); return; } @@ -1190,9 +1248,9 @@ void CircuitLibrary::set_rram_wprog_set_pmos(const CircuitModelId& circuit_model void CircuitLibrary::set_rram_wprog_reset_nmos(const CircuitModelId& circuit_model_id, const float& wprog_reset_nmos) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the design_tech of this circuit_model should be RRAM */ - VTR_ASSERT_SAFE(SPICE_MODEL_DESIGN_RRAM == design_tech_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_DESIGN_RRAM == design_tech_type(circuit_model_id)); wprog_reset_[circuit_model_id].set_x(wprog_reset_nmos); return; } @@ -1200,9 +1258,9 @@ void CircuitLibrary::set_rram_wprog_reset_nmos(const CircuitModelId& circuit_mod void CircuitLibrary::set_rram_wprog_reset_pmos(const CircuitModelId& circuit_model_id, const float& wprog_reset_pmos) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the design_tech of this circuit_model should be RRAM */ - VTR_ASSERT_SAFE(SPICE_MODEL_DESIGN_RRAM == design_tech_type(circuit_model_id)); + VTR_ASSERT(SPICE_MODEL_DESIGN_RRAM == design_tech_type(circuit_model_id)); wprog_reset_[circuit_model_id].set_y(wprog_reset_pmos); return; } @@ -1211,9 +1269,9 @@ void CircuitLibrary::set_rram_wprog_reset_pmos(const CircuitModelId& circuit_mod void CircuitLibrary::set_wire_type(const CircuitModelId& circuit_model_id, const enum e_wire_model_type& wire_type) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be WIRE or CHAN_WIRE */ - VTR_ASSERT_SAFE( (SPICE_MODEL_WIRE == circuit_model_type(circuit_model_id)) + VTR_ASSERT( (SPICE_MODEL_WIRE == circuit_model_type(circuit_model_id)) || (SPICE_MODEL_CHAN_WIRE == circuit_model_type(circuit_model_id)) ); wire_types_[circuit_model_id] = wire_type; return; @@ -1222,9 +1280,9 @@ void CircuitLibrary::set_wire_type(const CircuitModelId& circuit_model_id, void CircuitLibrary::set_wire_r(const CircuitModelId& circuit_model_id, const float& r_val) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be WIRE or CHAN_WIRE */ - VTR_ASSERT_SAFE( (SPICE_MODEL_WIRE == circuit_model_type(circuit_model_id)) + VTR_ASSERT( (SPICE_MODEL_WIRE == circuit_model_type(circuit_model_id)) || (SPICE_MODEL_CHAN_WIRE == circuit_model_type(circuit_model_id)) ); wire_rc_[circuit_model_id].set_x(r_val); return; @@ -1233,9 +1291,9 @@ void CircuitLibrary::set_wire_r(const CircuitModelId& circuit_model_id, void CircuitLibrary::set_wire_c(const CircuitModelId& circuit_model_id, const float& c_val) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be WIRE or CHAN_WIRE */ - VTR_ASSERT_SAFE( (SPICE_MODEL_WIRE == circuit_model_type(circuit_model_id)) + VTR_ASSERT( (SPICE_MODEL_WIRE == circuit_model_type(circuit_model_id)) || (SPICE_MODEL_CHAN_WIRE == circuit_model_type(circuit_model_id)) ); wire_rc_[circuit_model_id].set_y(c_val); return; @@ -1244,9 +1302,9 @@ void CircuitLibrary::set_wire_c(const CircuitModelId& circuit_model_id, void CircuitLibrary::set_wire_num_levels(const CircuitModelId& circuit_model_id, const size_t& num_level) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* validate that the type of this circuit_model should be WIRE or CHAN_WIRE */ - VTR_ASSERT_SAFE( (SPICE_MODEL_WIRE == circuit_model_type(circuit_model_id)) + VTR_ASSERT( (SPICE_MODEL_WIRE == circuit_model_type(circuit_model_id)) || (SPICE_MODEL_CHAN_WIRE == circuit_model_type(circuit_model_id)) ); wire_num_levels_[circuit_model_id] = num_level; return; @@ -1263,7 +1321,7 @@ void CircuitLibrary::set_wire_num_levels(const CircuitModelId& circuit_model_id, void CircuitLibrary::set_circuit_model_buffer(const CircuitModelId& circuit_model_id, const enum e_buffer_type buffer_type, const bool& existence, const std::string& circuit_model_name) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Check the range of vector */ if (size_t(buffer_type) >= buffer_existence_[circuit_model_id].size()) { /* Resize and assign values */ @@ -1285,7 +1343,7 @@ void CircuitLibrary::set_circuit_model_buffer(const CircuitModelId& circuit_mode */ void CircuitLibrary::link_port_circuit_model(const CircuitModelId& circuit_model_id) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Walk through each ports, get the port id and find the circuit model id by name */ for (auto& port_id : ports(circuit_model_id)) { /* Bypass empty name */ @@ -1303,7 +1361,7 @@ void CircuitLibrary::link_port_circuit_model(const CircuitModelId& circuit_model */ void CircuitLibrary::link_port_inv_circuit_model(const CircuitModelId& circuit_model_id) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Walk through each ports, get the port id and find the circuit model id by name */ for (auto& port_id : ports(circuit_model_id)) { /* Bypass empty name */ @@ -1328,7 +1386,7 @@ void CircuitLibrary::link_port_circuit_models(const CircuitModelId& circuit_mode */ void CircuitLibrary::link_buffer_circuit_model(const CircuitModelId& circuit_model_id) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Get the circuit model id by name, skip those with empty names*/ for (size_t buffer_id = 0; buffer_id < buffer_circuit_model_names_[circuit_model_id].size(); ++buffer_id) { if (true == buffer_circuit_model_names_[circuit_model_id][buffer_id].empty()) { @@ -1345,7 +1403,7 @@ void CircuitLibrary::link_buffer_circuit_model(const CircuitModelId& circuit_mod */ void CircuitLibrary::link_pass_gate_logic_circuit_model(const CircuitModelId& circuit_model_id) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Get the circuit model id by name, skip those with empty names*/ if (true == pass_gate_logic_circuit_model_names_[circuit_model_id].empty()) { return; @@ -1412,7 +1470,7 @@ void CircuitLibrary::add_edge(const CircuitModelId& circuit_model_id, const CircuitPortId& from_port, const size_t& from_pin, const CircuitPortId& to_port, const size_t& to_pin) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Create an edge in the edge id list */ CircuitEdgeId edge_id = CircuitEdgeId(edge_ids_[circuit_model_id].size()); @@ -1455,8 +1513,8 @@ void CircuitLibrary::set_edge_delay(const CircuitModelId& circuit_model_id, const enum spice_model_delay_type& delay_type, const float& delay_value) { /* validate the circuit_edge_id */ - VTR_ASSERT_SAFE(valid_circuit_edge_id(circuit_model_id, circuit_edge_id)); - VTR_ASSERT_SAFE(valid_delay_type(circuit_model_id, delay_type)); + VTR_ASSERT(valid_circuit_edge_id(circuit_model_id, circuit_edge_id)); + VTR_ASSERT(valid_delay_type(circuit_model_id, delay_type)); edge_timing_info_[circuit_model_id][circuit_edge_id][size_t(delay_type)] = delay_value; return; @@ -1465,7 +1523,7 @@ void CircuitLibrary::set_edge_delay(const CircuitModelId& circuit_model_id, /* Annotate delay values on a timing graph */ void CircuitLibrary::set_timing_graph_delays(const CircuitModelId& circuit_model_id) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); /* Go one delay_info by another */ for (const auto& delay_type : delay_types_[circuit_model_id]) { /* Parse the input port names and output names. @@ -1484,7 +1542,7 @@ void CircuitLibrary::set_timing_graph_delays(const CircuitModelId& circuit_model /* Try to find a port by the given name */ CircuitPortId port_id = port(circuit_model_id, port_info.get_name()); /* We must have a valid port and Port width must be 1! */ - VTR_ASSERT_SAFE(CIRCUIT_PORT_OPEN_ID != port_id); + VTR_ASSERT(CIRCUIT_PORT_OPEN_ID != port_id); if (0 == port_info.get_width()) { /* we need to configure the port width if it is zero. * This means that parser find some compact port defintion such as @@ -1492,12 +1550,12 @@ void CircuitLibrary::set_timing_graph_delays(const CircuitModelId& circuit_model size_t port_width = port_size(circuit_model_id, port_id); port_info.set_width(port_width); } else { - VTR_ASSERT_SAFE(1 == port_info.get_width()); + VTR_ASSERT(1 == port_info.get_width()); } /* The pin id should be valid! */ - VTR_ASSERT_SAFE(true == valid_circuit_pin_id(circuit_model_id, port_id, port_info.get_lsb())); + VTR_ASSERT(true == valid_circuit_pin_id(circuit_model_id, port_id, port_info.get_lsb())); /* This must be an input port! */ - VTR_ASSERT_SAFE(true == is_input_port(circuit_model_id, port_id)); + VTR_ASSERT(true == is_input_port(circuit_model_id, port_id)); /* Push to */ input_port_ids.push_back(port_id); input_pin_ids.push_back(port_info.get_lsb()); @@ -1513,7 +1571,7 @@ void CircuitLibrary::set_timing_graph_delays(const CircuitModelId& circuit_model /* Try to find a port by the given name */ CircuitPortId port_id = port(circuit_model_id, port_info.get_name()); /* We must have a valid port and Port width must be 1! */ - VTR_ASSERT_SAFE(CIRCUIT_PORT_OPEN_ID != port_id); + VTR_ASSERT(CIRCUIT_PORT_OPEN_ID != port_id); if (0 == port_info.get_width()) { /* we need to configure the port width if it is zero. * This means that parser find some compact port defintion such as @@ -1521,12 +1579,12 @@ void CircuitLibrary::set_timing_graph_delays(const CircuitModelId& circuit_model size_t port_width = port_size(circuit_model_id, port_id); port_info.set_width(port_width); } else { - VTR_ASSERT_SAFE(1 == port_info.get_width()); + VTR_ASSERT(1 == port_info.get_width()); } /* The pin id should be valid! */ - VTR_ASSERT_SAFE(true == valid_circuit_pin_id(circuit_model_id, port_id, port_info.get_lsb())); + VTR_ASSERT(true == valid_circuit_pin_id(circuit_model_id, port_id, port_info.get_lsb())); /* This must be an output port! */ - VTR_ASSERT_SAFE(true == is_output_port(circuit_model_id, port_id)); + VTR_ASSERT(true == is_output_port(circuit_model_id, port_id)); /* Push to */ output_port_ids.push_back(port_id); output_pin_ids.push_back(port_info.get_lsb()); @@ -1536,10 +1594,10 @@ void CircuitLibrary::set_timing_graph_delays(const CircuitModelId& circuit_model PortDelayParser port_delay_parser(delay_values_[circuit_model_id][size_t(delay_type)]); /* Make sure the delay matrix size matches */ - VTR_ASSERT_SAFE(port_delay_parser.height() == output_port_ids.size()); - VTR_ASSERT_SAFE(port_delay_parser.height() == output_pin_ids.size()); - VTR_ASSERT_SAFE(port_delay_parser.width() == input_port_ids.size()); - VTR_ASSERT_SAFE(port_delay_parser.width() == input_pin_ids.size()); + VTR_ASSERT(port_delay_parser.height() == output_port_ids.size()); + VTR_ASSERT(port_delay_parser.height() == output_pin_ids.size()); + VTR_ASSERT(port_delay_parser.width() == input_port_ids.size()); + VTR_ASSERT(port_delay_parser.width() == input_pin_ids.size()); /* Configure timing graph */ for (size_t i = 0; i < port_delay_parser.height(); ++i) { @@ -1549,7 +1607,7 @@ void CircuitLibrary::set_timing_graph_delays(const CircuitModelId& circuit_model input_port_ids[j], input_pin_ids[j], output_port_ids[i], output_pin_ids[i]); /* make sure we have an valid edge_id */ - VTR_ASSERT_SAFE(true == valid_circuit_edge_id(circuit_model_id, edge_id)); + VTR_ASSERT(true == valid_circuit_edge_id(circuit_model_id, edge_id)); set_edge_delay(circuit_model_id, edge_id, delay_type, delay_value); } @@ -1617,25 +1675,25 @@ bool CircuitLibrary::valid_circuit_model_id(const CircuitModelId& circuit_model_ bool CircuitLibrary::valid_circuit_port_id(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return ( size_t(circuit_port_id) < port_ids_[circuit_model_id].size() ) && ( circuit_port_id == port_ids_[circuit_model_id][circuit_port_id] ); } bool CircuitLibrary::valid_circuit_pin_id(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const size_t& pin_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_port_id(circuit_model_id, circuit_port_id)); + VTR_ASSERT(valid_circuit_port_id(circuit_model_id, circuit_port_id)); return ( size_t(pin_id) < port_size(circuit_model_id, circuit_port_id) ); } bool CircuitLibrary::valid_delay_type(const CircuitModelId& circuit_model_id, const enum spice_model_delay_type& delay_type) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return ( size_t(delay_type) < delay_types_[circuit_model_id].size() ) && ( delay_type == delay_types_[circuit_model_id][size_t(delay_type)] ); } bool CircuitLibrary::valid_circuit_edge_id(const CircuitModelId& circuit_model_id, const CircuitEdgeId& circuit_edge_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); return ( size_t(circuit_edge_id) < edge_ids_[circuit_model_id].size() ) && ( circuit_edge_id == edge_ids_[circuit_model_id][circuit_edge_id] ); } @@ -1649,7 +1707,7 @@ void CircuitLibrary::invalidate_circuit_model_lookup() const { /* Empty fast lookup for circuit ports for a circuit_model */ void CircuitLibrary::invalidate_circuit_model_port_lookup(const CircuitModelId& circuit_model_id) const { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); circuit_model_port_lookup_[size_t(circuit_model_id)].clear(); return; } @@ -1657,7 +1715,7 @@ void CircuitLibrary::invalidate_circuit_model_port_lookup(const CircuitModelId& /* Clear all the data structure related to the timing graph */ void CircuitLibrary::invalidate_circuit_model_timing_graph(const CircuitModelId& circuit_model_id) { /* validate the circuit_model_id */ - VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); edge_ids_[circuit_model_id].clear(); for (const auto& port_id : ports(circuit_model_id)) { diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.h b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.h index b655730d0..0b3ed3c06 100644 --- a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.h +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.h @@ -221,6 +221,7 @@ class CircuitLibrary { circuit_port_range ports(const CircuitModelId& circuit_model_id) const; std::vector circuit_models_by_type(const enum e_spice_model_type& type) const; std::vector ports_by_type(const CircuitModelId& circuit_model_id, const enum e_spice_model_port_type& port_type) const; + std::vector ports_by_type(const CircuitModelId& circuit_model_id, const enum e_spice_model_port_type& port_type, const bool& include_global_port) const; std::vector input_ports(const CircuitModelId& circuit_model_id) const; std::vector output_ports(const CircuitModelId& circuit_model_id) const; std::vector pins(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const; @@ -239,11 +240,13 @@ class CircuitLibrary { bool is_input_buffered(const CircuitModelId& circuit_model_id) const; bool is_output_buffered(const CircuitModelId& circuit_model_id) const; bool is_lut_intermediate_buffered(const CircuitModelId& circuit_model_id) const; + enum e_spice_model_structure mux_structure(const CircuitModelId& circuit_model_id) const; public: /* Public Accessors: Basic data query on Circuit Ports*/ bool is_input_port(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const; bool is_output_port(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const; CircuitPortId port(const CircuitModelId& circuit_model_id, const std::string& name) const; size_t num_ports(const CircuitModelId& circuit_model_id) const; + size_t num_ports_by_type(const CircuitModelId& circuit_model_id, const enum e_spice_model_port_type& port_type, const bool& include_global_port) const; enum e_spice_model_port_type port_type(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const; size_t port_size(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const; std::string port_prefix(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const; @@ -257,6 +260,7 @@ class CircuitLibrary { bool port_is_config_enable(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const; bool port_is_prog(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const; public: /* Public Accessors: Methods to find circuit model */ + CircuitModelId circuit_model(const char* name) const; CircuitModelId circuit_model(const std::string& name) const; CircuitModelId default_circuit_model(const enum e_spice_model_type& type) const; public: /* Public Accessors: Timing graph */ diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_types.h b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_types.h index 0ad9790dd..6d72b2242 100644 --- a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_types.h +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_types.h @@ -89,6 +89,8 @@ enum e_spice_model_structure { SPICE_MODEL_STRUCTURE_CROSSBAR, NUM_CIRCUIT_MODEL_STRUCTURE_TYPES }; +/* Strings correspond to each type of mux structure */ +constexpr std::array CIRCUIT_MODEL_STRUCTURE_TYPE_STRING = {{"TREE-LIKE", "ONE-LEVEL", "MULTI-LEVEL", "CROSSBAR"}}; enum e_spice_model_buffer_type { SPICE_MODEL_BUF_INV, @@ -138,6 +140,7 @@ enum e_sram_orgz { SPICE_SRAM_LOCAL_ENCODER, /* SRAMs are organized and accessed by a local encoder */ NUM_CIRCUIT_MODEL_SRAM_ORGZ_TYPES }; +constexpr std::array CIRCUIT_MODEL_SRAM_ORGZ_TYPE_STRING = {{"STANDALONE", "SCAN-CHAIN", "MEMORY_BANK", "LOCAL_ENCODER"}}; #endif diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/spice_types.h b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/spice_types.h index 1c333eb70..42ecbb3f2 100644 --- a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/spice_types.h +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/spice_types.h @@ -396,6 +396,7 @@ struct s_spice_mux_model { struct s_sram_inf_orgz { char* spice_model_name; // Xifan TANG: Spice Support t_spice_model* spice_model; // Xifan TANG: Spice Support + CircuitModelId circuit_model; enum e_sram_orgz type; }; diff --git a/vpr7_x2p/libarchfpga/SRC/include/physical_types.h b/vpr7_x2p/libarchfpga/SRC/include/physical_types.h index 24dee9ea8..81de09866 100644 --- a/vpr7_x2p/libarchfpga/SRC/include/physical_types.h +++ b/vpr7_x2p/libarchfpga/SRC/include/physical_types.h @@ -265,6 +265,7 @@ struct s_port { /* FPGA_SPICE_model support: * mapped SPICE model port */ t_spice_model_port* spice_model_port; + CircuitPortId circuit_model_port; char* physical_mode_pin; int physical_mode_pin_rotate_offset; /* The pin number will rotate by an offset unit when mapping to physical modes */ int phy_mode_pin_rotate_offset_acc; /* The pin number will rotate by an offset unit when mapping to physical modes */ @@ -341,6 +342,7 @@ struct s_interconnect { /* Xifan TANG: SPICE Support*/ char* spice_model_name; t_spice_model* spice_model; + CircuitModelId circuit_model; int fan_in; int fan_out; int num_mux; @@ -658,6 +660,7 @@ struct s_pb_type { char* physical_mode_name; char* spice_model_name; t_spice_model* spice_model; + CircuitModelId circuit_model; char* mode_bits; /* Mode bits to select */ int spice_model_sram_offset; char* physical_pb_type_name; @@ -846,6 +849,7 @@ typedef struct s_segment_inf { /* Xifan TANG: SPICE model support*/ char* spice_model_name; t_spice_model* spice_model; + CircuitModelId circuit_model; /* mrFPGA: Xifan TANG */ short seg_switch; /* end */ @@ -879,6 +883,7 @@ typedef struct s_switch_inf { /* Xifan TANG: spice support*/ char* spice_model_name; t_spice_model* spice_model; + CircuitModelId circuit_model; /* Xifan TANG: switch structure */ enum e_spice_model_structure structure; int switch_num_level; @@ -922,6 +927,7 @@ typedef struct s_direct_inf { /* Xifan Tang: FPGA-SPICE support */ char* spice_model_name; t_spice_model* spice_model; + CircuitModelId circuit_model; } t_direct_inf; diff --git a/vpr7_x2p/libarchfpga/SRC/read_xml_spice.c b/vpr7_x2p/libarchfpga/SRC/read_xml_spice.c index ac0892cf8..b2e66728c 100644 --- a/vpr7_x2p/libarchfpga/SRC/read_xml_spice.c +++ b/vpr7_x2p/libarchfpga/SRC/read_xml_spice.c @@ -1023,6 +1023,8 @@ static void ProcessSpiceModel(ezxml_t Parent, spice_model->design_tech_info.mux_info->structure = SPICE_MODEL_STRUCTURE_TREE; spice_model->design_tech_info.mux_info->add_const_input = FALSE; spice_model->design_tech_info.mux_info->const_input_val = 0; + spice_model->design_tech_info.mux_info->advanced_rram_design = FALSE; + spice_model->design_tech_info.mux_info->local_encoder = FALSE; } ezxml_set_attr(Node, "fracturable_lut", NULL); @@ -1632,7 +1634,8 @@ CircuitLibrary build_circuit_library(int num_spice_model, t_spice_model* spice_m } circuit_lib.set_circuit_model_lut_input_inverter(model_id, 0 != spice_models[imodel].lut_input_inverter->exist, model_name); } - if (NULL != spice_models[imodel].lut_intermediate_buffer) { + if ( (NULL != spice_models[imodel].lut_intermediate_buffer) + && (1 == spice_models[imodel].lut_intermediate_buffer->exist) ) { std::string model_name; if (NULL != spice_models[imodel].lut_intermediate_buffer->spice_model_name) { model_name = spice_models[imodel].lut_intermediate_buffer->spice_model_name; diff --git a/vpr7_x2p/vpr/SRC/base/vpr_types.h b/vpr7_x2p/vpr/SRC/base/vpr_types.h index 561362e1d..4b039d5c8 100755 --- a/vpr7_x2p/vpr/SRC/base/vpr_types.h +++ b/vpr7_x2p/vpr/SRC/base/vpr_types.h @@ -1128,6 +1128,7 @@ typedef struct s_clb_to_clb_directs { int y_offset; int z_offset; t_spice_model* spice_model; + CircuitModelId circuit_model; char* name; } t_clb_to_clb_directs; diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c index 748e62ef5..7e9042806 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c @@ -1301,6 +1301,7 @@ t_port* find_pb_type_port_match_spice_model_port(t_pb_type* pb_type, return ret; } + t_port** find_pb_type_ports_match_spice_model_port_type(t_pb_type* pb_type, enum e_spice_model_port_type port_type, int* port_num) { diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h index 34063fc95..075f9852c 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.h @@ -102,7 +102,6 @@ t_port** find_pb_type_ports_match_spice_model_port_type(t_pb_type* pb_type, enum e_spice_model_port_type port_type, int* port_num); - enum e_interconnect find_pb_graph_pin_in_edges_interc_type(t_pb_graph_pin pb_graph_pin); t_spice_model* find_pb_graph_pin_in_edges_interc_spice_model(t_pb_graph_pin pb_graph_pin); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_setup.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_setup.c index 011eca31a..fc36ffff6 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_setup.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_setup.c @@ -33,6 +33,7 @@ #include "verilog_api.h" #include "fpga_x2p_unique_routing.h" +#include "link_arch_circuit_lib.h" #include "fpga_x2p_setup.h" /***** Subroutines Declarations *****/ @@ -1322,10 +1323,14 @@ void fpga_x2p_setup(t_vpr_setup vpr_setup, /* Start time count */ t_start = clock(); - vpr_printf(TIO_MESSAGE_INFO, "\nFPGA-SPICE Tool suites Initilization begins...\n"); + vpr_printf(TIO_MESSAGE_INFO, "\nFPGA-X2P Tool suites Initilization begins...\n"); - /* Initialize Arch SPICE MODELS*/ + /* FIXME: this function is going to be removed when new linking function is working + * Initialize Arch SPICE MODELS + */ init_check_arch_spice_models(Arch, &(vpr_setup.RoutingArch)); + /* Link circuit models to architecture */ + link_circuit_library_to_arch(Arch, &(vpr_setup.RoutingArch)); /* Initialize idle mode and physical mode of each pb_type and pb_graph_node */ init_check_arch_pb_type_idle_and_phy_mode(); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.cpp b/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.cpp new file mode 100644 index 000000000..3cdd35eb1 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.cpp @@ -0,0 +1,592 @@ +/********************************************************** + * MIT License + * + * Copyright (c) 2018 LNIS - The University of Utah + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ***********************************************************************/ + +/************************************************************************ + * Filename: link_arch_circuit_lib.cpp + * Created by: Xifan Tang + * Change history: + * +-------------------------------------+ + * | Date | Author | Notes + * +-------------------------------------+ + * | 2019/08/12 | Xifan Tang | Created + * +-------------------------------------+ + ***********************************************************************/ +/************************************************************************ + * This file includes key functions to link circuit models to the architecture modules + ***********************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include vpr structs*/ +#include "util.h" +#include "physical_types.h" +#include "vpr_types.h" +#include "globals.h" +#include "rr_graph.h" +#include "vpr_utils.h" +#include "path_delay.h" +#include "stats.h" +#include "route_common.h" + +/* Include vtr libraries */ +#include "vtr_assert.h" + +/* Include spice support headers*/ +#include "linkedlist.h" +#include "fpga_x2p_types.h" +#include "fpga_x2p_globals.h" +#include "fpga_x2p_utils.h" +#include "fpga_x2p_timing_utils.h" +#include "fpga_x2p_backannotate_utils.h" +#include "fpga_x2p_pbtypes_utils.h" +#include "verilog_api.h" + +#include "check_circuit_library.h" +#include "link_arch_circuit_lib.h" + +/************************************************************************ + * Find a circuit model with a given name + * Case 1: if the circuit_model_name is not defined, + * we find a default circuit model and check its type + * Case 2: if the circuit_model_name is defined, + * we find a matched circuit model and check its type + ***********************************************************************/ +CircuitModelId link_circuit_model_by_name_and_type(const char* circuit_model_name, + const CircuitLibrary& circuit_lib, + const enum e_spice_model_type& model_type) { + CircuitModelId circuit_model = CIRCUIT_MODEL_OPEN_ID; + /* If the circuit_model_name is not defined, we use the default*/ + if (NULL == circuit_model_name) { + circuit_model = circuit_lib.default_circuit_model(model_type); + } else { + circuit_model = circuit_lib.circuit_model(circuit_model_name); + } + + /* Check the circuit model, we should have one! */ + if (CIRCUIT_MODEL_OPEN_ID == circuit_model) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,LINE[%d]) Fail to find a defined circuit model called %s!\n", + __FILE__, __LINE__, + circuit_lib.circuit_model_name(circuit_model).c_str()); + return circuit_model; /* Return here, no need to check the model_type */ + } + + /* Check the type of circuit model, make sure it is the one we want */ + if (model_type != circuit_lib.circuit_model_type(circuit_model)) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,LINE[%d]) Invalid type when trying to find circuit model called %s! Expect %s but found %s!\n", + __FILE__, __LINE__, + circuit_model_name, + CIRCUIT_MODEL_TYPE_STRING[size_t(model_type)], + CIRCUIT_MODEL_TYPE_STRING[size_t(circuit_lib.circuit_model_type(circuit_model))]); + } + + return circuit_model; +} + +/************************************************************************ + * Link circuit model to the SRAM organization + * Case 1: standalone organization required a SRAM circuit model + * Case 1: scan-chain organization required a SCFF circuit model + * Case 1: memory-bank organization required a SRAM circuit model + ***********************************************************************/ +static +void link_one_sram_inf_orgz(t_sram_inf_orgz* cur_sram_inf_orgz, + const CircuitLibrary& circuit_lib) { + /* If cur_sram_inf_orgz is not initialized, do nothing */ + if (NULL == cur_sram_inf_orgz) { + return; + } + + /* Check the type of SRAM_Ciruit_MODEL required by different sram organization */ + /* check SRAM ports + * Checker for circuit models used by the SRAM organization + * either SRAMs or SCFFs + * 1. It will check the basic port required for SRAMs and SCFFs + * 2. It will check any special ports required for SRAMs and SCFFs + */ + switch (cur_sram_inf_orgz->type) { + case SPICE_SRAM_STANDALONE: + cur_sram_inf_orgz->circuit_model = link_circuit_model_by_name_and_type(cur_sram_inf_orgz->spice_model_name, circuit_lib, SPICE_MODEL_SRAM); + /* check SRAM ports */ + check_sram_circuit_model_ports(circuit_lib, cur_sram_inf_orgz->circuit_model, false); + break; + case SPICE_SRAM_MEMORY_BANK: + cur_sram_inf_orgz->circuit_model = link_circuit_model_by_name_and_type(cur_sram_inf_orgz->spice_model_name, circuit_lib, SPICE_MODEL_SRAM); + /* check if this one has bit lines and word lines */ + check_sram_circuit_model_ports(circuit_lib, cur_sram_inf_orgz->circuit_model, true); + break; + case SPICE_SRAM_SCAN_CHAIN: + /* check Scan-chain Flip-flop ports */ + cur_sram_inf_orgz->circuit_model = link_circuit_model_by_name_and_type(cur_sram_inf_orgz->spice_model_name, circuit_lib, SPICE_MODEL_SCFF); + check_scff_circuit_model_ports(circuit_lib, cur_sram_inf_orgz->circuit_model); + break; + case SPICE_SRAM_LOCAL_ENCODER: + /* Wipe out LOCAL ENCODER, it is not supported here ! */ + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,LINE[%d]) Local encoder SRAM organization is not supported!\n", + __FILE__, __LINE__); + exit(1); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,LINE[%d]) Invalid SRAM organization!\n", + __FILE__, __LINE__); + exit(1); + } + + /* RRAM Scan-chain is not supported yet. Now just forbidden this option */ + if ( (SPICE_SRAM_SCAN_CHAIN == cur_sram_inf_orgz->type) + && (SPICE_MODEL_DESIGN_RRAM == circuit_lib.design_tech_type(cur_sram_inf_orgz->circuit_model)) ) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,LINE[%d]) RRAM-based Scan-chain Flip-flop has not been supported yet!\n", + __FILE__, __LINE__); + exit(1); + } + + return; +} + +static +void link_sram_inf(t_sram_inf* cur_sram_inf, + const CircuitLibrary& circuit_lib) { + /* We have two branches: + * 1. SPICE SRAM organization information + * 2. Verilog SRAM organization information + */ + link_one_sram_inf_orgz(cur_sram_inf->spice_sram_inf_orgz, + circuit_lib); + + link_one_sram_inf_orgz(cur_sram_inf->verilog_sram_inf_orgz, + circuit_lib); + + return; +} + + +/************************************************************************** + * With given circuit port, find the pb_type port with same name and type + **************************************************************************/ +t_port* find_pb_type_port_match_circuit_model_port(const t_pb_type* pb_type, + const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const CircuitPortId& circuit_port) { + t_port* ret = NULL; + size_t num_found = 0; + + /* Search ports */ + for (int iport = 0; iport < pb_type->num_ports; iport++) { + /* Match the name and port size*/ + if ( (0 == circuit_lib.port_prefix(circuit_model, circuit_port).compare(pb_type->ports[iport].name)) + && (size_t(pb_type->ports[iport].num_pins) == circuit_lib.port_size(circuit_model, circuit_port))) { + /* Match the type*/ + switch (circuit_lib.port_type(circuit_model, circuit_port)) { + case SPICE_MODEL_PORT_INPUT: + if ((IN_PORT == pb_type->ports[iport].type) + &&(0 == pb_type->ports[iport].is_clock)) { + ret = &(pb_type->ports[iport]); + num_found++; + } + break; + case SPICE_MODEL_PORT_OUTPUT: + if (OUT_PORT == pb_type->ports[iport].type) { + ret = &(pb_type->ports[iport]); + } + break; + case SPICE_MODEL_PORT_CLOCK: + if ((IN_PORT == pb_type->ports[iport].type)&&(1 == pb_type->ports[iport].is_clock)) { + ret = &(pb_type->ports[iport]); + num_found++; + } + break; + case SPICE_MODEL_PORT_INOUT : + if ((INOUT_PORT == pb_type->ports[iport].type)&&(0 == pb_type->ports[iport].is_clock)) { + ret = &(pb_type->ports[iport]); + num_found++; + } + break; + case SPICE_MODEL_PORT_SRAM: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR,"(File:%s, [LINE%d])Invalid type for circuit model port(%s)!\n", + __FILE__, __LINE__, circuit_lib.port_prefix(circuit_model, circuit_port)); + exit(1); + } + } + } + + /* We should find only 1 match */ + if (1 < num_found) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d])More than 1 pb_type(%s) port match spice_model_port(%s)!\n", + __FILE__, __LINE__, pb_type->name, circuit_lib.port_prefix(circuit_model, circuit_port).c_str()); + exit(1); + } + + return ret; +} + + +/************************************************************************ + * Map (synchronize) pb_type ports to circuit model ports + ***********************************************************************/ +static +int link_pb_type_port_to_circuit_model_ports(const t_pb_type* cur_pb_type, + const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model) { + + /* Check */ + assert(NULL != cur_pb_type); + + /* Initialize each port */ + for (int iport = 0; iport < cur_pb_type->num_ports; iport++) { + cur_pb_type->ports[iport].circuit_model_port = CIRCUIT_PORT_OPEN_ID; + } + + /* Return if SPICE_MODEL is NULL */ + if (CIRCUIT_MODEL_OPEN_ID == circuit_model) { + return 0; + } + + /* For each port, find a SPICE model port, which has the same name and port size */ + for (auto& port : circuit_lib.ports(circuit_model)) { + t_port* cur_pb_type_port = find_pb_type_port_match_circuit_model_port(cur_pb_type, circuit_lib, circuit_model, port); + /* Not every spice_model_port can find a mapped pb_type_port. + * Since a pb_type only includes necessary ports in technology mapping. + * ports for physical designs may be ignored ! + */ + if (NULL != cur_pb_type_port) { + cur_pb_type_port->circuit_model_port = port; + } + } + /* Although some spice_model_port may not have a corresponding pb_type_port + * but each pb_type_port should be mapped to a spice_model_port + */ + for (int iport = 0; iport < cur_pb_type->num_ports; iport++) { + if (CIRCUIT_PORT_OPEN_ID == cur_pb_type->ports[iport].circuit_model_port) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d])Pb_type(%s) Port(%s) cannot find a corresponding port in SPICE model(%s)\n", + __FILE__, __LINE__, cur_pb_type->name, cur_pb_type->ports[iport].name, + circuit_lib.circuit_model_name(circuit_model).c_str()); + exit(1); + } + } + + return cur_pb_type->num_ports; +} + +/************************************************************************ + * Find a circuit model for an interconnect in pb_type + * Case 1: if the circuit_model_name is not defined, + * we find a default circuit model and check its type + * Case 2: if the circuit_model_name is defined, + * we find a matched circuit model and check its type + ***********************************************************************/ +static +void link_pb_type_interc_circuit_model_by_type(t_interconnect* cur_interc, + const CircuitLibrary& circuit_lib, + const enum e_spice_model_type& model_type) { + + /* If the circuit_model_name is not defined, we use the default*/ + cur_interc->circuit_model = link_circuit_model_by_name_and_type(cur_interc->spice_model_name, + circuit_lib, + model_type); + /* Check the circuit model, we should have one! */ + if (CIRCUIT_MODEL_OPEN_ID == cur_interc->circuit_model) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,LINE[%d]) Error in linking circuit model for interconnect(name %s)! Check [LINE%d] in architecture file)!\n", + __FILE__, __LINE__, + cur_interc->name, + cur_interc->line_num); + exit(1); + } + + /* Special check for MUXes: + * If the multiplexers do not have any input buffers, the loop breaker cannot be disabled + */ + if (SPICE_MODEL_MUX == model_type) { + if (NULL != cur_interc->loop_breaker_string) { + if (false == circuit_lib.is_input_buffered(cur_interc->circuit_model)) { + vpr_printf(TIO_MESSAGE_INFO, + "Line[%d] Cannot disable an interconnect without input buffering.\n", + cur_interc->line_num); + } + } + } + + return; +} + +/************************************************************************ + * Find a circuit model for an interconnect in pb_type + * Case 1: if this is a DIRECT interconnection, + * we will try to find a circuit model whose type is WIRE + * Case 2: if this is a COMPLETE interconnection, we should evaluate + * the number of multiplexer required. + * when it does require multiplexers + * we will try to find a circuit model whose type is MUX + * otherwise, + * we will try to find a circuit model whose type is WIRE + * Case 3: if this is a MUX interconnection, + * we will try to find a circuit model whose type is WIRE + ***********************************************************************/ +static +void link_pb_type_interc_circuit_model(t_interconnect* cur_interc, + const CircuitLibrary& circuit_lib) { + switch (cur_interc->type) { + case DIRECT_INTERC: + link_pb_type_interc_circuit_model_by_type(cur_interc, circuit_lib, SPICE_MODEL_WIRE); + break; + case COMPLETE_INTERC: + /* Special for Completer Interconnection: + * 1. The input number is 1, this infers a direct interconnection. + * 2. The input number is larger than 1, this infers multplexers + * according to interconnect[j].num_mux identify the number of input at this level + */ + if (0 == cur_interc->num_mux) { + link_pb_type_interc_circuit_model_by_type(cur_interc, circuit_lib, SPICE_MODEL_WIRE); + } else { + link_pb_type_interc_circuit_model_by_type(cur_interc, circuit_lib, SPICE_MODEL_MUX); + } + break; + case MUX_INTERC: + link_pb_type_interc_circuit_model_by_type(cur_interc, circuit_lib, SPICE_MODEL_MUX); + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,LINE[%d]) Unknown type of interconnection (name=%s) defined in architecture file(LINE%d)!\n", + __FILE__, __LINE__, cur_interc->name, cur_interc->line_num); + exit(1); + } + return; +} + +/************************************************************************ + * Walk through the pb_types in a recursive way + * Find circuit_model_name definition in pb_types + * Try to match the name with defined spice_models + ***********************************************************************/ +static +void link_pb_types_circuit_model_rec(t_pb_type* cur_pb_type, + const CircuitLibrary& circuit_lib) { + if (NULL == cur_pb_type) { + vpr_printf(TIO_MESSAGE_WARNING, + "(File:%s,LINE[%d])cur_pb_type is null pointor!\n", + __FILE__, __LINE__); + return; + } + + /* If there is a circuit_model_name or physical_pb_type_name referring to a physical pb type, + * this is a leaf node! + */ + if ( TRUE == is_primitive_pb_type(cur_pb_type) ) { + /* What annoys me is VPR create a sub pb_type for each lut which suppose to be a leaf node + * This may bring software convience but ruins SPICE modeling + */ + if (NULL != cur_pb_type->physical_pb_type_name) { + /* if this is not a physical pb_type, we do not care its circuit_model_name*/ + return; + } + /* Let's find a matched circuit model!*/ + cur_pb_type->circuit_model = circuit_lib.circuit_model(cur_pb_type->spice_model_name); + if (CIRCUIT_MODEL_OPEN_ID == cur_pb_type->circuit_model) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,LINE[%d]) Fail to find a defined circuit model called %s, in pb_type(%s)!\n", + __FILE__, __LINE__, cur_pb_type->spice_model_name, cur_pb_type->name); + exit(1); + } + /* Map pb_type ports to SPICE model ports*/ + link_pb_type_port_to_circuit_model_ports(cur_pb_type, circuit_lib, cur_pb_type->circuit_model); + return; + } + + /* Otherwise, initialize it to be OPEN node */ + cur_pb_type->circuit_model = CIRCUIT_MODEL_OPEN_ID; + + /* Traversal the hierarchy*/ + for (int imode = 0; imode < cur_pb_type->num_modes; imode++) { + /* Task 1: Find the interconnections and match the spice_model */ + for (int jinterc = 0; jinterc < cur_pb_type->modes[imode].num_interconnect; jinterc++) { + /* Initialize it to be OPEN node */ + cur_pb_type->modes[imode].interconnect[jinterc].circuit_model = CIRCUIT_MODEL_OPEN_ID; + link_pb_type_interc_circuit_model(&(cur_pb_type->modes[imode].interconnect[jinterc]), + circuit_lib); + } + /* Task 2: Find the child pb_type, do matching recursively */ + for (int ipb = 0; ipb < cur_pb_type->modes[imode].num_pb_type_children; ipb++) { + link_pb_types_circuit_model_rec(&(cur_pb_type->modes[imode].pb_type_children[ipb]), circuit_lib); + } + } + return; +} + +/* Check if the spice model structure is the same with the switch_inf structure */ +static +size_t check_circuit_model_structure_match_switch_inf(const t_switch_inf& target_switch_inf, + const CircuitLibrary& circuit_lib) { + size_t num_err = 0; + + VTR_ASSERT_SAFE(CIRCUIT_MODEL_OPEN_ID != target_switch_inf.circuit_model); + if (target_switch_inf.structure != circuit_lib.mux_structure(target_switch_inf.circuit_model)) { + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s,[LINE%d]) Mismatch in MUX structure between circuit model(%s, %s) and switch_inf(%s, %s)!\n", + __FILE__, __LINE__, + circuit_lib.circuit_model_name(target_switch_inf.circuit_model).c_str(), + CIRCUIT_MODEL_STRUCTURE_TYPE_STRING[size_t(circuit_lib.mux_structure(target_switch_inf.circuit_model))], + target_switch_inf.name, + CIRCUIT_MODEL_STRUCTURE_TYPE_STRING[size_t(target_switch_inf.structure)]); + num_err++; + } + return num_err; +} + + +/************************************************************************ + * Initialize and check circuit models defined in architecture + * Tasks: + * 1. Link the circuit model defined in pb_types and routing switches + * 2. Add default circuit model for any inexplicit definition + ***********************************************************************/ +void link_circuit_library_to_arch(t_arch* arch, + t_det_routing_arch* routing_arch) { + + vpr_printf(TIO_MESSAGE_INFO, "Linking circuit models to modules in FPGA architecture...\n"); + + /* Check Circuit models first*/ + VTR_ASSERT_SAFE( (NULL != arch) && (NULL != arch->spice) ); + + /* 1. Link the spice model defined in pb_types and routing switches */ + /* Step A: Check routing switches, connection blocks*/ + if (0 >= arch->num_cb_switch) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s, LINE[%d]) Define Switches for Connection Blocks is mandatory in FPGA X2P support! Miss this part in architecture file.\n", + __FILE__,__LINE__); + exit(1); + } + + for (int i = 0; i < arch->num_cb_switch; i++) { + arch->cb_switches[i].circuit_model = link_circuit_model_by_name_and_type(arch->cb_switches[i].spice_model_name, + arch->spice->circuit_lib, SPICE_MODEL_MUX); + if (CIRCUIT_MODEL_OPEN_ID == arch->cb_switches[i].circuit_model) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s, LINE[%d])Invalid circuit model name(%s) of Switch(%s) is undefined in circuit models!\n", + __FILE__, __LINE__, arch->cb_switches[i].spice_model_name, arch->cb_switches[i].name); + exit(1); + } + /* Check the spice model structure is matched with the structure in switch_inf */ + if (0 < check_circuit_model_structure_match_switch_inf(arch->cb_switches[i], arch->spice->circuit_lib)) { + exit(1); + } + } + + /* Step B: Check switch list: Switch Box*/ + if (0 >= arch->num_switches) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s, LINE[%d]) Define Switches for Switch Boxes is mandatory in FPGA X2P support! Miss this part in architecture file.\n", + __FILE__, __LINE__); + exit(1); + } + + for (int i = 0; i < arch->num_switches; i++) { + arch->Switches[i].circuit_model = link_circuit_model_by_name_and_type(arch->Switches[i].spice_model_name, + arch->spice->circuit_lib, SPICE_MODEL_MUX); + if (CIRCUIT_MODEL_OPEN_ID == arch->Switches[i].circuit_model) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s, LINE[%d])Invalid circuit model name(%s) of Switch(%s) is undefined in circuit models!\n", + __FILE__, __LINE__, arch->Switches[i].spice_model_name, arch->Switches[i].name); + exit(1); + } + /* Check the spice model structure is matched with the structure in switch_inf */ + if (0 < check_circuit_model_structure_match_switch_inf(arch->Switches[i], arch->spice->circuit_lib)) { + exit(1); + } + } + + /* Update the switches in detailed routing architecture settings*/ + for (int i = 0; i < routing_arch->num_switch; i++) { + switch_inf[i].circuit_model = link_circuit_model_by_name_and_type(switch_inf[i].spice_model_name, + arch->spice->circuit_lib, SPICE_MODEL_MUX); + if (CIRCUIT_MODEL_OPEN_ID == switch_inf[i].circuit_model) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s, LINE[%d])Invalid circuit model name(%s) of Switch(%s) is undefined in circuit models!\n", + __FILE__, __LINE__, switch_inf[i].spice_model_name, switch_inf[i].name); + exit(1); + } + } + + /* Step C: Find SRAM Model*/ + link_sram_inf(&(arch->sram_inf), arch->spice->circuit_lib); + + /* Step D: Find the segment spice_model*/ + for (int i = 0; i < arch->num_segments; i++) { + arch->Segments[i].circuit_model = link_circuit_model_by_name_and_type(arch->Segments[i].spice_model_name, + arch->spice->circuit_lib, SPICE_MODEL_CHAN_WIRE); + if (CIRCUIT_MODEL_OPEN_ID == arch->Segments[i].circuit_model) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s, LINE[%d])Invalid circuit model name(%s) of Segment(Length:%d) is undefined in circuit models!\n", + __FILE__ ,__LINE__, + arch->Segments[i].spice_model_name, + arch->Segments[i].length); + exit(1); + } + } + + /* Step E: Direct connections between CLBs */ + for (int i = 0; i < arch->num_directs; i++) { + arch->Directs[i].circuit_model = link_circuit_model_by_name_and_type(arch->Directs[i].spice_model_name, + arch->spice->circuit_lib, SPICE_MODEL_WIRE); + /* Check SPICE model type */ + if (CIRCUIT_MODEL_OPEN_ID == arch->Directs[i].circuit_model) { + vpr_printf(TIO_MESSAGE_ERROR, + "(FILE:%s, LINE[%d])Invalid circuit model name(%s) of CLB to CLB Direct Connection (name=%s) is undefined in circuit models!\n", + __FILE__ ,__LINE__, + arch->Directs[i].spice_model_name, + arch->Directs[i].name); + exit(1); + } + /* Copy it to clb2clb_directs */ + clb2clb_direct[i].circuit_model = arch->Directs[i].circuit_model; + } + + /* 2. Search Complex Blocks (Pb_Types), Link spice_model according to the spice_model_name*/ + for (int i = 0; i < num_types; i++) { + if (NULL != type_descriptors[i].pb_type) { + link_pb_types_circuit_model_rec(type_descriptors[i].pb_type, arch->spice->circuit_lib); + } + } + + vpr_printf(TIO_MESSAGE_INFO, "Linking circuit models to modules in FPGA architecture...Completed\n"); + + return; +} + +/************************************************************************ + * End of file : link_arch_circuit_lib.cpp + ***********************************************************************/ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.h new file mode 100644 index 000000000..1b134a78d --- /dev/null +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/link_arch_circuit_lib.h @@ -0,0 +1,68 @@ +/********************************************************** + * MIT License + * + * Copyright (c) 2018 LNIS - The University of Utah + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ***********************************************************************/ + +/************************************************************************ + * Filename: link_arch_circuit_lib.h + * Created by: Xifan Tang + * Change history: + * +-------------------------------------+ + * | Date | Author | Notes + * +-------------------------------------+ + * | 2019/08/12 | Xifan Tang | Created + * +-------------------------------------+ + ***********************************************************************/ + +/* IMPORTANT: + * The following preprocessing flags are added to + * avoid compilation error when this headers are included in more than 1 times + */ +#ifndef LINK_ARCH_CIRCUIT_LIB_H +#define LINK_ARCH_CIRCUIT_LIB_H + +/* + * Notes in include header files in a head file + * Only include the neccessary header files + * that is required by the data types in the function/class declarations! + */ +/* Header files should be included in a sequence */ +/* Standard header files required go first */ + +CircuitModelId link_circuit_model_by_name_and_type(const char* circuit_model_name, + const CircuitLibrary& circuit_lib, + const enum e_spice_model_type& model_type); + +t_port* find_pb_type_port_match_circuit_model_port(const t_pb_type* pb_type, + const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const CircuitPortId& circuit_port); + +void link_circuit_library_to_arch(t_arch* arch, + t_det_routing_arch* routing_arch); + +#endif + +/************************************************************************ + * End of file : link_arch_circuit_lib.h + ***********************************************************************/ +