From 392f5798368c40b2a685dab1e2090270a6144e1d Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 13 Aug 2019 13:25:23 -0600 Subject: [PATCH 1/7] 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 + ***********************************************************************/ + From ef4d15df4e0bcf7b50d82555d3612cf473364d8b Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 13 Aug 2019 13:37:35 -0600 Subject: [PATCH 2/7] reorganize the libarchfpga repository --- vpr7_x2p/libarchfpga/SRC/{include => }/ReadLine.h | 0 vpr7_x2p/libarchfpga/SRC/{include => }/arch_types.h | 0 vpr7_x2p/libarchfpga/SRC/{include => }/arch_types_mrfpga.h | 0 vpr7_x2p/libarchfpga/SRC/{include => }/cad_types.h | 0 .../SRC/{fpga_spice_include => }/check_circuit_library.cpp | 0 .../SRC/{fpga_spice_include => }/check_circuit_library.h | 0 .../SRC/{fpga_spice_include => }/circuit_library.cpp | 0 .../libarchfpga/SRC/{fpga_spice_include => }/circuit_library.h | 0 .../libarchfpga/SRC/{fpga_spice_include => }/circuit_types.h | 0 .../libarchfpga/SRC/{fpga_spice_include => }/device_port.cpp | 0 vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/device_port.h | 0 vpr7_x2p/libarchfpga/SRC/{include => }/ezxml.h | 0 vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/linkedlist.h | 0 vpr7_x2p/libarchfpga/SRC/{include => }/logic_types.h | 0 vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/my_free_fwd.h | 0 vpr7_x2p/libarchfpga/SRC/{include => }/physical_types.h | 0 .../libarchfpga/SRC/{fpga_spice_include => }/port_parser.cpp | 0 vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/port_parser.h | 0 vpr7_x2p/libarchfpga/SRC/{include => }/read_xml_arch_file.h | 0 vpr7_x2p/libarchfpga/SRC/{include => }/read_xml_mrfpga.h | 0 .../libarchfpga/SRC/{fpga_spice_include => }/read_xml_spice.h | 0 .../SRC/{fpga_spice_include => }/read_xml_spice_util.h | 0 vpr7_x2p/libarchfpga/SRC/{include => }/read_xml_util.h | 0 vpr7_x2p/libarchfpga/SRC/{include => }/sides.h | 0 vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/spice_types.h | 0 .../libarchfpga/SRC/{fpga_spice_include => }/string_token.cpp | 0 .../libarchfpga/SRC/{fpga_spice_include => }/string_token.h | 0 vpr7_x2p/libarchfpga/SRC/{include => }/util.h | 0 vpr7_x2p/vpr/SRC/ctags_vpr_src.sh | 2 +- 29 files changed, 1 insertion(+), 1 deletion(-) rename vpr7_x2p/libarchfpga/SRC/{include => }/ReadLine.h (100%) rename vpr7_x2p/libarchfpga/SRC/{include => }/arch_types.h (100%) rename vpr7_x2p/libarchfpga/SRC/{include => }/arch_types_mrfpga.h (100%) rename vpr7_x2p/libarchfpga/SRC/{include => }/cad_types.h (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/check_circuit_library.cpp (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/check_circuit_library.h (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/circuit_library.cpp (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/circuit_library.h (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/circuit_types.h (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/device_port.cpp (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/device_port.h (100%) rename vpr7_x2p/libarchfpga/SRC/{include => }/ezxml.h (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/linkedlist.h (100%) rename vpr7_x2p/libarchfpga/SRC/{include => }/logic_types.h (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/my_free_fwd.h (100%) rename vpr7_x2p/libarchfpga/SRC/{include => }/physical_types.h (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/port_parser.cpp (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/port_parser.h (100%) rename vpr7_x2p/libarchfpga/SRC/{include => }/read_xml_arch_file.h (100%) rename vpr7_x2p/libarchfpga/SRC/{include => }/read_xml_mrfpga.h (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/read_xml_spice.h (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/read_xml_spice_util.h (100%) rename vpr7_x2p/libarchfpga/SRC/{include => }/read_xml_util.h (100%) rename vpr7_x2p/libarchfpga/SRC/{include => }/sides.h (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/spice_types.h (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/string_token.cpp (100%) rename vpr7_x2p/libarchfpga/SRC/{fpga_spice_include => }/string_token.h (100%) rename vpr7_x2p/libarchfpga/SRC/{include => }/util.h (100%) diff --git a/vpr7_x2p/libarchfpga/SRC/include/ReadLine.h b/vpr7_x2p/libarchfpga/SRC/ReadLine.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/include/ReadLine.h rename to vpr7_x2p/libarchfpga/SRC/ReadLine.h diff --git a/vpr7_x2p/libarchfpga/SRC/include/arch_types.h b/vpr7_x2p/libarchfpga/SRC/arch_types.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/include/arch_types.h rename to vpr7_x2p/libarchfpga/SRC/arch_types.h diff --git a/vpr7_x2p/libarchfpga/SRC/include/arch_types_mrfpga.h b/vpr7_x2p/libarchfpga/SRC/arch_types_mrfpga.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/include/arch_types_mrfpga.h rename to vpr7_x2p/libarchfpga/SRC/arch_types_mrfpga.h diff --git a/vpr7_x2p/libarchfpga/SRC/include/cad_types.h b/vpr7_x2p/libarchfpga/SRC/cad_types.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/include/cad_types.h rename to vpr7_x2p/libarchfpga/SRC/cad_types.h diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/check_circuit_library.cpp b/vpr7_x2p/libarchfpga/SRC/check_circuit_library.cpp similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/check_circuit_library.cpp rename to vpr7_x2p/libarchfpga/SRC/check_circuit_library.cpp diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/check_circuit_library.h b/vpr7_x2p/libarchfpga/SRC/check_circuit_library.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/check_circuit_library.h rename to vpr7_x2p/libarchfpga/SRC/check_circuit_library.h diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.cpp b/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.cpp rename to vpr7_x2p/libarchfpga/SRC/circuit_library.cpp diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.h b/vpr7_x2p/libarchfpga/SRC/circuit_library.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.h rename to vpr7_x2p/libarchfpga/SRC/circuit_library.h diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_types.h b/vpr7_x2p/libarchfpga/SRC/circuit_types.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_types.h rename to vpr7_x2p/libarchfpga/SRC/circuit_types.h diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/device_port.cpp b/vpr7_x2p/libarchfpga/SRC/device_port.cpp similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/device_port.cpp rename to vpr7_x2p/libarchfpga/SRC/device_port.cpp diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/device_port.h b/vpr7_x2p/libarchfpga/SRC/device_port.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/device_port.h rename to vpr7_x2p/libarchfpga/SRC/device_port.h diff --git a/vpr7_x2p/libarchfpga/SRC/include/ezxml.h b/vpr7_x2p/libarchfpga/SRC/ezxml.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/include/ezxml.h rename to vpr7_x2p/libarchfpga/SRC/ezxml.h diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/linkedlist.h b/vpr7_x2p/libarchfpga/SRC/linkedlist.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/linkedlist.h rename to vpr7_x2p/libarchfpga/SRC/linkedlist.h diff --git a/vpr7_x2p/libarchfpga/SRC/include/logic_types.h b/vpr7_x2p/libarchfpga/SRC/logic_types.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/include/logic_types.h rename to vpr7_x2p/libarchfpga/SRC/logic_types.h diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/my_free_fwd.h b/vpr7_x2p/libarchfpga/SRC/my_free_fwd.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/my_free_fwd.h rename to vpr7_x2p/libarchfpga/SRC/my_free_fwd.h diff --git a/vpr7_x2p/libarchfpga/SRC/include/physical_types.h b/vpr7_x2p/libarchfpga/SRC/physical_types.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/include/physical_types.h rename to vpr7_x2p/libarchfpga/SRC/physical_types.h diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/port_parser.cpp b/vpr7_x2p/libarchfpga/SRC/port_parser.cpp similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/port_parser.cpp rename to vpr7_x2p/libarchfpga/SRC/port_parser.cpp diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/port_parser.h b/vpr7_x2p/libarchfpga/SRC/port_parser.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/port_parser.h rename to vpr7_x2p/libarchfpga/SRC/port_parser.h diff --git a/vpr7_x2p/libarchfpga/SRC/include/read_xml_arch_file.h b/vpr7_x2p/libarchfpga/SRC/read_xml_arch_file.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/include/read_xml_arch_file.h rename to vpr7_x2p/libarchfpga/SRC/read_xml_arch_file.h diff --git a/vpr7_x2p/libarchfpga/SRC/include/read_xml_mrfpga.h b/vpr7_x2p/libarchfpga/SRC/read_xml_mrfpga.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/include/read_xml_mrfpga.h rename to vpr7_x2p/libarchfpga/SRC/read_xml_mrfpga.h diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/read_xml_spice.h b/vpr7_x2p/libarchfpga/SRC/read_xml_spice.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/read_xml_spice.h rename to vpr7_x2p/libarchfpga/SRC/read_xml_spice.h diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/read_xml_spice_util.h b/vpr7_x2p/libarchfpga/SRC/read_xml_spice_util.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/read_xml_spice_util.h rename to vpr7_x2p/libarchfpga/SRC/read_xml_spice_util.h diff --git a/vpr7_x2p/libarchfpga/SRC/include/read_xml_util.h b/vpr7_x2p/libarchfpga/SRC/read_xml_util.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/include/read_xml_util.h rename to vpr7_x2p/libarchfpga/SRC/read_xml_util.h diff --git a/vpr7_x2p/libarchfpga/SRC/include/sides.h b/vpr7_x2p/libarchfpga/SRC/sides.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/include/sides.h rename to vpr7_x2p/libarchfpga/SRC/sides.h diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/spice_types.h b/vpr7_x2p/libarchfpga/SRC/spice_types.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/spice_types.h rename to vpr7_x2p/libarchfpga/SRC/spice_types.h diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/string_token.cpp b/vpr7_x2p/libarchfpga/SRC/string_token.cpp similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/string_token.cpp rename to vpr7_x2p/libarchfpga/SRC/string_token.cpp diff --git a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/string_token.h b/vpr7_x2p/libarchfpga/SRC/string_token.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/fpga_spice_include/string_token.h rename to vpr7_x2p/libarchfpga/SRC/string_token.h diff --git a/vpr7_x2p/libarchfpga/SRC/include/util.h b/vpr7_x2p/libarchfpga/SRC/util.h similarity index 100% rename from vpr7_x2p/libarchfpga/SRC/include/util.h rename to vpr7_x2p/libarchfpga/SRC/util.h diff --git a/vpr7_x2p/vpr/SRC/ctags_vpr_src.sh b/vpr7_x2p/vpr/SRC/ctags_vpr_src.sh index 5a37c337a..919a90230 100755 --- a/vpr7_x2p/vpr/SRC/ctags_vpr_src.sh +++ b/vpr7_x2p/vpr/SRC/ctags_vpr_src.sh @@ -1,2 +1,2 @@ rm tags -ctags -R shell_main.c main.c ./* ../../libarchfpga/SRC/include/*.[ch] ../../libarchfpga/SRC/fpga_spice_include/*.[ch] ../../libarchfpga/SRC/*.[ch] ../../pcre/SRC/*.[ch] +ctags -R shell_main.c main.c ./* ../../libarchfpga/SRC/*.[ch] ../../pcre/SRC/*.[ch] From c7526cb43cd531e4d35207a57a8682625cc5a4a2 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 13 Aug 2019 14:19:40 -0600 Subject: [PATCH 3/7] memory sanitized --- vpr7_x2p/libarchfpga/SRC/check_circuit_library.cpp | 2 +- vpr7_x2p/libarchfpga/SRC/circuit_library.cpp | 11 +++++++---- vpr7_x2p/libarchfpga/SRC/circuit_library.h | 1 + vpr7_x2p/libarchfpga/SRC/circuit_types.h | 2 +- vpr7_x2p/libarchfpga/SRC/read_xml_spice.c | 5 +++-- vpr7_x2p/vpr/SRC/base/SetupVPR.c | 2 +- vpr7_x2p/vpr/SRC/ctags_vpr_src.sh | 2 +- 7 files changed, 15 insertions(+), 10 deletions(-) diff --git a/vpr7_x2p/libarchfpga/SRC/check_circuit_library.cpp b/vpr7_x2p/libarchfpga/SRC/check_circuit_library.cpp index 98952927f..0b0f8fa69 100644 --- a/vpr7_x2p/libarchfpga/SRC/check_circuit_library.cpp +++ b/vpr7_x2p/libarchfpga/SRC/check_circuit_library.cpp @@ -450,7 +450,7 @@ void check_circuit_library(const CircuitLibrary& circuit_lib) { num_err += check_required_default_circuit_model(circuit_lib, SPICE_MODEL_WIRE); /* If we have any errors, exit */ - vpr_printf(TIO_MESSAGE_ERROR, + vpr_printf(TIO_MESSAGE_INFO, "Finished checking circuit library with %d errors!\n", num_err); diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp b/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp index 6bd5aab07..4da76e417 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp @@ -48,6 +48,9 @@ /************************************************************************ * Constructors ***********************************************************************/ +CircuitLibrary::CircuitLibrary() { + return; +} /************************************************************************ * Public Accessors : aggregates @@ -1272,7 +1275,7 @@ void CircuitLibrary::set_wire_type(const CircuitModelId& 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( (SPICE_MODEL_WIRE == circuit_model_type(circuit_model_id)) - || (SPICE_MODEL_CHAN_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; } @@ -1283,7 +1286,7 @@ void CircuitLibrary::set_wire_r(const CircuitModelId& 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( (SPICE_MODEL_WIRE == circuit_model_type(circuit_model_id)) - || (SPICE_MODEL_CHAN_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; } @@ -1294,7 +1297,7 @@ void CircuitLibrary::set_wire_c(const CircuitModelId& 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( (SPICE_MODEL_WIRE == circuit_model_type(circuit_model_id)) - || (SPICE_MODEL_CHAN_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; } @@ -1305,7 +1308,7 @@ void CircuitLibrary::set_wire_num_levels(const CircuitModelId& 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( (SPICE_MODEL_WIRE == circuit_model_type(circuit_model_id)) - || (SPICE_MODEL_CHAN_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; } diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library.h b/vpr7_x2p/libarchfpga/SRC/circuit_library.h index 0b3ed3c06..1717bb60f 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library.h +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library.h @@ -216,6 +216,7 @@ class CircuitLibrary { INPUT = 0, OUTPUT, LUT_INPUT_BUFFER, LUT_INPUT_INVERTER, LUT_INTER_BUFFER, NUM_BUFFER_TYPE /* Last one is a counter */ }; public: /* Constructors */ + CircuitLibrary(); public: /* Accessors: aggregates */ circuit_model_range circuit_models() const; circuit_port_range ports(const CircuitModelId& circuit_model_id) const; diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_types.h b/vpr7_x2p/libarchfpga/SRC/circuit_types.h index 6d72b2242..a2b86f38f 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_types.h +++ b/vpr7_x2p/libarchfpga/SRC/circuit_types.h @@ -114,7 +114,7 @@ enum e_spice_model_gate_type { enum e_wire_model_type { WIRE_MODEL_PIE, WIRE_MODEL_T, - NUM_WIRE_MODEL_TYPES, + NUM_WIRE_MODEL_TYPES }; enum e_spice_model_port_type { diff --git a/vpr7_x2p/libarchfpga/SRC/read_xml_spice.c b/vpr7_x2p/libarchfpga/SRC/read_xml_spice.c index b2e66728c..17ebb718a 100644 --- a/vpr7_x2p/libarchfpga/SRC/read_xml_spice.c +++ b/vpr7_x2p/libarchfpga/SRC/read_xml_spice.c @@ -1028,7 +1028,6 @@ static void ProcessSpiceModel(ezxml_t Parent, } ezxml_set_attr(Node, "fracturable_lut", NULL); - spice_model->design_tech_info.gate_info = NULL; if (SPICE_MODEL_GATE == spice_model->type) { /* Malloc */ @@ -1073,13 +1072,15 @@ static void ProcessSpiceModel(ezxml_t Parent, /* LUT intermediate buffers */ Node = ezxml_child(Parent, "lut_intermediate_buffer"); - spice_model->lut_intermediate_buffer = (t_spice_model_buffer*)my_calloc(1, sizeof(t_spice_model_buffer)); + spice_model->lut_intermediate_buffer = NULL; if (Node) { + spice_model->lut_intermediate_buffer = (t_spice_model_buffer*)my_calloc(1, sizeof(t_spice_model_buffer)); /* Malloc the lut_input_buffer */ ProcessSpiceModelBuffer(Node,spice_model->lut_intermediate_buffer); FreeNode(Node); } else if ((SPICE_MODEL_LUT == spice_model->type) || (SPICE_MODEL_MUX == spice_model->type)) { + spice_model->lut_intermediate_buffer = (t_spice_model_buffer*)my_calloc(1, sizeof(t_spice_model_buffer)); /* Assign default values */ spice_model->lut_intermediate_buffer->exist = 0; spice_model->lut_intermediate_buffer->spice_model = NULL; diff --git a/vpr7_x2p/vpr/SRC/base/SetupVPR.c b/vpr7_x2p/vpr/SRC/base/SetupVPR.c index 7a78d6d97..5b0e90004 100644 --- a/vpr7_x2p/vpr/SRC/base/SetupVPR.c +++ b/vpr7_x2p/vpr/SRC/base/SetupVPR.c @@ -1186,7 +1186,7 @@ static void SetupSynVerilogOpts(t_options Options, /* SynVerilog needs the input from spice modeling */ if (FALSE == arch->read_xml_spice) { arch->read_xml_spice = syn_verilog_opts->dump_syn_verilog; - arch->spice = (t_spice*)my_malloc(sizeof(t_spice)); + arch->spice = (t_spice*)my_calloc(1, sizeof(t_spice)); } return; diff --git a/vpr7_x2p/vpr/SRC/ctags_vpr_src.sh b/vpr7_x2p/vpr/SRC/ctags_vpr_src.sh index 919a90230..95bff29de 100755 --- a/vpr7_x2p/vpr/SRC/ctags_vpr_src.sh +++ b/vpr7_x2p/vpr/SRC/ctags_vpr_src.sh @@ -1,2 +1,2 @@ rm tags -ctags -R shell_main.c main.c ./* ../../libarchfpga/SRC/*.[ch] ../../pcre/SRC/*.[ch] +ctags -R shell_main.c main.c ./* ../../libarchfpga/SRC/* ../../pcre/SRC/*.[ch] From 4cffd8ac2d78a3cb1ee170e08ea70bac4822d743 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 13 Aug 2019 15:37:42 -0600 Subject: [PATCH 4/7] keep route file updated with tileable rr_graph --- .../rr_graph/rr_graph_builder_utils.cpp | 27 +++++++++++++++++++ .../device/rr_graph/rr_graph_builder_utils.h | 3 +++ vpr7_x2p/vpr/SRC/route/route_common.c | 15 ++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.cpp b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.cpp index 6752def9e..167d6d161 100644 --- a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.cpp +++ b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.cpp @@ -341,6 +341,33 @@ void add_edges_for_two_rr_nodes(const t_rr_graph* rr_graph, } +/************************************************************************ + * Get the track_id of a routing track w.r.t its coordinator + * In tileable routing architecture, the track_id changes SB by SB. + * Therefore the track_ids are stored in a vector, indexed by the relative coordinator + * based on the starting point of the track + * For routing tracks in INC_DIRECTION + * (xlow, ylow) should be the starting point + * + * (xlow, ylow) (xhigh, yhigh) + * track_id[0] -------------------------------> track_id[xhigh - xlow + yhigh - ylow] + * + * For routing tracks in DEC_DIRECTION + * (xhigh, yhigh) should be the starting point + * + * (xlow, ylow) (xhigh, yhigh) + * track_id[0] <------------------------------- track_id[xhigh - xlow + yhigh - ylow] + * + * + ***********************************************************************/ +short get_rr_node_actual_track_id(const t_rr_node* track_rr_node, + const DeviceCoordinator& coord) { + DeviceCoordinator low_coord(track_rr_node->xlow, track_rr_node->ylow); + size_t offset = (int)abs((int)coord.get_x() - (int)low_coord.get_x() + (int)coord.get_y() - (int)low_coord.get_y()); + return track_rr_node->track_ids[offset]; +} + + /************************************************************************ * Get the coordinator of a starting point of a routing track * For routing tracks in INC_DIRECTION diff --git a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.h b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.h index c213546d5..5ef5382f3 100644 --- a/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.h +++ b/vpr7_x2p/vpr/SRC/device/rr_graph/rr_graph_builder_utils.h @@ -35,6 +35,9 @@ void add_edges_for_two_rr_nodes(const t_rr_graph* rr_graph, const std::vector des_rr_node, const std::vector driver_switches); +short get_rr_node_actual_track_id(const t_rr_node* track_rr_node, + const DeviceCoordinator& coord); + DeviceCoordinator get_track_rr_node_start_coordinator(const t_rr_node* track_rr_node); DeviceCoordinator get_track_rr_node_end_coordinator(const t_rr_node* track_rr_node); diff --git a/vpr7_x2p/vpr/SRC/route/route_common.c b/vpr7_x2p/vpr/SRC/route/route_common.c index ad8f2d8eb..83b7c8070 100755 --- a/vpr7_x2p/vpr/SRC/route/route_common.c +++ b/vpr7_x2p/vpr/SRC/route/route_common.c @@ -20,6 +20,8 @@ #include "buffer_insertion.h" /* end */ +#include "rr_graph_builder_utils.h" + /* Xifan TANG: useful functions for pb_pin_eq_auto_detect */ void reassign_rr_node_net_num_from_scratch(); @@ -1214,7 +1216,18 @@ void print_route(char *route_file) { break; } - fprintf(fp, "%d ", rr_node[inode].ptc_num); + /* A kind of dirty fix for tileable routing, + * the track_ids is allocated by tileable routing. + * If the vector is not empty, it means tileable routing is enabled + * we need another function to get the track_id rather than ptc_num + */ + if (0 == rr_node[inode].track_ids.size()) { + fprintf(fp, "%d ", rr_node[inode].ptc_num); + } else { + /* Xifan Tang: for routing tracks, get the actual track ids */ + DeviceCoordinator cur_coord(ilow, jlow); + fprintf(fp, "%d ", get_rr_node_actual_track_id(&(rr_node[inode]), cur_coord)); + } /* Uncomment line below if you're debugging and want to see the switch types * * used in the routing. */ From 1118b28397fac4a335e4ab1290f31ed923656d72 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 13 Aug 2019 16:11:04 -0600 Subject: [PATCH 5/7] use single subckt for switch box again, to abolish the multi-module subckt --- vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c index eb736e27e..76bf438d0 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_routing.c @@ -2350,7 +2350,7 @@ void dump_verilog_routing_switch_box_unique_subckt(t_sram_orgz_info* cur_sram_or dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info, rr_gsb.get_sb_conf_bits_lsb(), rr_gsb.get_sb_conf_bits_msb(), - VERILOG_PORT_OUTPUT, is_explicit_mapping); + VERILOG_PORT_INPUT, is_explicit_mapping); fprintf(fp, "\n"); fprintf(fp, "`endif\n"); } @@ -3967,7 +3967,7 @@ void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info, /* Create a snapshot on sram_orgz_info */ t_sram_orgz_info* stamped_sram_orgz_info = snapshot_sram_orgz_info(cur_sram_orgz_info); - /* Output unique side modules */ + /* Output unique side modules for (size_t side = 0; side < device_rr_gsb.get_max_num_sides(); ++side) { Side side_manager(side); for (size_t iseg = 0; iseg < device_rr_gsb.get_num_segments(); ++iseg) { @@ -3978,12 +3978,17 @@ void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info, } } } + */ /* Output unique modules */ for (size_t isb = 0; isb < device_rr_gsb.get_num_sb_unique_module(); ++isb) { const RRGSB& unique_mirror = device_rr_gsb.get_sb_unique_module(isb); + /* dump_verilog_routing_switch_box_unique_module(cur_sram_orgz_info, verilog_dir, subckt_dir, unique_mirror, explicit_port_mapping); + */ + dump_verilog_routing_switch_box_unique_subckt(cur_sram_orgz_info, verilog_dir, + subckt_dir, unique_mirror, explicit_port_mapping); } /* Restore sram_orgz_info to the base */ From edfa72a666731a9423b55782490880a0564a60d7 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 13 Aug 2019 16:47:28 -0600 Subject: [PATCH 6/7] try to fix the bug in clock net identification --- vpr7_x2p/vpr/SRC/base/read_blif.c | 5 ++++- vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_pbtypes_utils.c | 6 ++---- vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_pbtypes.c | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/vpr7_x2p/vpr/SRC/base/read_blif.c b/vpr7_x2p/vpr/SRC/base/read_blif.c index 8e982725d..75008fc3f 100644 --- a/vpr7_x2p/vpr/SRC/base/read_blif.c +++ b/vpr7_x2p/vpr/SRC/base/read_blif.c @@ -524,7 +524,7 @@ static void add_latch(int doall, INP t_model *latch_model) { /* Store the initial value */ logical_block[num_logical_blocks - 1].init_val = my_atoi(saved_names[4]); /* Add clock identification */ - logical_block[logical_block[num_logical_blocks - 1].clock_net].is_clock = TRUE; + logical_block[vpack_net[logical_block[num_logical_blocks - 1].clock_net].node_block[0]].is_clock = TRUE; /*END*/ num_latches++; @@ -722,6 +722,9 @@ static void add_subckt(int doall, t_model *user_models) { add_vpack_net(circuit_signal_name[i], RECEIVER, num_logical_blocks - 1, port->index, my_atoi(pin_number), TRUE, doall); + + /* Add clock identification */ + logical_block[vpack_net[logical_block[num_logical_blocks - 1].clock_net].node_block[0]].is_clock = TRUE; } else { logical_block[num_logical_blocks - 1].input_nets[port->index][my_atoi( pin_number)] = add_vpack_net( 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 7e9042806..ca1f0a96a 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 @@ -1005,8 +1005,7 @@ int rec_count_num_conf_bits_pb_type_physical_mode(t_pb_type* cur_pb_type, cur_pb_type->physical_mode_num_conf_bits = 0; /* Recursively finish all the child pb_types*/ - if ((NULL == cur_pb_type->spice_model_name) - && (NULL == cur_pb_type->physical_pb_type_name)) { + if ( FALSE == is_primitive_pb_type(cur_pb_type)) { /* Find the mode that define_idle_mode*/ mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); for (ipb = 0; ipb < cur_pb_type->modes[mode_index].num_pb_type_children; ipb++) { @@ -1017,8 +1016,7 @@ int rec_count_num_conf_bits_pb_type_physical_mode(t_pb_type* cur_pb_type, } /* Check if this has defined a spice_model*/ - if ((NULL != cur_pb_type->spice_model_name) - || (NULL != cur_pb_type->physical_pb_type_name)) { + if ( TRUE == is_primitive_pb_type(cur_pb_type)) { sum_num_conf_bits = count_num_conf_bits_one_spice_model(cur_pb_type->phy_pb_type->spice_model, cur_sram_orgz_info->type, 0); cur_pb_type->physical_mode_num_conf_bits = sum_num_conf_bits; /* calculate the number of reserved configuration bits */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_pbtypes.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_pbtypes.c index 5db74a44f..f87ff45a7 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_pbtypes.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_pbtypes.c @@ -1751,6 +1751,7 @@ void dump_verilog_phy_pb_graph_node_rec(t_sram_orgz_info* cur_sram_orgz_info, /* update stamped sram counter */ stamped_sram_cnt += cur_pb_type->physical_mode_num_conf_bits; /* Check */ + if (stamped_sram_cnt != get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info)) assert(stamped_sram_cnt == get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info)); assert(stamped_iopad_cnt == iopad_verilog_model->cnt); /* Finish for primitive node, return */ From d2d8af541658ba2a9af954ebf1f7b8d8c56b2ac3 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 13 Aug 2019 17:34:09 -0600 Subject: [PATCH 7/7] bug fixing for pb_type num_conf_bits and num_iopads stats --- .../fpga_x2p/base/fpga_x2p_pbtypes_utils.c | 46 +++++++++++++++++++ .../fpga_x2p/base/fpga_x2p_pbtypes_utils.h | 4 ++ .../vpr/SRC/fpga_x2p/verilog/verilog_api.c | 6 ++- 3 files changed, 54 insertions(+), 2 deletions(-) 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 ca1f0a96a..9da08d95b 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 @@ -1023,6 +1023,7 @@ int rec_count_num_conf_bits_pb_type_physical_mode(t_pb_type* cur_pb_type, cur_pb_type->physical_mode_num_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(cur_pb_type->phy_pb_type->spice_model, cur_sram_orgz_info->type, 0); + } else { /* Count the sum of configuration bits of all the children pb_types */ /* Find the mode that define_idle_mode*/ mode_index = find_pb_type_physical_mode_index((*cur_pb_type)); @@ -1232,6 +1233,28 @@ void init_grids_num_conf_bits(t_sram_orgz_info* cur_sram_orgz_info) { return; } +/******************************************************************** + * Initialize the number of configuration bits for each pb_type + * in the list of type descriptors + *******************************************************************/ +void init_pb_types_num_conf_bits(t_sram_orgz_info* cur_sram_orgz_info) { + for (int itype = 0; itype < num_types; ++itype) { + /* bypass EMPTY_TYPES */ + if (EMPTY_TYPE == &(type_descriptors[itype])) { + continue; + } + int capacity= type_descriptors[itype].capacity; + assert(0 < capacity); + + /* check capacity and if this has been mapped */ + for (int iz = 0; iz < capacity; iz++) { + /* Check in all the blocks(clustered logic block), there is a match x,y,z*/ + rec_count_num_conf_bits_pb_type_physical_mode(type_descriptors[itype].pb_type, cur_sram_orgz_info); + } + } + return; +} + /* With given spice_model_port, find the pb_type port with same name and type*/ t_port* find_pb_type_port_match_spice_model_port(t_pb_type* pb_type, t_spice_model_port* spice_model_port) { @@ -1793,6 +1816,29 @@ void init_grids_num_iopads() { return; } +/******************************************************************** + * Initialize the number of configuration bits for each pb_type + * in the list of type descriptors + *******************************************************************/ +void init_pb_types_num_iopads() { + for (int itype = 0; itype < num_types; ++itype) { + /* bypass EMPTY_TYPES */ + if (EMPTY_TYPE == &(type_descriptors[itype])) { + continue; + } + + int capacity= type_descriptors[itype].capacity; + assert(0 < capacity); + + /* check capacity and if this has been mapped */ + for (int iz = 0; iz < capacity; iz++) { + /* Check in all the blocks(clustered logic block), there is a match x,y,z*/ + rec_count_num_iopads_pb_type_physical_mode(type_descriptors[itype].pb_type); + } + } + return; +} + /* Count the number of mode configuration bits of a grid (type_descriptor) in default mode */ void rec_count_num_mode_bits_pb_type_default_mode(t_pb_type* cur_pb_type) { int mode_index, ipb, jpb; 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 075f9852c..8a85329c0 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 @@ -93,6 +93,8 @@ void init_one_grid_num_conf_bits(int ix, int iy, void init_grids_num_conf_bits(t_sram_orgz_info* cur_sram_orgz_info); +void init_pb_types_num_conf_bits(t_sram_orgz_info* cur_sram_orgz_info); + void map_clb_pins_to_pb_graph_pins(); t_port* find_pb_type_port_match_spice_model_port(t_pb_type* pb_type, @@ -135,6 +137,8 @@ void init_one_grid_num_iopads(int ix, int iy); void init_grids_num_iopads(); +void init_pb_types_num_iopads(); + void rec_count_num_mode_bits_pb_type_default_mode(t_pb_type* cur_pb_type); void rec_count_num_mode_bits_pb(t_pb* cur_pb); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c index 41b2c634c..5c4d1f132 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_api.c @@ -242,8 +242,10 @@ void vpr_fpga_verilog(t_vpr_setup vpr_setup, /* Initialize the number of configuration bits of all the grids */ vpr_printf(TIO_MESSAGE_INFO, "Count the number of configuration bits, IO pads in each logic block...\n"); /* init_grids_num_conf_bits(sram_verilog_orgz_type); */ - init_grids_num_conf_bits(sram_verilog_orgz_info); - init_grids_num_iopads(); + //init_grids_num_conf_bits(sram_verilog_orgz_info); + init_pb_types_num_conf_bits(sram_verilog_orgz_info); + //init_grids_num_iopads(); + init_pb_types_num_iopads(); /* init_grids_num_mode_bits(); */ dump_verilog_defines_preproc(src_dir_path,