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 e192cb6af..2a6e32756 100644 --- a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.cpp +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.cpp @@ -33,6 +33,8 @@ * +-------------------------------------+ ***********************************************************************/ +#include + #include "vtr_assert.h" #include "circuit_library.h" @@ -46,7 +48,7 @@ ***********************************************************************/ /************************************************************************ - * Accessors : aggregates + * Public Accessors : aggregates ***********************************************************************/ CircuitLibrary::circuit_model_range CircuitLibrary::circuit_models() const { return vtr::make_range(circuit_model_ids_.begin(), circuit_model_ids_.end()); @@ -54,7 +56,7 @@ CircuitLibrary::circuit_model_range CircuitLibrary::circuit_models() const { /************************************************************************ - * Accessors : Methods to find circuit model + * Public Accessors : Methods to find circuit model ***********************************************************************/ /* Find a circuit model by a given name and return its id */ CircuitModelId CircuitLibrary::get_circuit_model_id_by_name(const std::string& name) const { @@ -84,7 +86,7 @@ CircuitModelId CircuitLibrary::get_default_circuit_model_id(const enum e_spice_m } /************************************************************************ - * Mutators + * Public Mutators ***********************************************************************/ /* Add a circuit model to the library, and return it Id */ CircuitModelId CircuitLibrary::add_circuit_model() { @@ -107,7 +109,7 @@ CircuitModelId CircuitLibrary::add_circuit_model() { dump_explicit_port_map_.push_back(false); /* Design technology information */ - design_tech_.push_back(NUM_CIRCUIT_MODEL_DESIGN_TECH_TYPES); + design_tech_types_.push_back(NUM_CIRCUIT_MODEL_DESIGN_TECH_TYPES); power_gated_.push_back(false); /* Buffer existence */ @@ -190,23 +192,240 @@ CircuitModelId CircuitLibrary::add_circuit_model() { wire_rc_.emplace_back(); wire_num_levels_.push_back(-1); - /* Invalidate fast look-up*/ + /* Update circuit port fast look-up */ + circuit_model_port_lookup_.emplace_back(); + /* Invalidate fast look-up*/ + invalidate_circuit_model_lookup(); return circuit_model_id; } +/* Set the type of a 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)); + circuit_model_types_[circuit_model_id] = type; + return; +} + +/* 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)); + circuit_model_names_[circuit_model_id] = name; + return; +} + +/* 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)); + circuit_model_prefix_[circuit_model_id] = prefix; + return; +} + +/* 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)); + circuit_model_verilog_netlists_[circuit_model_id] = verilog_netlist; + return; +} + +/* 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)); + circuit_model_spice_netlists_[circuit_model_id] = spice_netlist; + return; +} + +/* 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)); + circuit_model_is_default_[circuit_model_id] = is_default; + return; +} + +/* 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)); + dump_structural_verilog_[circuit_model_id] = dump_structural_verilog; + return; +} + +/* 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)); + dump_explicit_port_map_[circuit_model_id] = dump_explicit_port_map; + return; +} + +/* 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)); + design_tech_types_[circuit_model_id] = design_tech_type; + return; +} + +/* Set the power-gated flag of a Circuit Model */ +void CircuitLibrary::set_circuit_model_power_gated(const CircuitModelId& circuit_model_id, const bool& power_gated) { + /* validate the circuit_model_id */ + VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + power_gated_[circuit_model_id] = power_gated; + return; +} + +/* Set input buffer information for the circuit model */ +void CircuitLibrary::set_circuit_model_input_buffer(const CircuitModelId& circuit_model_id, + const bool& existence, const std::string& circuit_model_name) { + /* Just call the base function and give the proper type */ + set_circuit_model_buffer(circuit_model_id, INPUT, existence, circuit_model_name); + return; +} + +/* Set output buffer information for the circuit model */ +void CircuitLibrary::set_circuit_model_output_buffer(const CircuitModelId& circuit_model_id, + const bool& existence, const std::string& circuit_model_name) { + /* Just call the base function and give the proper type */ + set_circuit_model_buffer(circuit_model_id, OUTPUT, existence, circuit_model_name); + return; +} + +/* Set input buffer information for the circuit model, only applicable to LUTs! */ +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)); + /* Make sure the circuit model is a LUT! */ + VTR_ASSERT_SAFE(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; +} + +/* Set input inverter information for the circuit model, only applicable to LUTs! */ +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)); + /* Make sure the circuit model is a LUT! */ + VTR_ASSERT_SAFE(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; +} + +/* Set intermediate buffer information for the circuit model, only applicable to LUTs! */ +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)); + /* Make sure the circuit model is a LUT! */ + VTR_ASSERT_SAFE(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; +} + /************************************************************************ * Internal Mutators ***********************************************************************/ +/* Set the information for a buffer + * For a buffer type, we check if it is in the range of vector + * If yes, just assign values + * If no, resize the vector and then assign values + */ +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)); + /* Check the range of vector */ + if (size_t(buffer_type) >= buffer_existence_[circuit_model_id].size()) { + /* Resize and assign values */ + buffer_existence_[circuit_model_id].resize(size_t(buffer_type) + 1); + buffer_circuit_model_names_[circuit_model_id].resize(size_t(buffer_type) + 1); + buffer_circuit_model_ids_[circuit_model_id].resize(size_t(buffer_type) + 1); + } + /* Now we are in the range, assign values */ + buffer_existence_[circuit_model_id][size_t(buffer_type)] = existence; + buffer_circuit_model_names_[circuit_model_id][size_t(buffer_type)] = circuit_model_name; + buffer_circuit_model_ids_[circuit_model_id][size_t(buffer_type)] = CIRCUIT_MODEL_OPEN_ID; /* Set an OPEN id here, which will be linked later */ + return; +} + /* Link the inv_circuit_model_id for each port of a circuit model. * We search the inv_circuit_model_name in the CircuitLibrary and * configure the port inv_circuit_model_id */ void CircuitLibrary::set_circuit_model_port_inv_circuit_model(const CircuitModelId& circuit_model_id) { + /* validate the circuit_model_id */ + VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id)); + /* TODO: complete this function when port mutators are finished */ return; } + +/************************************************************************ + * Internal mutators: build fast look-ups + ***********************************************************************/ +void CircuitLibrary::build_circuit_model_lookup() { + /* invalidate fast look-up */ + invalidate_circuit_model_lookup(); + /* Classify circuit models by type */ + circuit_model_lookup_.resize(NUM_CIRCUIT_MODEL_TYPES); + /* Walk through circuit_models and categorize */ + for (auto& id : circuit_model_ids_) { + circuit_model_lookup_[circuit_model_types_[id]].push_back(id); + } + /* Make the default circuit_model to be the first element for each type */ + for (auto& type : circuit_model_lookup_) { + /* if the first element is already a default model, we skip this */ + if (true == circuit_model_is_default_[type[0]]) { + continue; + } + /* Check the array, and try to find a default model */ + for (size_t id = 0; id < type.size(); ++id) { + if (false == circuit_model_is_default_[type[id]]) { + continue; + } + /* Once we find a default model, swap with the first element and finish the loop */ + std::swap(type[0], type[id]); + break; + } + } + return; +} + +/************************************************************************ + * Internal invalidators/validators + ***********************************************************************/ +/* Validators */ +bool CircuitLibrary::valid_circuit_model_id(const CircuitModelId& circuit_model_id) const { + return ( size_t(circuit_model_id) < circuit_model_ids_.size() ) && ( circuit_model_id == circuit_model_ids_[circuit_model_id] ); +} + +/* Invalidators */ +/* Empty fast lookup for circuit_models*/ +void CircuitLibrary::invalidate_circuit_model_lookup() const { + circuit_model_lookup_.clear(); + return; +} + +/* 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)); + circuit_model_port_lookup_[size_t(circuit_model_id)].clear(); + return; +} + /************************************************************************ * End of file : circuit_library.cpp ***********************************************************************/ 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 bedfabb7f..b6a5464b4 100644 --- a/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.h +++ b/vpr7_x2p/libarchfpga/SRC/fpga_spice_include/circuit_library.h @@ -47,6 +47,8 @@ */ /* Header files should be included in a sequence */ /* Standard header files required go first */ +#include + #include "vtr_strong_id.h" #include "vtr_geometry.h" @@ -100,7 +102,7 @@ typedef vtr::StrongId CircuitEdgeId; * 2. dump_explicit_port_map_: if Verilog generator will use explicit port mapping when instanciate the circuit model * * ------ Design technology information ----- - * 1. design_tech_: the design technology [cmos|rram] for each circuit model + * 1. design_tech_types_: the design technology [cmos|rram] for each circuit model * 2. power_gated_: specify if the circuit model is power-gated (contain a input to turn on/off VDD and GND) * * ------ Buffer existence ----- @@ -210,20 +212,43 @@ class CircuitLibrary { typedef vtr::Range circuit_edge_range; /* local enumeration for buffer existence */ enum e_buffer_type: unsigned char{ - INPUT = 0, OUTPUT, LUT_INPUT_BUFFER, LUT_INPUT_INV, LUT_INTER_BUFFER, NUM_BUFFER_TYPE /* Last one is a counter */ + INPUT = 0, OUTPUT, LUT_INPUT_BUFFER, LUT_INPUT_INVERTER, LUT_INTER_BUFFER, NUM_BUFFER_TYPE /* Last one is a counter */ }; public: /* Constructors */ public: /* Accessors: aggregates */ circuit_model_range circuit_models() const; - public: /* Accessors: Basic data query */ - public: /* Accessors: Methods to find circuit model */ + public: /* Public Accessors: Basic data query */ + public: /* Public Accessors: Methods to find circuit model */ CircuitModelId get_circuit_model_id_by_name(const std::string& name) const ; CircuitModelId get_default_circuit_model_id(const enum e_spice_model_type& type) const; - public: /* Mutators */ + public: /* Public Mutators */ CircuitModelId add_circuit_model(); - public: /* Internal mutators */ + void set_circuit_model_type(const CircuitModelId& circuit_model_id, const enum e_spice_model_type& type); + void set_circuit_model_name(const CircuitModelId& circuit_model_id, const std::string& name); + void set_circuit_model_prefix(const CircuitModelId& circuit_model_id, const std::string& prefix); + void set_circuit_model_verilog_netlist(const CircuitModelId& circuit_model_id, const std::string& verilog_netlist); + void set_circuit_model_spice_netlist(const CircuitModelId& circuit_model_id, const std::string& spice_netlist); + void set_circuit_model_is_default(const CircuitModelId& circuit_model_id, const bool& is_default); + void set_circuit_model_dump_structural_verilog(const CircuitModelId& circuit_model_id, const bool& dump_structural_verilog); + void set_circuit_model_dump_explicit_port_map(const CircuitModelId& circuit_model_id, const bool& dump_explicit_port_map); + void set_circuit_model_design_tech_type(const CircuitModelId& circuit_model_id, const enum e_spice_model_design_tech& design_tech_type); + void set_circuit_model_power_gated(const CircuitModelId& circuit_model_id, const bool& power_gated); + void set_circuit_model_input_buffer(const CircuitModelId& circuit_model_id, const bool& existence, const std::string& circuit_model_name); + void set_circuit_model_output_buffer(const CircuitModelId& circuit_model_id, const bool& existence, const std::string& circuit_model_name); + void set_circuit_model_lut_input_buffer(const CircuitModelId& circuit_model_id, const bool& existence, const std::string& circuit_model_name); + void set_circuit_model_lut_input_inverter(const CircuitModelId& circuit_model_id, const bool& existence, const std::string& circuit_model_name); + void set_circuit_model_lut_intermediate_buffer(const CircuitModelId& circuit_model_id, const bool& existence, const std::string& circuit_model_name); + public: /* Internal mutators: link circuit_models */ + void 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); void set_circuit_model_port_inv_circuit_model(const CircuitModelId& circuit_model_id); - private: /* Internal validators */ + public: /* Internal mutators: build fast look-ups */ + void build_circuit_model_lookup(); + private: /* Internal invalidators/validators */ + /* Validators */ + bool valid_circuit_model_id(const CircuitModelId& circuit_model_id) const; + /* Invalidators */ + void invalidate_circuit_model_lookup() const; + void invalidate_circuit_model_port_lookup(const CircuitModelId& circuit_model_id) const; private: /* Internal data */ /* Fundamental information */ vtr::vector circuit_model_ids_; @@ -240,15 +265,15 @@ class CircuitLibrary { */ typedef std::vector> CircuitModelLookup; mutable CircuitModelLookup circuit_model_lookup_; /* [circuit_model_type][circuit_model_ids] */ - typedef std::vector>>> CircuitModelPortLookup; - mutable CircuitModelPortLookup circuit_model_port_lookup_; /* [circuit_model_type][circuit_model_id][port_type][port_ids] */ + typedef std::vector>> CircuitModelPortLookup; + mutable CircuitModelPortLookup circuit_model_port_lookup_; /* [circuit_model_id][port_type][port_ids] */ /* Verilog generator options */ vtr::vector dump_structural_verilog_; vtr::vector dump_explicit_port_map_; /* Design technology information */ - vtr::vector design_tech_; + vtr::vector design_tech_types_; vtr::vector power_gated_; /* Buffer existence */