diff --git a/docs/source/manual/arch_lang/circuit_library.rst b/docs/source/manual/arch_lang/circuit_library.rst index 9fe29a0fa..59e5f055f 100644 --- a/docs/source/manual/arch_lang/circuit_library.rst +++ b/docs/source/manual/arch_lang/circuit_library.rst @@ -78,9 +78,9 @@ Here, we focus these common syntax and we will detail special syntax in :ref:`ci .. warning:: ``prefix`` may be deprecated soon -.. note:: Multiplexers cannot be user-defined. +.. warning:: Multiplexers cannot be user-defined. -.. note:: For a circuit model type, only one circuit model can be set as default. +.. warning:: For a circuit model type, only one circuit model is allowed to be set as default. If there is only one circuit model defined in a type, it will be considered as the default automatically. .. note:: If ```` or ```` are not specified, FPGA-Verilog/SPICE auto-generates the Verilog/SPICE netlists for multiplexers, wires, and LUTs. diff --git a/libopenfpga/libarchopenfpga/src/check_circuit_library.cpp b/libopenfpga/libarchopenfpga/src/check_circuit_library.cpp index ea6db0678..e438ba5f8 100644 --- a/libopenfpga/libarchopenfpga/src/check_circuit_library.cpp +++ b/libopenfpga/libarchopenfpga/src/check_circuit_library.cpp @@ -197,6 +197,43 @@ size_t check_circuit_model_port_required(const CircuitLibrary& circuit_lib, return num_err; } +/************************************************************************ + * A generic function to search each default circuit model by types + * that have been defined by users. + * If a type of circuit model is defined, we expect there is a default model + * to be specified + ***********************************************************************/ +static +size_t check_default_circuit_model_by_types(const CircuitLibrary& circuit_lib) { + size_t num_err = 0; + + for (size_t itype = 0; itype < NUM_CIRCUIT_MODEL_TYPES; ++itype) { + std::vector curr_models = circuit_lib.models_by_type(e_circuit_model_type(itype)); + if (0 == curr_models.size()) { + continue; + } + /* Go through the models and try to find a default one */ + size_t found_default_counter = 0; + for (const auto& curr_model : curr_models) { + if (true == circuit_lib.model_is_default(curr_model)) { + found_default_counter++; + } + } + if (0 == found_default_counter) { + VTR_LOG_ERROR("Miss a default circuit model for the type %s! Try to define it in your architecture file!\n", + CIRCUIT_MODEL_TYPE_STRING[itype]); + num_err++; + } + if (1 < found_default_counter) { + VTR_LOG_ERROR("Found >1 default circuit models for the type %s! Expect only one!\n", + CIRCUIT_MODEL_TYPE_STRING[itype]); + num_err++; + } + } + + return num_err; +} + /************************************************************************ * A generic function to find the default circuit model with a given type * If not found, we give an error @@ -207,9 +244,9 @@ size_t check_required_default_circuit_model(const CircuitLibrary& circuit_lib, size_t num_err = 0; if (CircuitModelId::INVALID() == circuit_lib.default_model(circuit_model_type)) { - VTR_LOG_ERROR("A default circuit model for the type %s! Try to define it in your architecture file!\n", + VTR_LOG_ERROR("Miss 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); + num_err++; } return num_err; @@ -626,7 +663,10 @@ bool check_circuit_library(const CircuitLibrary& circuit_lib) { num_err += check_circuit_model_port_required(circuit_lib, CIRCUIT_MODEL_LUT, lut_port_types_required); - /* 10. We must have default circuit models for these types: MUX, channel wires and wires */ + /* 10. For each type of circuit models that are define, we must have 1 default model + * We must have default circuit models for these types: MUX, channel wires and wires + */ + num_err += check_default_circuit_model_by_types(circuit_lib); num_err += check_required_default_circuit_model(circuit_lib, CIRCUIT_MODEL_MUX); num_err += check_required_default_circuit_model(circuit_lib, CIRCUIT_MODEL_CHAN_WIRE); num_err += check_required_default_circuit_model(circuit_lib, CIRCUIT_MODEL_WIRE); diff --git a/libopenfpga/libarchopenfpga/src/circuit_library.cpp b/libopenfpga/libarchopenfpga/src/circuit_library.cpp index cccc62e71..881035ee7 100644 --- a/libopenfpga/libarchopenfpga/src/circuit_library.cpp +++ b/libopenfpga/libarchopenfpga/src/circuit_library.cpp @@ -2,6 +2,7 @@ #include #include "vtr_assert.h" +#include "vtr_log.h" #include "openfpga_port_parser.h" #include "circuit_library.h" @@ -2108,6 +2109,23 @@ void CircuitLibrary::build_timing_graphs() { return; } +/* Automatically identify the default models for each type*/ +void CircuitLibrary::auto_detect_default_models() { + /* Go through the model fast look-up */ + for (const auto& curr_type_models : model_lookup_) { + if ( (1 == curr_type_models.size()) + && (false == model_is_default(curr_type_models[0]))) { + /* This is the only model in this type, + * it is safe to set it to be default + * Give a warning for users + */ + set_model_is_default(curr_type_models[0], true); + VTR_LOG_WARN("Automatically set circuit model '%s' to be default in its type.\n", + model_name(curr_type_models[0]).c_str()); + } + } +} + /************************************************************************ * Internal mutators: build timing graphs ***********************************************************************/ diff --git a/libopenfpga/libarchopenfpga/src/circuit_library.h b/libopenfpga/libarchopenfpga/src/circuit_library.h index abb03d1f8..5e023c665 100644 --- a/libopenfpga/libarchopenfpga/src/circuit_library.h +++ b/libopenfpga/libarchopenfpga/src/circuit_library.h @@ -461,6 +461,10 @@ class CircuitLibrary { public: /* Public Mutators: builders */ void build_model_links(); void build_timing_graphs(); + /* Automatically identify the default models for each type, + * suggest to do this after circuit library is built + */ + void auto_detect_default_models(); public: /* Internal mutators: build timing graphs */ void add_edge(const CircuitModelId& model_id, const CircuitPortId& from_port, const size_t& from_pin, diff --git a/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp b/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp index 6bc31ef46..e8ce6aeab 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp @@ -52,6 +52,9 @@ openfpga::Arch read_xml_openfpga_arch(const char* arch_file_name) { auto xml_circuit_models = get_single_child(xml_openfpga_arch, "circuit_library", loc_data); openfpga_arch.circuit_lib = read_xml_circuit_library(xml_circuit_models, loc_data); + /* Automatically identify the default models for circuit library */ + openfpga_arch.circuit_lib.auto_detect_default_models(); + /* Build the internal links for the circuit library */ openfpga_arch.circuit_lib.build_model_links(); diff --git a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml index bbc33f2e8..6d5df7467 100644 --- a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml @@ -184,7 +184,7 @@ - + diff --git a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_frac_mem32K_frac_dsp36_40nm_openfpga.xml b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_frac_mem32K_frac_dsp36_40nm_openfpga.xml index ef872ccbf..6ddb0d681 100644 --- a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_frac_mem32K_frac_dsp36_40nm_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_frac_mem32K_frac_dsp36_40nm_openfpga.xml @@ -184,7 +184,7 @@ - + diff --git a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_mem16K_40nm_openfpga.xml b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_mem16K_40nm_openfpga.xml index c4d47ad2c..b8c99a382 100644 --- a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_mem16K_40nm_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_mem16K_40nm_openfpga.xml @@ -184,7 +184,7 @@ - + diff --git a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_mem16K_aib_40nm_openfpga.xml b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_mem16K_aib_40nm_openfpga.xml index 5925aeb2d..c0c1aa581 100644 --- a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_mem16K_aib_40nm_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_mem16K_aib_40nm_openfpga.xml @@ -175,7 +175,7 @@ - + @@ -184,7 +184,7 @@ - + diff --git a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_column_chain_40nm_openfpga.xml b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_column_chain_40nm_openfpga.xml index f2265e48c..26af034f5 100644 --- a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_column_chain_40nm_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_column_chain_40nm_openfpga.xml @@ -184,7 +184,7 @@ - + diff --git a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_chain_40nm_openfpga.xml b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_chain_40nm_openfpga.xml index 3597e7c50..e10c12d27 100644 --- a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_chain_40nm_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_chain_40nm_openfpga.xml @@ -184,7 +184,7 @@ - + diff --git a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_40nm_openfpga.xml b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_40nm_openfpga.xml index b17169f78..8537cfc18 100644 --- a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_40nm_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_40nm_openfpga.xml @@ -189,7 +189,7 @@ - + diff --git a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_depop50_40nm_openfpga.xml b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_depop50_40nm_openfpga.xml index f26140913..b815842e7 100644 --- a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_depop50_40nm_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_depop50_40nm_openfpga.xml @@ -189,7 +189,7 @@ - + diff --git a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_depop50_spypad_40nm_openfpga.xml b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_depop50_spypad_40nm_openfpga.xml index 7f31c435f..c74625e33 100644 --- a/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_depop50_spypad_40nm_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_depop50_spypad_40nm_openfpga.xml @@ -154,7 +154,7 @@ - + @@ -204,7 +204,7 @@ - +