Merge remote-tracking branch 'origin/dev' into heterogeneous
This commit is contained in:
commit
8dab4dec90
|
@ -49,6 +49,7 @@ template<class T>
|
|||
class Point {
|
||||
public: //Constructors
|
||||
Point(T x_val, T y_val);
|
||||
Point();
|
||||
|
||||
public: //Accessors
|
||||
|
||||
|
@ -59,6 +60,10 @@ class Point {
|
|||
friend bool operator== <>(Point<T> lhs, Point<T> rhs);
|
||||
friend bool operator!= <>(Point<T> lhs, Point<T> rhs);
|
||||
friend bool operator< <>(Point<T> lhs, Point<T> rhs);
|
||||
public: //Mutators
|
||||
void set_x(T x_val);
|
||||
void set_y(T y_val);
|
||||
void swap();
|
||||
private:
|
||||
T x_;
|
||||
T y_;
|
||||
|
|
|
@ -10,6 +10,12 @@ namespace vtr {
|
|||
//pass
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Point<T>::Point() {
|
||||
//pass
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
T Point<T>::x() const {
|
||||
return x_;
|
||||
|
@ -36,6 +42,22 @@ namespace vtr {
|
|||
return std::make_tuple(lhs.x(), lhs.y()) < std::make_tuple(rhs.x(), rhs.y());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Point<T>::set_x(T x_val) {
|
||||
x_ = x_val;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Point<T>::set_y(T y_val) {
|
||||
y_ = y_val;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Point<T>::swap() {
|
||||
std::swap(x_, y_);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Rect
|
||||
*/
|
||||
|
|
|
@ -35,11 +35,12 @@ set_target_properties(libarchfpga PROPERTIES PREFIX "") #Avoid extra 'lib' prefi
|
|||
|
||||
# Specify dependency
|
||||
target_link_libraries(libarchfpga
|
||||
libvtrutil
|
||||
libpcre
|
||||
libprinthandler)
|
||||
|
||||
add_executable(read_arch ${EXEC_SOURCES})
|
||||
target_link_libraries(read_arch libarchfpga)
|
||||
target_link_libraries(read_arch libarchfpga libvtrutil)
|
||||
|
||||
|
||||
# install: TO BE TESTED
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
/**********************************************************
|
||||
* 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: check_circuit_library.cpp
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2019/08/12 | Xifan Tang | Created
|
||||
* +-------------------------------------+
|
||||
***********************************************************************/
|
||||
|
||||
/* Header files should be included in a sequence */
|
||||
/* Standard header files required go first */
|
||||
#include "util.h"
|
||||
#include "check_circuit_library.h"
|
||||
|
||||
|
||||
/* 1. Circuit models have unique names, return the number of errors */
|
||||
static
|
||||
size_t check_circuit_library_unique_names(const CircuitLibrary& circuit_lib) {
|
||||
size_t num_err = 0;
|
||||
|
||||
for (size_t i = 0; i < circuit_lib.num_circuit_models(); ++i) {
|
||||
/* Skip for the last element, because the inner loop will access it */
|
||||
if (i == circuit_lib.num_circuit_models() - 1) {
|
||||
continue;
|
||||
}
|
||||
/* Get the name of reference */
|
||||
const std::string& i_name = circuit_lib.circuit_model_name(CircuitModelId(i));
|
||||
for (size_t j = i + 1; j < circuit_lib.num_circuit_models(); ++j) {
|
||||
/* Compare the name of candidate */
|
||||
const std::string& j_name = circuit_lib.circuit_model_name(CircuitModelId(j));
|
||||
/* Compare the name and skip for different names */
|
||||
if (0 != i_name.compare(j_name)) {
|
||||
continue;
|
||||
}
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"Circuit model(index=%d) and (index=%d) share the same name, which is invalid!\n",
|
||||
i , j, i_name.c_str());
|
||||
/* Incremental the counter for errors */
|
||||
num_err++;
|
||||
}
|
||||
}
|
||||
|
||||
return num_err;
|
||||
}
|
||||
|
||||
|
||||
/* 1. Circuit models have unique names, return the number of errors */
|
||||
static
|
||||
size_t check_circuit_library_unique_prefix(const CircuitLibrary& circuit_lib) {
|
||||
size_t num_err = 0;
|
||||
|
||||
for (size_t i = 0; i < circuit_lib.num_circuit_models(); ++i) {
|
||||
/* Skip for the last element, because the inner loop will access it */
|
||||
if (i == circuit_lib.num_circuit_models() - 1) {
|
||||
continue;
|
||||
}
|
||||
/* Get the name of reference */
|
||||
const std::string& i_prefix = circuit_lib.circuit_model_prefix(CircuitModelId(i));
|
||||
for (size_t j = i + 1; j < circuit_lib.num_circuit_models(); ++j) {
|
||||
/* Compare the name of candidate */
|
||||
const std::string& j_prefix = circuit_lib.circuit_model_prefix(CircuitModelId(j));
|
||||
/* Compare the name and skip for different prefix */
|
||||
if (0 != i_prefix.compare(j_prefix)) {
|
||||
continue;
|
||||
}
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"Circuit model(name=%s) and (name=%s) share the same prefix, which is invalid!\n",
|
||||
circuit_lib.circuit_model_name(CircuitModelId(i)).c_str(),
|
||||
circuit_lib.circuit_model_name(CircuitModelId(j)).c_str(),
|
||||
i_prefix.c_str());
|
||||
/* Incremental the counter for errors */
|
||||
num_err++;
|
||||
}
|
||||
}
|
||||
|
||||
return num_err;
|
||||
}
|
||||
|
||||
/* A generic function to check the port list of a circuit model in a given type */
|
||||
static
|
||||
size_t check_circuit_model_required(const CircuitLibrary& circuit_lib,
|
||||
const enum e_spice_model_type& circuit_model_type_to_check) {
|
||||
size_t num_err = 0;
|
||||
|
||||
/* We must have an IOPAD*/
|
||||
if ( 0 == circuit_lib.circuit_models_by_type(circuit_model_type_to_check).size()) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"At least one %s circuit model is required!\n",
|
||||
CIRCUIT_MODEL_TYPE_STRING[size_t(circuit_model_type_to_check)]);
|
||||
/* Incremental the counter for errors */
|
||||
num_err++;
|
||||
}
|
||||
|
||||
return num_err;
|
||||
}
|
||||
|
||||
/* A generic function to check the port list of a circuit model in a given type */
|
||||
static
|
||||
size_t check_circuit_model_port_required(const CircuitLibrary& circuit_lib,
|
||||
const enum e_spice_model_type& circuit_model_type_to_check,
|
||||
const std::vector<enum e_spice_model_port_type>& port_types_to_check) {
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num_err;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Check points to make sure we have a valid circuit library
|
||||
* Detailed checkpoints:
|
||||
* 1. Circuit models have unique names
|
||||
* 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
|
||||
***********************************************************************/
|
||||
void check_circuit_library(const CircuitLibrary& circuit_lib) {
|
||||
size_t num_err = 0;
|
||||
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Checking circuit models...\n");
|
||||
|
||||
/* 1. Circuit models have unique names
|
||||
* For each circuit model, we always make sure it does not share any name with any circuit model locating after it
|
||||
*/
|
||||
num_err += check_circuit_library_unique_names(circuit_lib);
|
||||
|
||||
/* 2. Circuit models have unique prefix
|
||||
* For each circuit model, we always make sure it does not share any prefix with any circuit model locating after it
|
||||
*/
|
||||
num_err += check_circuit_library_unique_prefix(circuit_lib);
|
||||
|
||||
/* 3. Check io has been defined and has input and output ports
|
||||
* [a] We must have an IOPAD!
|
||||
* [b] For each IOPAD, we must have at least an input, an output, an INOUT and an SRAM port
|
||||
*/
|
||||
num_err += check_circuit_model_required(circuit_lib, SPICE_MODEL_IOPAD);
|
||||
|
||||
std::vector<enum e_spice_model_port_type> iopad_port_types_required;
|
||||
iopad_port_types_required.push_back(SPICE_MODEL_PORT_INPUT);
|
||||
iopad_port_types_required.push_back(SPICE_MODEL_PORT_OUTPUT);
|
||||
iopad_port_types_required.push_back(SPICE_MODEL_PORT_INOUT);
|
||||
iopad_port_types_required.push_back(SPICE_MODEL_PORT_SRAM);
|
||||
|
||||
num_err += check_circuit_model_port_required(circuit_lib, SPICE_MODEL_IOPAD, iopad_port_types_required);
|
||||
|
||||
/* 4. Check mux has been defined and has input and output ports
|
||||
* [a] We must have a MUX!
|
||||
* [b] For each MUX, we must have at least an input, an output, and an SRAM port
|
||||
*/
|
||||
num_err += check_circuit_model_required(circuit_lib, SPICE_MODEL_MUX);
|
||||
|
||||
std::vector<enum e_spice_model_port_type> mux_port_types_required;
|
||||
mux_port_types_required.push_back(SPICE_MODEL_PORT_INPUT);
|
||||
mux_port_types_required.push_back(SPICE_MODEL_PORT_OUTPUT);
|
||||
mux_port_types_required.push_back(SPICE_MODEL_PORT_SRAM);
|
||||
|
||||
num_err += check_circuit_model_port_required(circuit_lib, SPICE_MODEL_MUX, mux_port_types_required);
|
||||
|
||||
/* 5. We must have at least one SRAM or SCFF */
|
||||
if ( ( 0 == circuit_lib.circuit_models_by_type(SPICE_MODEL_SRAM).size())
|
||||
&& ( 0 == circuit_lib.circuit_models_by_type(SPICE_MODEL_SCFF).size()) ) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"At least one %s or %s circuit model is required!\n",
|
||||
CIRCUIT_MODEL_TYPE_STRING[size_t(SPICE_MODEL_SRAM)],
|
||||
CIRCUIT_MODEL_TYPE_STRING[size_t(SPICE_MODEL_SCFF)]);
|
||||
/* Incremental the counter for errors */
|
||||
num_err++;
|
||||
}
|
||||
|
||||
/* 6. SRAM must have at least an input and an output ports*/
|
||||
std::vector<enum e_spice_model_port_type> sram_port_types_required;
|
||||
sram_port_types_required.push_back(SPICE_MODEL_PORT_INPUT);
|
||||
sram_port_types_required.push_back(SPICE_MODEL_PORT_OUTPUT);
|
||||
|
||||
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*/
|
||||
std::vector<enum e_spice_model_port_type> scff_port_types_required;
|
||||
scff_port_types_required.push_back(SPICE_MODEL_PORT_CLOCK);
|
||||
scff_port_types_required.push_back(SPICE_MODEL_PORT_INPUT);
|
||||
scff_port_types_required.push_back(SPICE_MODEL_PORT_OUTPUT);
|
||||
|
||||
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*/
|
||||
std::vector<enum e_spice_model_port_type> ff_port_types_required;
|
||||
ff_port_types_required.push_back(SPICE_MODEL_PORT_CLOCK);
|
||||
ff_port_types_required.push_back(SPICE_MODEL_PORT_INPUT);
|
||||
ff_port_types_required.push_back(SPICE_MODEL_PORT_OUTPUT);
|
||||
|
||||
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*/
|
||||
std::vector<enum e_spice_model_port_type> lut_port_types_required;
|
||||
lut_port_types_required.push_back(SPICE_MODEL_PORT_SRAM);
|
||||
lut_port_types_required.push_back(SPICE_MODEL_PORT_INPUT);
|
||||
lut_port_types_required.push_back(SPICE_MODEL_PORT_OUTPUT);
|
||||
|
||||
num_err += check_circuit_model_port_required(circuit_lib, SPICE_MODEL_LUT, lut_port_types_required);
|
||||
|
||||
/* If we have any errors, exit */
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"Finished checking circuit library with %d errors!\n",
|
||||
num_err);
|
||||
|
||||
if (0 < num_err) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* End of file : check_circuit_library.cpp
|
||||
***********************************************************************/
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/**********************************************************
|
||||
* 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: check_circuit_library.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 CHECK_CIRCUIT_LIBRARY_H
|
||||
#define CHECK_CIRCUIT_LIBRARY_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 */
|
||||
#include "circuit_library.h"
|
||||
|
||||
/* Check points to make sure we have a valid circuit library */
|
||||
void check_circuit_library(const CircuitLibrary& circuit_lib);
|
||||
|
||||
#endif
|
||||
|
||||
/************************************************************************
|
||||
* End of file : check_circuit_library.h
|
||||
***********************************************************************/
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,574 @@
|
|||
/**********************************************************
|
||||
* 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: circuit_library.h
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2019/08/06 | 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 CIRCUIT_LIBRARY_H
|
||||
#define CIRCUIT_LIBRARY_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 */
|
||||
#include <string>
|
||||
|
||||
#include "vtr_strong_id.h"
|
||||
#include "vtr_geometry.h"
|
||||
|
||||
#include "vtr_vector.h"
|
||||
#include "vtr_range.h"
|
||||
|
||||
#include "circuit_types.h"
|
||||
|
||||
/************************************************************************
|
||||
* Create strong id for Circuit Models/Ports to avoid illegal type casting
|
||||
***********************************************************************/
|
||||
struct circuit_model_id_tag;
|
||||
struct circuit_port_id_tag;
|
||||
struct circuit_edge_id_tag;
|
||||
|
||||
typedef vtr::StrongId<circuit_model_id_tag> CircuitModelId;
|
||||
typedef vtr::StrongId<circuit_port_id_tag> CircuitPortId;
|
||||
typedef vtr::StrongId<circuit_edge_id_tag> CircuitEdgeId;
|
||||
|
||||
|
||||
/* Alias for open ids */
|
||||
#define CIRCUIT_MODEL_OPEN_ID CircuitModelId(-1)
|
||||
#define CIRCUIT_PORT_OPEN_ID CircuitPortId(-1)
|
||||
#define CIRCUIT_EDGE_OPEN_ID CircuitEdgeId(-1)
|
||||
|
||||
/************************************************************************
|
||||
* The class CircuitLibrary is a critical data structure for OpenFPGA
|
||||
* It stores all the circuit-level details from XML architecture file
|
||||
*
|
||||
* It includes the following data:
|
||||
*
|
||||
* ------ Fundamental Information -----
|
||||
* 1. circuit_model_ids_ : unique identifier to find a circuit model
|
||||
* Use a strong id for search, to avoid illegal type casting
|
||||
* 2. circuit_model_types_: types of the circuit model, see details in the definition of enum e_spice_model_type
|
||||
* 3. circuit_model_names_: unique names for each circuit models.
|
||||
* It should be the same as user-defined Verilog modules, if it is not auto-generated
|
||||
* 4. circuit_model_prefix_: the prefix of a circuit model when it is instanciated
|
||||
* 5. verilog_netlist_: specified path and file name of Verilog netlist if a circuit model is not auto-generated
|
||||
* 6. spice_netlist_: specified path and file name of SPICE netlist if a circuit model is not auto-generated
|
||||
* 7. is_default_: indicate if the circuit model is the default one among all those in the same type
|
||||
*
|
||||
* ------ Fast look-ups-----
|
||||
* 1. circuit_model_lookup_: A multi-dimension vector to provide fast look-up on circuit models for users
|
||||
* It classifies CircuitModelIds by their type and set the default model in the first element for each type.
|
||||
* 2. circuit_model_port_lookup_: A multi-dimension vector to provide fast look-up on ports of circuit models for users
|
||||
* It classifies Ports by their types
|
||||
*
|
||||
* ------ Verilog generation options -----
|
||||
* 1. dump_structural_verilog_: if Verilog generator will output structural Verilog syntax for the circuit model
|
||||
* 2. dump_explicit_port_map_: if Verilog generator will use explicit port mapping when instanciate the circuit model
|
||||
*
|
||||
* ------ Design technology information -----
|
||||
* 1. design_tech_types_: the design technology [cmos|rram] for each circuit model
|
||||
* 2. is_power_gated_: specify if the circuit model is power-gated (contain a input to turn on/off VDD and GND)
|
||||
*
|
||||
* ------ Buffer existence -----
|
||||
* Use vectors to simplify the defition of buffer existence:
|
||||
* index (low=0 to high) represents INPUT, OUTPUT, LUT_INPUT_BUF, LUT_INPUT_INV, LUT_INTER_BUFFER
|
||||
* 1. buffer_existence_: specify if this circuit model has an buffer
|
||||
* 2. buffer_circuit_model_name_: specify the name of circuit model for the buffer
|
||||
* 3. buffer_circuit_model_id_: specify the id of circuit model for the buffer
|
||||
*
|
||||
* ------ Pass-gate-related parameters ------
|
||||
* 1. pass_gate_logic_circuit_model_name_: specify the name of circuit model for the pass gate logic
|
||||
* 2. pass_gate_logic_circuit_model_id_: specify the id of circuit model for the pass gate logic
|
||||
*
|
||||
* ------ Port information ------
|
||||
* 1. port_ids_: unique id of ports belonging to a circuit model
|
||||
* 2. port_types_: types of ports belonging to a circuit model
|
||||
* 3. port_sizes_: width of ports belonging to a circuit model
|
||||
* 4. port_prefix_: prefix of a port when instance of a circuit model
|
||||
* 5. port_lib_names_: port name in the standard cell library, only used when explicit_port_mapping is enabled
|
||||
* 6. port_inv_prefix_: the prefix to be added for the inverted port. This is mainly used by SRAM ports, which have an coupled inverterd port
|
||||
* 7. port_is_mode_select: specify if this port is used to select operating modes of the circuit model
|
||||
* 8. port_is_global: specify if this port is a global signal shared by other circuit model
|
||||
* 9. port_is_reset: specify if this port is a reset signal which needs special pulse widths in testbenches
|
||||
* 10. port_is_set: specify if this port is a set signal which needs special pulse widths in testbenches
|
||||
* 11. port_is_config_enable: specify if this port is a config_enable signal which needs special pulse widths in testbenches
|
||||
* 12. port_is_prog: specify if this port is for FPGA programming use which needs special pulse widths in testbenches
|
||||
* 13. port_circuit_model_name: the name of circuit model linked to the port
|
||||
* 14. port_circuit_model_ids_: the Id of circuit model linked to the port
|
||||
* 15. port_inv_circuit_model_names_: the name of inverter circuit model linked to the port
|
||||
* 16. port_inv_circuit_model_ids_: the Id of inverter circuit model linked to the port
|
||||
* 17. port_tri_state_map_: only applicable to inputs of LUTs, the tri-state map applied to each pin of this port
|
||||
* 18. port_lut_frac_level_: only applicable to outputs of LUTs, indicate which level of outputs inside LUT multiplexing structure will be used
|
||||
* 19. port_lut_output_mask_: only applicable to outputs of LUTs, indicate which output at an internal level of LUT multiplexing structure will be used
|
||||
* 20. port_sram_orgz_: only applicable to SRAM ports, indicate how the SRAMs will be organized, either memory decoders or scan-chains
|
||||
*
|
||||
* ------ Delay information ------
|
||||
* 1. delay_types_: type of pin-to-pin delay, either rising_edge of falling_edge
|
||||
* 2. delay_in_port_names_: name of input ports that the pin-to-pin delay is linked to
|
||||
* 3. delay_in_port_names_: name of output ports that the pin-to-pin delay is linked to
|
||||
* 4. delay_values_: delay values of the pin-to-pin delay
|
||||
*
|
||||
* ------ Timing graph information: TODO: consider using tatum? ------
|
||||
* Timing graph is allocated when delay information is made
|
||||
* 1. edge_ids_ : ids of edges in the timing graph
|
||||
* 2. port_in_edge_ids_: ids of input edges for each pin of a circuit port
|
||||
* 3. port_out_edge_ids_: ids of output edges for each pin of a circuit port
|
||||
* 4. edge_src_port_ids_: ids of source ports that each edge is connected to
|
||||
* 5. edge_src_pin_ids_: ids of source pin that each edge is connected to
|
||||
* 6. edge_sink_port_ids_: ids of sink ports that each edge is connected to
|
||||
* 7. edge_sink_pin_ids_: ids of sink pin that each edge is connected to
|
||||
* 8. edge_trise_: rising delay of the edge
|
||||
* 9. edge_tfall_: falling delay of the edge
|
||||
*
|
||||
* ------ Buffer/Inverter-related parameters ------
|
||||
* Note: only applicable to circuit models whose type is buffer or inverter
|
||||
* 1. buffer_types_: type of the buffer, either buffer or inverter
|
||||
* 2. buffer_location_maps_: location of the buffer, only applicable to LUTs
|
||||
* 3. buffer_sizes_: size of buffer (transistor size for the first stage)
|
||||
* 4. buffer_is_tapered_: specify if this buffer has multiple stages
|
||||
* 5. buffer_num_levels: specify the number of levels of this buffer (if this is defined as multi-level buffer)
|
||||
* 6. buffer_f_per_stage: specify the driving strength of the buffer by stage
|
||||
*
|
||||
* ------ Pass-gate-logic-related parameters ------
|
||||
* Note: only applicable to circuit models whose type is pass-gate-logic
|
||||
* 1. pass_gate_logic_types_: types of the pass-gate-logic, either transmission-gate or pass-transistor
|
||||
* 2. pass_gate_logic_nmos_sizes_: size of NMOS transistor in the pass-gate-logic
|
||||
* 3. pass_gate_logic_pmos_sizes_: size of PMOS transistor in the pass-gate-logic, only applicable for transmission-gates
|
||||
*
|
||||
* ------ Multiplexer-related parameters ------
|
||||
* Note: only applicable to circuit models whose type is MUX
|
||||
* 1. mux_structure_: specify the structure of a multiplexer, one-level, multi-level or tree-like
|
||||
* 2. mux_num_levels_: specify the number of levels for a multiplexer
|
||||
* 3. mux_add_const_input_: specify if this multiplexer has a constant input
|
||||
* 4. mux_const_input_values_: specify the value of the constant input for this multiplexer (valid only when mux_add_const_input is true)
|
||||
* 5. mux_use_local_encoder_: specify if the mux as a local encoder between SRAMs and multiplexing structure
|
||||
* 6. mux_advanced_rram_design_: specify if the multiplexer will use advanced RRAM circuit design topology
|
||||
*
|
||||
* ------ LUT-related parameters ------
|
||||
* Note: only applicable to circuit models whose type is LUT
|
||||
* 1. lut_is_fracturable_: specify if this LUT is built with fracturable structure
|
||||
*
|
||||
* ------ RRAM-related parameters ------
|
||||
* Note: only applicable to circuit models whose design technology is RRAM
|
||||
* 1. rlrs: RRAM resistance in Low-Resistance State (LRS)
|
||||
* 2. rhrs: RRAM resistance in High-Resistance State (HRS)
|
||||
* The following transistor sizes are applicable for 4T1R programming structures
|
||||
* 3. wprog_set_nmos: size of n-type programming transistor used to set a RRAM
|
||||
* 4. wprog_set_pmos: size of p-type programming transistor used to set a RRAM
|
||||
* 5. wprog_reset_nmos: size of n-type programming transistor used to reset a RRAM
|
||||
* 6. wprog_reset_pmos: size of p-type programming transistor used to reset a RRAM
|
||||
*
|
||||
* ------ Metal wire-related parameters ------
|
||||
* Note: only applicable to circuit models whose type is wires or channel wires
|
||||
* 1. wire_types_: types of the metal wire for the circuit_model
|
||||
* 2. wire_res_val_: resistance value of the metal wire for the circuit model
|
||||
* 3. wire_cap_val_: capacitance value of the metal wire for the circuit model
|
||||
* 4. wire_num_levels_: number of levels of the metal wire model for the circuit model
|
||||
***********************************************************************/
|
||||
class CircuitLibrary {
|
||||
public: /* Types */
|
||||
typedef vtr::vector<CircuitModelId, CircuitModelId>::const_iterator circuit_model_iterator;
|
||||
typedef vtr::vector<CircuitModelId, std::string>::const_iterator circuit_model_string_iterator;
|
||||
typedef vtr::vector<CircuitPortId, CircuitPortId>::const_iterator circuit_port_iterator;
|
||||
typedef vtr::vector<CircuitEdgeId, CircuitEdgeId>::const_iterator circuit_edge_iterator;
|
||||
/* Create range */
|
||||
typedef vtr::Range<circuit_model_iterator> circuit_model_range;
|
||||
typedef vtr::Range<circuit_port_iterator> circuit_port_range;
|
||||
typedef vtr::Range<circuit_edge_iterator> circuit_edge_range;
|
||||
/* local enumeration for buffer existence */
|
||||
enum e_buffer_type: unsigned char{
|
||||
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;
|
||||
circuit_port_range ports(const CircuitModelId& circuit_model_id) const;
|
||||
std::vector<CircuitModelId> circuit_models_by_type(const enum e_spice_model_type& type) const;
|
||||
std::vector<CircuitPortId> ports_by_type(const CircuitModelId& circuit_model_id, const enum e_spice_model_port_type& port_type) const;
|
||||
std::vector<CircuitPortId> input_ports(const CircuitModelId& circuit_model_id) const;
|
||||
std::vector<CircuitPortId> output_ports(const CircuitModelId& circuit_model_id) const;
|
||||
std::vector<size_t> pins(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const;
|
||||
public: /* Public Accessors: Basic data query on Circuit Models*/
|
||||
size_t num_circuit_models() const;
|
||||
enum e_spice_model_type circuit_model_type(const CircuitModelId& circuit_model_id) const;
|
||||
std::string circuit_model_name(const CircuitModelId& circuit_model_id) const;
|
||||
std::string circuit_model_prefix(const CircuitModelId& circuit_model_id) const;
|
||||
std::string circuit_model_verilog_netlist(const CircuitModelId& circuit_model_id) const;
|
||||
std::string circuit_model_spice_netlist(const CircuitModelId& circuit_model_id) const;
|
||||
bool circuit_model_is_default(const CircuitModelId& circuit_model_id) const;
|
||||
bool dump_structural_verilog(const CircuitModelId& circuit_model_id) const;
|
||||
bool dump_explicit_port_map(const CircuitModelId& circuit_model_id) const;
|
||||
enum e_spice_model_design_tech design_tech_type(const CircuitModelId& circuit_model_id) const;
|
||||
bool is_power_gated(const CircuitModelId& circuit_model_id) const;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
std::string port_lib_name(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const;
|
||||
std::string port_inv_prefix(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const;
|
||||
size_t port_default_value(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const;
|
||||
bool port_is_mode_select(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const;
|
||||
bool port_is_global(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const;
|
||||
bool port_is_reset(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const;
|
||||
bool port_is_set(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const;
|
||||
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 std::string& name) const;
|
||||
CircuitModelId default_circuit_model(const enum e_spice_model_type& type) const;
|
||||
public: /* Public Accessors: Timing graph */
|
||||
CircuitEdgeId edge(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& from_port, const size_t from_pin,
|
||||
const CircuitPortId& to_port, const size_t to_pin);
|
||||
public: /* Public Mutators */
|
||||
CircuitModelId add_circuit_model();
|
||||
/* Fundamental information */
|
||||
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);
|
||||
/* Verilog generator options */
|
||||
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);
|
||||
/* Design technology information */
|
||||
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_is_power_gated(const CircuitModelId& circuit_model_id, const bool& is_power_gated);
|
||||
/* Buffer existence */
|
||||
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);
|
||||
void set_circuit_model_lut_intermediate_buffer_location_map(const CircuitModelId& circuit_model_id,
|
||||
const std::string& location_map);
|
||||
/* Pass-gate-related parameters */
|
||||
void set_circuit_model_pass_gate_logic(const CircuitModelId& circuit_model_id, const std::string& circuit_model_name);
|
||||
/* Port information */
|
||||
CircuitPortId add_circuit_model_port(const CircuitModelId& circuit_model_id);
|
||||
void set_port_type(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const enum e_spice_model_port_type& port_type);
|
||||
void set_port_size(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const size_t& port_size);
|
||||
void set_port_prefix(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const std::string& port_prefix);
|
||||
void set_port_lib_name(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const std::string& lib_name);
|
||||
void set_port_inv_prefix(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const std::string& inv_prefix);
|
||||
void set_port_default_value(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const size_t& default_val);
|
||||
void set_port_is_mode_select(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const bool& is_mode_select);
|
||||
void set_port_is_global(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const bool& is_global);
|
||||
void set_port_is_reset(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const bool& is_reset);
|
||||
void set_port_is_set(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const bool& is_set);
|
||||
void set_port_is_config_enable(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const bool& is_config_enable);
|
||||
void set_port_is_prog(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const bool& is_prog);
|
||||
void set_port_circuit_model_name(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const std::string& circuit_model_name);
|
||||
void set_port_circuit_model_id(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const CircuitModelId& port_circuit_model_id);
|
||||
void set_port_inv_circuit_model_name(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const std::string& inv_circuit_model_name);
|
||||
void set_port_inv_circuit_model_id(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const CircuitModelId& inv_circuit_model_id);
|
||||
void set_port_tri_state_map(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const std::string& tri_state_map);
|
||||
void set_port_lut_frac_level(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const size_t& lut_frac_level);
|
||||
void set_port_lut_output_mask(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const std::vector<size_t>& lut_output_masks);
|
||||
void set_port_sram_orgz(const CircuitModelId& circuit_model_id,
|
||||
const CircuitPortId& circuit_port_id,
|
||||
const enum e_sram_orgz& sram_orgz);
|
||||
/* Delay information */
|
||||
void add_delay_info(const CircuitModelId& circuit_model_id,
|
||||
const enum spice_model_delay_type& delay_type);
|
||||
void set_delay_in_port_names(const CircuitModelId& circuit_model_id,
|
||||
const enum spice_model_delay_type& delay_type,
|
||||
const std::string& in_port_names);
|
||||
void set_delay_out_port_names(const CircuitModelId& circuit_model_id,
|
||||
const enum spice_model_delay_type& delay_type,
|
||||
const std::string& out_port_names);
|
||||
void set_delay_values(const CircuitModelId& circuit_model_id,
|
||||
const enum spice_model_delay_type& delay_type,
|
||||
const std::string& delay_values);
|
||||
/* Buffer/Inverter-related parameters */
|
||||
void set_buffer_type(const CircuitModelId& circuit_model_id,
|
||||
const enum e_spice_model_buffer_type& buffer_type);
|
||||
void set_buffer_size(const CircuitModelId& circuit_model_id,
|
||||
const float& buffer_size);
|
||||
void set_buffer_num_levels(const CircuitModelId& circuit_model_id,
|
||||
const size_t& num_levels);
|
||||
void set_buffer_f_per_stage(const CircuitModelId& circuit_model_id,
|
||||
const size_t& f_per_stage);
|
||||
/* Pass-gate-related parameters */
|
||||
void set_pass_gate_logic_type(const CircuitModelId& circuit_model_id,
|
||||
const enum e_spice_model_pass_gate_logic_type& pass_gate_logic_type);
|
||||
void set_pass_gate_logic_nmos_size(const CircuitModelId& circuit_model_id,
|
||||
const float& nmos_size);
|
||||
void set_pass_gate_logic_pmos_size(const CircuitModelId& circuit_model_id,
|
||||
const float& pmos_size);
|
||||
/* Multiplexer-related parameters */
|
||||
void set_mux_structure(const CircuitModelId& circuit_model_id,
|
||||
const enum e_spice_model_structure& mux_structure);
|
||||
void set_mux_num_levels(const CircuitModelId& circuit_model_id,
|
||||
const size_t& num_levels);
|
||||
void set_mux_const_input_value(const CircuitModelId& circuit_model_id,
|
||||
const size_t& const_input_value);
|
||||
void set_mux_use_local_encoder(const CircuitModelId& circuit_model_id,
|
||||
const bool& use_local_encoder);
|
||||
void set_mux_use_advanced_rram_design(const CircuitModelId& circuit_model_id,
|
||||
const bool& use_advanced_rram_design);
|
||||
/* LUT-related parameters */
|
||||
void set_lut_is_fracturable(const CircuitModelId& circuit_model_id,
|
||||
const bool& is_fracturable);
|
||||
/* Gate-related parameters */
|
||||
void set_gate_type(const CircuitModelId& circuit_model_id,
|
||||
const enum e_spice_model_gate_type& gate_type);
|
||||
/* RRAM-related design technology information */
|
||||
void set_rram_rlrs(const CircuitModelId& circuit_model_id,
|
||||
const float& rlrs);
|
||||
void set_rram_rhrs(const CircuitModelId& circuit_model_id,
|
||||
const float& rhrs);
|
||||
void set_rram_wprog_set_nmos(const CircuitModelId& circuit_model_id,
|
||||
const float& wprog_set_nmos);
|
||||
void set_rram_wprog_set_pmos(const CircuitModelId& circuit_model_id,
|
||||
const float& wprog_set_pmos);
|
||||
void set_rram_wprog_reset_nmos(const CircuitModelId& circuit_model_id,
|
||||
const float& wprog_reset_nmos);
|
||||
void set_rram_wprog_reset_pmos(const CircuitModelId& circuit_model_id,
|
||||
const float& wprog_reset_pmos);
|
||||
/* Wire parameters */
|
||||
void set_wire_type(const CircuitModelId& circuit_model_id,
|
||||
const enum e_wire_model_type& wire_type);
|
||||
void set_wire_r(const CircuitModelId& circuit_model_id,
|
||||
const float& r_val);
|
||||
void set_wire_c(const CircuitModelId& circuit_model_id,
|
||||
const float& c_val);
|
||||
void set_wire_num_levels(const CircuitModelId& circuit_model_id,
|
||||
const size_t& num_level);
|
||||
public: /* Public Mutators: builders */
|
||||
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 link_port_circuit_model(const CircuitModelId& circuit_model_id);
|
||||
void link_port_inv_circuit_model(const CircuitModelId& circuit_model_id);
|
||||
void link_port_circuit_models(const CircuitModelId& circuit_model_id);
|
||||
void link_buffer_circuit_model(const CircuitModelId& circuit_model_id);
|
||||
void link_pass_gate_logic_circuit_model(const CircuitModelId& circuit_model_id);
|
||||
void build_circuit_model_links();
|
||||
void build_circuit_model_timing_graph(const CircuitModelId& circuit_model_id);
|
||||
void build_timing_graphs();
|
||||
public: /* Internal mutators: build timing graphs */
|
||||
void 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);
|
||||
void set_edge_delay(const CircuitModelId& circuit_model_id,
|
||||
const CircuitEdgeId& circuit_edge_id,
|
||||
const enum spice_model_delay_type& delay_type,
|
||||
const float& delay_value);
|
||||
/* validate the circuit_edge_id */
|
||||
void set_timing_graph_delays(const CircuitModelId& circuit_model_id);
|
||||
public: /* Internal mutators: build fast look-ups */
|
||||
void build_circuit_model_lookup();
|
||||
void build_circuit_model_port_lookup(const CircuitModelId& circuit_model_id);
|
||||
private: /* Internal invalidators/validators */
|
||||
/* Validators */
|
||||
bool valid_circuit_model_id(const CircuitModelId& circuit_model_id) const;
|
||||
bool valid_circuit_port_id(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const;
|
||||
bool valid_circuit_pin_id(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id, const size_t& pin_id) const;
|
||||
bool valid_delay_type(const CircuitModelId& circuit_model_id, const enum spice_model_delay_type& delay_type) const;
|
||||
bool valid_circuit_edge_id(const CircuitModelId& circuit_model_id, const CircuitEdgeId& circuit_edge_id) const;
|
||||
/* Invalidators */
|
||||
void invalidate_circuit_model_lookup() const;
|
||||
void invalidate_circuit_model_port_lookup(const CircuitModelId& circuit_model_id) const;
|
||||
void invalidate_circuit_model_timing_graph(const CircuitModelId& circuit_model_id);
|
||||
private: /* Internal data */
|
||||
/* Fundamental information */
|
||||
vtr::vector<CircuitModelId, CircuitModelId> circuit_model_ids_;
|
||||
vtr::vector<CircuitModelId, enum e_spice_model_type> circuit_model_types_;
|
||||
vtr::vector<CircuitModelId, std::string> circuit_model_names_;
|
||||
vtr::vector<CircuitModelId, std::string> circuit_model_prefix_;
|
||||
vtr::vector<CircuitModelId, std::string> circuit_model_verilog_netlists_;
|
||||
vtr::vector<CircuitModelId, std::string> circuit_model_spice_netlists_;
|
||||
vtr::vector<CircuitModelId, bool> circuit_model_is_default_;
|
||||
|
||||
/* fast look-up for circuit models to categorize by types
|
||||
* [type][num_ids]
|
||||
* Important: we force the default circuit model in the first element for each type
|
||||
*/
|
||||
typedef std::vector<std::vector<CircuitModelId>> CircuitModelLookup;
|
||||
mutable CircuitModelLookup circuit_model_lookup_; /* [circuit_model_type][circuit_model_ids] */
|
||||
typedef std::vector<std::vector<std::vector<CircuitPortId>>> CircuitModelPortLookup;
|
||||
mutable CircuitModelPortLookup circuit_model_port_lookup_; /* [circuit_model_id][port_type][port_ids] */
|
||||
|
||||
/* Verilog generator options */
|
||||
vtr::vector<CircuitModelId, bool> dump_structural_verilog_;
|
||||
vtr::vector<CircuitModelId, bool> dump_explicit_port_map_;
|
||||
|
||||
/* Design technology information */
|
||||
vtr::vector<CircuitModelId, enum e_spice_model_design_tech> design_tech_types_;
|
||||
vtr::vector<CircuitModelId, bool> is_power_gated_;
|
||||
|
||||
/* Buffer existence */
|
||||
vtr::vector<CircuitModelId, std::vector<bool>> buffer_existence_;
|
||||
vtr::vector<CircuitModelId, std::vector<std::string>> buffer_circuit_model_names_;
|
||||
vtr::vector<CircuitModelId, std::vector<CircuitModelId>> buffer_circuit_model_ids_;
|
||||
vtr::vector<CircuitModelId, std::vector<std::string>> buffer_location_maps_;
|
||||
|
||||
/* Pass-gate-related parameters */
|
||||
vtr::vector<CircuitModelId, std::string> pass_gate_logic_circuit_model_names_;
|
||||
vtr::vector<CircuitModelId, CircuitModelId> pass_gate_logic_circuit_model_ids_;
|
||||
|
||||
/* Port information */
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, CircuitPortId>> port_ids_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, enum e_spice_model_port_type>> port_types_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, size_t>> port_sizes_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::string>> port_prefix_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::string>> port_lib_names_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::string>> port_inv_prefix_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, size_t>> port_default_values_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, bool>> port_is_mode_select_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, bool>> port_is_global_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, bool>> port_is_reset_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, bool>> port_is_set_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, bool>> port_is_config_enable_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, bool>> port_is_prog_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::string>> port_circuit_model_names_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, CircuitModelId>> port_circuit_model_ids_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::string>> port_inv_circuit_model_names_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, CircuitModelId>> port_inv_circuit_model_ids_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::string>> port_tri_state_maps_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, size_t>> port_lut_frac_level_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, std::vector<size_t>>> port_lut_output_masks_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, enum e_sram_orgz>> port_sram_orgz_;
|
||||
|
||||
/* Timing graphs */
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, CircuitEdgeId>> edge_ids_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, vtr::vector<size_t, CircuitEdgeId>>> port_in_edge_ids_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, vtr::vector<size_t, CircuitEdgeId>>> port_out_edge_ids_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, CircuitPortId>> edge_src_port_ids_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, size_t>> edge_src_pin_ids_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, CircuitPortId>> edge_sink_port_ids_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, size_t>> edge_sink_pin_ids_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, std::vector<float>>> edge_timing_info_; /* x0 => trise, x1 => tfall */
|
||||
|
||||
/* Delay information */
|
||||
vtr::vector<CircuitModelId, std::vector<enum spice_model_delay_type>> delay_types_;
|
||||
vtr::vector<CircuitModelId, std::vector<std::string>> delay_in_port_names_;
|
||||
vtr::vector<CircuitModelId, std::vector<std::string>> delay_out_port_names_;
|
||||
vtr::vector<CircuitModelId, std::vector<std::string>> delay_values_;
|
||||
|
||||
/* Buffer/Inverter-related parameters */
|
||||
vtr::vector<CircuitModelId, enum e_spice_model_buffer_type> buffer_types_;
|
||||
vtr::vector<CircuitModelId, float> buffer_sizes_;
|
||||
vtr::vector<CircuitModelId, size_t> buffer_num_levels_;
|
||||
vtr::vector<CircuitModelId, size_t> buffer_f_per_stage_;
|
||||
|
||||
/* Pass-gate-related parameters */
|
||||
vtr::vector<CircuitModelId, enum e_spice_model_pass_gate_logic_type> pass_gate_logic_types_;
|
||||
vtr::vector<CircuitModelId, vtr::Point<float>> pass_gate_logic_sizes_; /* x=> nmos_size; y => pmos_size */
|
||||
|
||||
/* Multiplexer-related parameters */
|
||||
vtr::vector<CircuitModelId, enum e_spice_model_structure> mux_structure_;
|
||||
vtr::vector<CircuitModelId, size_t> mux_num_levels_;
|
||||
vtr::vector<CircuitModelId, size_t> mux_const_input_values_;
|
||||
vtr::vector<CircuitModelId, bool> mux_use_local_encoder_;
|
||||
vtr::vector<CircuitModelId, bool> mux_use_advanced_rram_design_;
|
||||
|
||||
/* LUT-related parameters */
|
||||
vtr::vector<CircuitModelId, bool> lut_is_fracturable_;
|
||||
|
||||
/* Gate-related parameters */
|
||||
vtr::vector<CircuitModelId, enum e_spice_model_gate_type> gate_types_;
|
||||
|
||||
/* RRAM-related design technology information */
|
||||
vtr::vector<CircuitModelId, vtr::Point<float>> rram_res_; /* x => R_LRS, y => R_HRS */
|
||||
vtr::vector<CircuitModelId, vtr::Point<float>> wprog_set_; /* x => wprog_set_nmos, y=> wprog_set_pmos */
|
||||
vtr::vector<CircuitModelId, vtr::Point<float>> wprog_reset_; /* x => wprog_reset_nmos, y=> wprog_reset_pmos */
|
||||
|
||||
/* Wire parameters */
|
||||
vtr::vector<CircuitModelId, enum e_wire_model_type> wire_types_;
|
||||
vtr::vector<CircuitModelId, vtr::Point<float>> wire_rc_; /* x => wire_res_val, y=> wire_cap_val */
|
||||
vtr::vector<CircuitModelId, size_t> wire_num_levels_;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/************************************************************************
|
||||
* End of file : circuit_library.cpp
|
||||
***********************************************************************/
|
|
@ -0,0 +1,148 @@
|
|||
/**********************************************************
|
||||
* 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: circuit_types.h
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2019/08/08 | 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 CIRCUIT_TYPES_H
|
||||
#define CIRCUIT_TYPES_H
|
||||
|
||||
/************************************************************************
|
||||
* This file includes basic enumeration types for circuit models
|
||||
***********************************************************************/
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
enum spice_model_delay_type {
|
||||
SPICE_MODEL_DELAY_RISE,
|
||||
SPICE_MODEL_DELAY_FALL,
|
||||
NUM_CIRCUIT_MODEL_DELAY_TYPES
|
||||
};
|
||||
|
||||
/*Struct for a SPICE model of a module*/
|
||||
enum e_spice_model_type {
|
||||
SPICE_MODEL_CHAN_WIRE,
|
||||
SPICE_MODEL_WIRE,
|
||||
SPICE_MODEL_MUX,
|
||||
SPICE_MODEL_LUT,
|
||||
SPICE_MODEL_FF,
|
||||
SPICE_MODEL_SRAM,
|
||||
SPICE_MODEL_HARDLOGIC,
|
||||
SPICE_MODEL_SCFF,
|
||||
SPICE_MODEL_IOPAD,
|
||||
SPICE_MODEL_INVBUF,
|
||||
SPICE_MODEL_PASSGATE,
|
||||
SPICE_MODEL_GATE,
|
||||
NUM_CIRCUIT_MODEL_TYPES
|
||||
};
|
||||
/* Strings correspond to each port type */
|
||||
constexpr std::array<const char*, NUM_CIRCUIT_MODEL_TYPES> CIRCUIT_MODEL_TYPE_STRING = {{"CHAN_WIRE", "WIRE", "MUX", "LUT", "FF", "SRAM", "HARDLOGIC", "SCFF", "IOPAD", "INVBUF", "PASSGATE", "GATE"}};
|
||||
|
||||
enum e_spice_model_design_tech {
|
||||
SPICE_MODEL_DESIGN_CMOS,
|
||||
SPICE_MODEL_DESIGN_RRAM,
|
||||
NUM_CIRCUIT_MODEL_DESIGN_TECH_TYPES
|
||||
};
|
||||
|
||||
enum e_spice_model_structure {
|
||||
SPICE_MODEL_STRUCTURE_TREE,
|
||||
SPICE_MODEL_STRUCTURE_ONELEVEL,
|
||||
SPICE_MODEL_STRUCTURE_MULTILEVEL,
|
||||
SPICE_MODEL_STRUCTURE_CROSSBAR,
|
||||
NUM_CIRCUIT_MODEL_STRUCTURE_TYPES
|
||||
};
|
||||
|
||||
enum e_spice_model_buffer_type {
|
||||
SPICE_MODEL_BUF_INV,
|
||||
SPICE_MODEL_BUF_BUF,
|
||||
NUM_CIRCUIT_MODEL_BUF_TYPES
|
||||
};
|
||||
|
||||
enum e_spice_model_pass_gate_logic_type {
|
||||
SPICE_MODEL_PASS_GATE_TRANSMISSION,
|
||||
SPICE_MODEL_PASS_GATE_TRANSISTOR,
|
||||
NUM_CIRCUIT_MODEL_PASS_GATE_TYPES
|
||||
};
|
||||
|
||||
enum e_spice_model_gate_type {
|
||||
SPICE_MODEL_GATE_AND,
|
||||
SPICE_MODEL_GATE_OR,
|
||||
SPICE_MODEL_GATE_MUX2,
|
||||
NUM_SPICE_MODEL_GATE_TYPES
|
||||
};
|
||||
|
||||
enum e_wire_model_type {
|
||||
WIRE_MODEL_PIE,
|
||||
WIRE_MODEL_T,
|
||||
NUM_WIRE_MODEL_TYPES,
|
||||
};
|
||||
|
||||
enum e_spice_model_port_type {
|
||||
SPICE_MODEL_PORT_INPUT,
|
||||
SPICE_MODEL_PORT_OUTPUT,
|
||||
SPICE_MODEL_PORT_INOUT,
|
||||
SPICE_MODEL_PORT_CLOCK,
|
||||
SPICE_MODEL_PORT_SRAM,
|
||||
SPICE_MODEL_PORT_BL,
|
||||
SPICE_MODEL_PORT_BLB,
|
||||
SPICE_MODEL_PORT_WL,
|
||||
SPICE_MODEL_PORT_WLB,
|
||||
NUM_CIRCUIT_MODEL_PORT_TYPES
|
||||
};
|
||||
/* Strings correspond to each port type */
|
||||
constexpr std::array<const char*, NUM_CIRCUIT_MODEL_PORT_TYPES> CIRCUIT_MODEL_PORT_TYPE_STRING = {{"INPUT", "OUTPUT", "INOUT", "CLOCK", "SRAM", "BL", "BLB", "WL", "WLB"}};
|
||||
|
||||
/* For SRAM */
|
||||
enum e_sram_orgz {
|
||||
SPICE_SRAM_STANDALONE, /* SRAMs are organized and accessed as standalone elements */
|
||||
SPICE_SRAM_SCAN_CHAIN, /* SRAMs are organized and accessed by a scan-chain */
|
||||
SPICE_SRAM_MEMORY_BANK, /* SRAMs are organized and accessed by memory bank */
|
||||
SPICE_SRAM_LOCAL_ENCODER, /* SRAMs are organized and accessed by a local encoder */
|
||||
NUM_CIRCUIT_MODEL_SRAM_ORGZ_TYPES
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/************************************************************************
|
||||
* End of file : circuit_types.h
|
||||
***********************************************************************/
|
||||
|
|
@ -37,14 +37,26 @@ size_t BasicPort::get_lsb() const {
|
|||
return lsb_;
|
||||
}
|
||||
|
||||
/* get the name */
|
||||
std::string BasicPort::get_name() const {
|
||||
return name_;
|
||||
}
|
||||
|
||||
/* Mutators */
|
||||
/* copy */
|
||||
void BasicPort::set(const BasicPort& basic_port) {
|
||||
name_ = basic_port.get_name();
|
||||
lsb_ = basic_port.get_lsb();
|
||||
msb_ = basic_port.get_msb();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* set the port LSB and MSB */
|
||||
void BasicPort::set_name(const std::string& name) {
|
||||
name_ = name;
|
||||
return;
|
||||
}
|
||||
|
||||
/* set the port LSB and MSB */
|
||||
void BasicPort::set_width(size_t width) {
|
|
@ -5,6 +5,8 @@
|
|||
#ifndef DEVICE_PORT_H
|
||||
#define DEVICE_PORT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
/* A basic port */
|
||||
class BasicPort {
|
||||
public: /* Constructors */
|
||||
|
@ -14,8 +16,11 @@ class BasicPort {
|
|||
size_t get_width() const; /* get the port width */
|
||||
size_t get_msb() const; /* get the LSB */
|
||||
size_t get_lsb() const; /* get the LSB */
|
||||
std::string get_name() const; /* get the name */
|
||||
bool is_valid() const; /* check if port size is valid > 0 */
|
||||
public: /* Mutators */
|
||||
void set(const BasicPort& basic_port); /* copy */
|
||||
void set_name(const std::string& name); /* set the port LSB and MSB */
|
||||
void set_width(size_t width); /* set the port LSB and MSB */
|
||||
void set_width(size_t lsb, size_t msb); /* set the port LSB and MSB */
|
||||
void set_lsb(size_t lsb);
|
||||
|
@ -28,8 +33,8 @@ class BasicPort {
|
|||
void combine(const BasicPort& port); /* Combine two ports */
|
||||
private: /* internal functions */
|
||||
void make_invalid(); /* Make a port invalid */
|
||||
bool is_valid() const; /* check if port size is valid > 0 */
|
||||
private: /* Internal Data */
|
||||
std::string name_; /* Name of this port */
|
||||
size_t msb_; /* Most Significant Bit of this port */
|
||||
size_t lsb_; /* Least Significant Bit of this port */
|
||||
};
|
|
@ -0,0 +1,331 @@
|
|||
/**********************************************************
|
||||
* 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: port_parser.cpp
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2019/08/09 | Xifan Tang | Created
|
||||
* +-------------------------------------+
|
||||
***********************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Member functions for Port parsers
|
||||
***********************************************************************/
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_geometry.h"
|
||||
|
||||
#include "string_token.h"
|
||||
|
||||
#include "port_parser.h"
|
||||
|
||||
/************************************************************************
|
||||
* Member functions for PortParser class
|
||||
***********************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Constructors
|
||||
***********************************************************************/
|
||||
PortParser::PortParser (const std::string& data) {
|
||||
set_default_bracket();
|
||||
set_default_delim();
|
||||
set_data(data);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public Accessors
|
||||
***********************************************************************/
|
||||
/* Get the data string */
|
||||
std::string PortParser::data() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
BasicPort PortParser::port() const {
|
||||
return port_;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public Mutators
|
||||
***********************************************************************/
|
||||
void PortParser::set_data(const std::string& data) {
|
||||
data_ = data;
|
||||
parse();
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Internal Mutators
|
||||
***********************************************************************/
|
||||
/* Parse the data */
|
||||
void PortParser::parse() {
|
||||
/* Create a tokenizer */
|
||||
StringToken tokenizer(data_);
|
||||
|
||||
/* Split the data into <port_name> and <pin_string> */
|
||||
std::vector<std::string> port_tokens = tokenizer.split(bracket_.x());
|
||||
/* Make sure we have a port name! */
|
||||
VTR_ASSERT_SAFE ((1 == port_tokens.size()) || (2 == port_tokens.size()));
|
||||
/* Store the port name! */
|
||||
port_.set_name(port_tokens[0]);
|
||||
|
||||
/* If we only have one token */
|
||||
if (1 == port_tokens.size()) {
|
||||
port_.set_width(0);
|
||||
return; /* We can finish here */
|
||||
}
|
||||
|
||||
/* Chomp the ']' */
|
||||
tokenizer.set_data(port_tokens[1]);
|
||||
std::vector<std::string> pin_tokens = tokenizer.split(bracket_.y());
|
||||
/* Make sure we have a valid string! */
|
||||
VTR_ASSERT_SAFE (1 == port_tokens.size());
|
||||
|
||||
/* Split the pin string now */
|
||||
tokenizer.set_data(port_tokens[0]);
|
||||
pin_tokens = tokenizer.split(delim_);
|
||||
|
||||
/* Check if we have LSB and MSB or just one */
|
||||
if ( 1 == pin_tokens.size() ) {
|
||||
/* Single pin */
|
||||
port_.set_width(stoi(pin_tokens[0]), stoi(pin_tokens[0]));
|
||||
} else if ( 2 == pin_tokens.size() ) {
|
||||
/* A number of pin */
|
||||
port_.set_width(stoi(pin_tokens[0]), stoi(pin_tokens[1]));
|
||||
}
|
||||
|
||||
/* Re-order to ensure LSB <= MSB */
|
||||
if (false == port_.is_valid()) {
|
||||
port_.revert();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void PortParser::set_default_bracket() {
|
||||
bracket_.set_x('[');
|
||||
bracket_.set_y(']');
|
||||
return;
|
||||
}
|
||||
|
||||
void PortParser::set_default_delim() {
|
||||
delim_ = ':';
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Member functions for MultiPortParser class
|
||||
***********************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Constructors
|
||||
***********************************************************************/
|
||||
MultiPortParser::MultiPortParser (const std::string& data) {
|
||||
set_default_delim();
|
||||
set_data(data);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public Accessors
|
||||
***********************************************************************/
|
||||
/* Get the data string */
|
||||
std::string MultiPortParser::data() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
std::vector<BasicPort> MultiPortParser::ports() const {
|
||||
return ports_;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public Mutators
|
||||
***********************************************************************/
|
||||
void MultiPortParser::set_data(const std::string& data) {
|
||||
data_ = data;
|
||||
parse();
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Internal Mutators
|
||||
***********************************************************************/
|
||||
/* Split the data line into fragments and parse one by one */
|
||||
void MultiPortParser::parse() {
|
||||
/* Clear content */
|
||||
clear();
|
||||
|
||||
/* Create a tokenizer */
|
||||
StringToken tokenizer(data_);
|
||||
|
||||
/* Split the data into <port_name> and <pin_string> */
|
||||
std::vector<std::string> port_tokens = tokenizer.split(delim_);
|
||||
|
||||
/* Use PortParser for each token */
|
||||
for (const auto& port : port_tokens) {
|
||||
PortParser port_parser(port);
|
||||
/* Get the port name, LSB and MSB */
|
||||
ports_.push_back(port_parser.port());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void MultiPortParser::set_default_delim() {
|
||||
delim_ = ' ';
|
||||
return;
|
||||
}
|
||||
|
||||
void MultiPortParser::clear() {
|
||||
ports_.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Member functions for PortDelayParser class
|
||||
***********************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Constructors
|
||||
***********************************************************************/
|
||||
PortDelayParser::PortDelayParser (const std::string& data) {
|
||||
set_default_element_delim();
|
||||
set_default_line_delim();
|
||||
set_data(data);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public Accessors
|
||||
***********************************************************************/
|
||||
/* Get the data string */
|
||||
std::string PortDelayParser::data() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
/* Get the size of delay matrix [height, width]*/
|
||||
size_t PortDelayParser::height() const {
|
||||
return delay_matrix_.dim_size(0);
|
||||
}
|
||||
|
||||
size_t PortDelayParser::width() const {
|
||||
return delay_matrix_.dim_size(1);
|
||||
}
|
||||
|
||||
vtr::Point<size_t> PortDelayParser::delay_size() const {
|
||||
vtr::Point<size_t> matrix_size(height(), width());
|
||||
return matrix_size;
|
||||
}
|
||||
|
||||
float PortDelayParser::delay(size_t x, size_t y) const {
|
||||
/* Make sure x and y are in range */
|
||||
VTR_ASSERT_SAFE( (x < width()) && (y < height()) );
|
||||
return delay_matrix_[x][y];
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public Mutators
|
||||
***********************************************************************/
|
||||
void PortDelayParser::set_data(const std::string& data) {
|
||||
data_ = data;
|
||||
parse();
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Internal Mutators
|
||||
***********************************************************************/
|
||||
/* Split the data line into fragments and parse one by one */
|
||||
void PortDelayParser::parse() {
|
||||
/* Clear content */
|
||||
clear();
|
||||
|
||||
/* Create a tokenizer */
|
||||
StringToken delay_tokenizer(data_);
|
||||
/* Ensure a clean start! Trim whitespace at the beginning and end of the string */
|
||||
delay_tokenizer.trim();
|
||||
|
||||
/* Split the data into different lines */
|
||||
std::vector<std::string> delay_lines = delay_tokenizer.split(line_delim_);
|
||||
|
||||
/* The number of lines is actually the height of delay matrix */
|
||||
size_t matrix_height = delay_lines.size();
|
||||
size_t matrix_width = 0;
|
||||
|
||||
/* Visit each line and split with element_delim */
|
||||
for (const auto& line : delay_lines) {
|
||||
/* Create a tokenizer for each line */
|
||||
StringToken line_tokenizer(line);
|
||||
std::vector<std::string> delay_elements = line_tokenizer.split(element_delim_);
|
||||
/* Get maximum number of length, which is the width of delay matrix */
|
||||
matrix_width = std::max(matrix_width, delay_elements.size());
|
||||
}
|
||||
|
||||
/* Resize matrix */
|
||||
delay_matrix_.resize({matrix_height, matrix_width});
|
||||
|
||||
/* Fill matrix */
|
||||
for (const auto& line : delay_lines) {
|
||||
/* Create a tokenizer for each line */
|
||||
StringToken line_tokenizer(line);
|
||||
std::vector<std::string> delay_elements = line_tokenizer.split(element_delim_);
|
||||
/* Get maximum number of length, which is the width of delay matrix */
|
||||
for (const auto& element : delay_elements) {
|
||||
delay_matrix_[size_t(&line - &delay_lines[0])][size_t(&element - &delay_elements[0])] = stof(element);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void PortDelayParser::set_default_element_delim() {
|
||||
/* Ensure a clean start */
|
||||
element_delim_.clear();
|
||||
element_delim_.push_back(' ');
|
||||
element_delim_.push_back('\t');
|
||||
return;
|
||||
}
|
||||
|
||||
void PortDelayParser::set_default_line_delim() {
|
||||
/* Ensure a clean start */
|
||||
line_delim_.clear();
|
||||
line_delim_.push_back('\n');
|
||||
line_delim_.push_back('\r');
|
||||
return;
|
||||
}
|
||||
|
||||
void PortDelayParser::clear() {
|
||||
delay_matrix_.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* End of file : port_parser.cpp
|
||||
***********************************************************************/
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
/**********************************************************
|
||||
* 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: port_parser.h
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2019/08/09 | 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 PORT_PARSER_H
|
||||
#define PORT_PARSER_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 */
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "vtr_ndmatrix.h"
|
||||
#include "vtr_geometry.h"
|
||||
|
||||
#include "device_port.h"
|
||||
#include "string_token.h"
|
||||
|
||||
/************************************************************************
|
||||
* This file includes parsers for port definition in the architecture XML
|
||||
* language. Note that it is also compatiable to Verilog syntax.
|
||||
* It means we may reuse this for constructing a structural Verilog parser
|
||||
***********************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Class PortParser: single port parser
|
||||
* Supported port definition:
|
||||
* 1. <port_name>[<LSB>:<MSB>]
|
||||
* 2. <port_name>[<MSB>:<LSB>]
|
||||
* 3. <port_name>[<single_pin_index>]
|
||||
* 4. <port_name>[]
|
||||
* 5. <port_name>
|
||||
* In case 4 and 5, we will assign (-1,-1) for LSB and MSB
|
||||
***********************************************************************/
|
||||
class PortParser{
|
||||
public : /* Constructors*/
|
||||
PortParser (const std::string& data);
|
||||
public : /* Public Accessors */
|
||||
std::string data() const;
|
||||
BasicPort port() const;
|
||||
public : /* Public Mutators */
|
||||
void set_data(const std::string& data);
|
||||
private : /* Private Mutators */
|
||||
void parse();
|
||||
void set_default_bracket();
|
||||
void set_default_delim();
|
||||
private: /* Internal data */
|
||||
std::string data_; /* Lines to be splited */
|
||||
vtr::Point<char> bracket_;
|
||||
char delim_;
|
||||
BasicPort port_;
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* MultiPortParser: a parser for multiple ports in one line
|
||||
***********************************************************************/
|
||||
class MultiPortParser {
|
||||
public : /* Constructors*/
|
||||
MultiPortParser (const std::string& data);
|
||||
public : /* Public Accessors */
|
||||
std::string data() const;
|
||||
std::vector<BasicPort> ports() const;
|
||||
public : /* Public Mutators */
|
||||
void set_data(const std::string& data);
|
||||
private : /* Private Mutators */
|
||||
void parse();
|
||||
void set_default_delim();
|
||||
void clear();
|
||||
private: /* Internal data */
|
||||
std::string data_; /* Lines to be splited */
|
||||
char delim_;
|
||||
std::vector<BasicPort> ports_;
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* PortDelayParser: a parser for 2D delay matrix
|
||||
***********************************************************************/
|
||||
class PortDelayParser {
|
||||
public : /* Constructors*/
|
||||
PortDelayParser (const std::string& data);
|
||||
public : /* Public Accessors */
|
||||
std::string data() const;
|
||||
size_t height() const;
|
||||
size_t width() const;
|
||||
vtr::Point<size_t> delay_size() const;
|
||||
float delay(size_t x, size_t y) const;
|
||||
public : /* Public Mutators */
|
||||
void set_data(const std::string& data);
|
||||
private : /* Private Mutators */
|
||||
void parse();
|
||||
void set_default_element_delim();
|
||||
void set_default_line_delim();
|
||||
void clear();
|
||||
private: /* Internal data */
|
||||
std::string data_; /* Lines to be splited */
|
||||
std::vector<char> element_delim_;
|
||||
std::vector<char> line_delim_;
|
||||
vtr::Matrix<float> delay_matrix_;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/************************************************************************
|
||||
* End of file : port_parser.h
|
||||
***********************************************************************/
|
||||
|
|
@ -1,6 +1,55 @@
|
|||
/**********************************************************
|
||||
* 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: read_xml_spice.h
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2015/XX/XX | 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 READ_XML_SPICE_H
|
||||
#define READ_XML_SPICE_H
|
||||
|
||||
/* Xifan TANG: Spice Support*/
|
||||
|
||||
void ProcessSpiceSRAM(INOUTP ezxml_t Node, OUTP struct s_arch* arch);
|
||||
|
||||
void ProcessSpiceSettings(ezxml_t Parent,
|
||||
t_spice* spice);
|
||||
|
||||
#endif
|
||||
|
||||
/************************************************************************
|
||||
* End of file : read_xml_spice.h
|
||||
***********************************************************************/
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "util.h"
|
||||
#include "linkedlist.h"
|
||||
#include "circuit_library.h"
|
||||
|
||||
/* Xifan TANG: Spice support*/
|
||||
enum e_spice_tech_lib_type {
|
||||
|
@ -10,55 +11,6 @@ enum e_spice_tech_lib_type {
|
|||
SPICE_LIB_ACADEMIA
|
||||
};
|
||||
|
||||
enum spice_model_delay_type {
|
||||
SPICE_MODEL_DELAY_RISE,
|
||||
SPICE_MODEL_DELAY_FALL
|
||||
};
|
||||
|
||||
/*Struct for a SPICE model of a module*/
|
||||
enum e_spice_model_type {
|
||||
SPICE_MODEL_CHAN_WIRE,
|
||||
SPICE_MODEL_WIRE,
|
||||
SPICE_MODEL_MUX,
|
||||
SPICE_MODEL_LUT,
|
||||
SPICE_MODEL_FF,
|
||||
SPICE_MODEL_SRAM,
|
||||
SPICE_MODEL_HARDLOGIC,
|
||||
SPICE_MODEL_SCFF,
|
||||
SPICE_MODEL_IOPAD,
|
||||
SPICE_MODEL_INVBUF,
|
||||
SPICE_MODEL_PASSGATE,
|
||||
SPICE_MODEL_GATE
|
||||
};
|
||||
|
||||
enum e_spice_model_design_tech {
|
||||
SPICE_MODEL_DESIGN_CMOS,
|
||||
SPICE_MODEL_DESIGN_RRAM
|
||||
};
|
||||
|
||||
enum e_spice_model_structure {
|
||||
SPICE_MODEL_STRUCTURE_TREE,
|
||||
SPICE_MODEL_STRUCTURE_ONELEVEL,
|
||||
SPICE_MODEL_STRUCTURE_MULTILEVEL,
|
||||
SPICE_MODEL_STRUCTURE_CROSSBAR
|
||||
};
|
||||
|
||||
enum e_spice_model_buffer_type {
|
||||
SPICE_MODEL_BUF_INV,
|
||||
SPICE_MODEL_BUF_BUF
|
||||
};
|
||||
|
||||
enum e_spice_model_pass_gate_logic_type {
|
||||
SPICE_MODEL_PASS_GATE_TRANSMISSION,
|
||||
SPICE_MODEL_PASS_GATE_TRANSISTOR
|
||||
};
|
||||
|
||||
enum e_spice_model_gate_type {
|
||||
SPICE_MODEL_GATE_AND,
|
||||
SPICE_MODEL_GATE_OR,
|
||||
SPICE_MODEL_GATE_MUX2
|
||||
};
|
||||
|
||||
/* Transistor-level basic informations*/
|
||||
enum e_spice_trans_type {
|
||||
SPICE_TRANS_NMOS,
|
||||
|
@ -67,23 +19,6 @@ enum e_spice_trans_type {
|
|||
SPICE_TRANS_IO_PMOS
|
||||
};
|
||||
|
||||
enum e_wire_model_type {
|
||||
WIRE_MODEL_PIE,
|
||||
WIRE_MODEL_T
|
||||
};
|
||||
|
||||
enum e_spice_model_port_type {
|
||||
SPICE_MODEL_PORT_INPUT,
|
||||
SPICE_MODEL_PORT_OUTPUT,
|
||||
SPICE_MODEL_PORT_INOUT,
|
||||
SPICE_MODEL_PORT_CLOCK,
|
||||
SPICE_MODEL_PORT_SRAM,
|
||||
SPICE_MODEL_PORT_BL,
|
||||
SPICE_MODEL_PORT_BLB,
|
||||
SPICE_MODEL_PORT_WL,
|
||||
SPICE_MODEL_PORT_WLB
|
||||
};
|
||||
|
||||
/* For process corner */
|
||||
enum e_process_corner {
|
||||
BEST_CORNER,
|
||||
|
@ -91,14 +26,6 @@ enum e_process_corner {
|
|||
WORST_CORNER
|
||||
};
|
||||
|
||||
/* For SRAM */
|
||||
enum e_sram_orgz {
|
||||
SPICE_SRAM_STANDALONE, /* SRAMs are organized and accessed as standalone elements */
|
||||
SPICE_SRAM_SCAN_CHAIN, /* SRAMs are organized and accessed by a scan-chain */
|
||||
SPICE_SRAM_MEMORY_BANK, /* SRAMs are organized and accessed by memory bank */
|
||||
SPICE_SRAM_LOCAL_ENCODER /* SRAMs are organized and accessed by a local encoder */
|
||||
};
|
||||
|
||||
enum e_spice_accuracy_type {
|
||||
SPICE_FRAC, SPICE_ABS
|
||||
};
|
||||
|
@ -441,6 +368,8 @@ struct s_spice {
|
|||
t_spice_tech_lib tech_lib;
|
||||
int num_spice_model;
|
||||
t_spice_model* spice_models;
|
||||
/* Circuit library, object to replace the legacy spice_models */
|
||||
CircuitLibrary circuit_lib;
|
||||
};
|
||||
|
||||
/* Information needed to build a Multiplexer architecture*/
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
/**********************************************************
|
||||
* 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: string_token.cpp
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2019/08/09 | Xifan Tang | Created
|
||||
* +-------------------------------------+
|
||||
***********************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Member functions for StringToken class
|
||||
***********************************************************************/
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include "vtr_assert.h"
|
||||
|
||||
#include "string_token.h"
|
||||
|
||||
/************************************************************************
|
||||
* Constructors
|
||||
***********************************************************************/
|
||||
StringToken::StringToken (const std::string& data) {
|
||||
set_data(data);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public Accessors
|
||||
***********************************************************************/
|
||||
/* Get the data string */
|
||||
std::string StringToken::data() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
/* Split the string using a given delim */
|
||||
std::vector<std::string> StringToken::split(const std::string& delims) const {
|
||||
/* Return vector */
|
||||
std::vector<std::string> ret;
|
||||
|
||||
/* Get a writable char array */
|
||||
char* tmp = new char[data_.size() + 1];
|
||||
std::copy(data_.begin(), data_.end(), tmp);
|
||||
tmp[data_.size()] = '\0';
|
||||
/* Split using strtok */
|
||||
char* result = strtok(tmp, delims.c_str());
|
||||
while (NULL != result) {
|
||||
std::string result_str(result);
|
||||
/* Store the token */
|
||||
ret.push_back(result_str);
|
||||
/* Got to next */
|
||||
result = strtok(NULL, delims.c_str());
|
||||
}
|
||||
|
||||
/* Free the tmp */
|
||||
delete[] tmp;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Split the string using a given delim */
|
||||
std::vector<std::string> StringToken::split(const char& delim) const {
|
||||
/* Create delims */
|
||||
std::string delims(1, delim);
|
||||
|
||||
return split(delims);
|
||||
}
|
||||
|
||||
/* Split the string using a given delim */
|
||||
std::vector<std::string> StringToken::split(const char* delim) const {
|
||||
/* Create delims */
|
||||
std::string delims(delim);
|
||||
|
||||
return split(delims);
|
||||
}
|
||||
|
||||
/* Split the string using a given delim */
|
||||
std::vector<std::string> StringToken::split(const std::vector<char>& delims) const {
|
||||
/* Create delims */
|
||||
std::string delims_str;
|
||||
for (const auto& delim : delims) {
|
||||
delims_str.push_back(delim);
|
||||
}
|
||||
|
||||
return split(delims_str);
|
||||
}
|
||||
|
||||
|
||||
/* Split the string */
|
||||
std::vector<std::string> StringToken::split() {
|
||||
/* Add a default delim */
|
||||
if (true == delims_.empty()) {
|
||||
add_default_delim();
|
||||
}
|
||||
/* Create delims */
|
||||
std::string delims;
|
||||
for (const auto& delim : delims_) {
|
||||
delims.push_back(delim);
|
||||
}
|
||||
|
||||
return split(delims);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public Mutators
|
||||
***********************************************************************/
|
||||
void StringToken::set_data(const std::string& data) {
|
||||
data_ = data;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add a delima to the list */
|
||||
void StringToken::add_delim(const char& delim) {
|
||||
delims_.push_back(delim);
|
||||
}
|
||||
|
||||
/* Remove the string repeated at the beginning of string */
|
||||
void StringToken::ltrim(const std::string& sensitive_word) {
|
||||
size_t start = data_.find_first_not_of(sensitive_word);
|
||||
data_ = (start == std::string::npos) ? "" : data_.substr(start);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove the string repeated at the end of string */
|
||||
void StringToken::rtrim(const std::string& sensitive_word) {
|
||||
size_t end = data_.find_last_not_of(sensitive_word);
|
||||
data_ = (end == std::string::npos) ? "" : data_.substr(0, end + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
void StringToken::trim() {
|
||||
rtrim(" ");
|
||||
ltrim(" ");
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Internal Mutators
|
||||
***********************************************************************/
|
||||
void StringToken::add_default_delim() {
|
||||
VTR_ASSERT_SAFE(true == delims_.empty());
|
||||
delims_.push_back(' ');
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* End of file : string_token.cpp
|
||||
***********************************************************************/
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/**********************************************************
|
||||
* 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: string_token.h
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2019/08/09 | 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 STRING_TOKEN_H
|
||||
#define STRING_TOKEN_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 */
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file includes a tokenizer for string objects
|
||||
* It splits a string with given delima and return a vector of tokens
|
||||
* It can accept different delima in splitting strings
|
||||
***********************************************************************/
|
||||
|
||||
class StringToken {
|
||||
public : /* Constructors*/
|
||||
StringToken (const std::string& data);
|
||||
public : /* Public Accessors */
|
||||
std::string data() const;
|
||||
std::vector<std::string> split(const std::string& delims) const;
|
||||
std::vector<std::string> split(const char& delim) const;
|
||||
std::vector<std::string> split(const char* delim) const;
|
||||
std::vector<std::string> split(const std::vector<char>& delim) const;
|
||||
std::vector<std::string> split();
|
||||
public : /* Public Mutators */
|
||||
void set_data(const std::string& data);
|
||||
void add_delim(const char& delim);
|
||||
void ltrim(const std::string& sensitive_word);
|
||||
void rtrim(const std::string& sensitive_word);
|
||||
void trim();
|
||||
private : /* Private Mutators */
|
||||
void add_default_delim();
|
||||
private: /* Internal data */
|
||||
std::string data_; /* Lines to be splited */
|
||||
std::vector<char> delims_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/************************************************************************
|
||||
* End of file : string_token.h
|
||||
***********************************************************************/
|
||||
|
|
@ -1,3 +1,40 @@
|
|||
/**********************************************************
|
||||
* 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: read_xml_spice.c
|
||||
* Created by: Xifan Tang
|
||||
* Change history:
|
||||
* +-------------------------------------+
|
||||
* | Date | Author | Notes
|
||||
* +-------------------------------------+
|
||||
* | 2015/XX/XX | Xifan Tang | Created
|
||||
* +-------------------------------------+
|
||||
* | 2019/08/12 | Xifan Tang | Code construction for circuit library
|
||||
* +-------------------------------------+
|
||||
***********************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
|
@ -10,6 +47,9 @@
|
|||
#include "read_xml_spice_util.h"
|
||||
#include "read_xml_spice.h"
|
||||
|
||||
#include "circuit_library.h"
|
||||
#include "check_circuit_library.h"
|
||||
|
||||
/*********** Subroutines Declaration (only called in this source file) **********/
|
||||
static void ProcessSpiceMeasParams(ezxml_t Parent,
|
||||
t_spice_meas_params* meas_params);
|
||||
|
@ -768,6 +808,8 @@ static void ProcessSpiceModelPort(ezxml_t Node,
|
|||
||(SPICE_MODEL_PORT_WLB == port->type)) {
|
||||
port->inv_spice_model_name = my_strdup(FindProperty(Node, "inv_circuit_model_name", FALSE));
|
||||
ezxml_set_attr(Node, "inv_circuit_model_name", NULL);
|
||||
} else {
|
||||
port->inv_spice_model_name = NULL;
|
||||
}
|
||||
|
||||
/* Add a feature to enable/disable the configuration encoders for multiplexers */
|
||||
|
@ -914,6 +956,13 @@ static void ProcessSpiceModel(ezxml_t Parent,
|
|||
|
||||
/* Check the design technology settings*/
|
||||
Node = ezxml_child(Parent, "design_technology");
|
||||
/* Initialize */
|
||||
spice_model->design_tech_info.buffer_info = NULL;
|
||||
spice_model->design_tech_info.pass_gate_info = NULL;
|
||||
spice_model->design_tech_info.rram_info = NULL;
|
||||
spice_model->design_tech_info.mux_info = NULL;
|
||||
spice_model->design_tech_info.lut_info = NULL;
|
||||
spice_model->design_tech_info.gate_info = NULL;
|
||||
if (Node) {
|
||||
/* Specify if this spice_model is power gated or not*/
|
||||
spice_model->design_tech_info.power_gated = GetBooleanProperty(Node,"power_gated", FALSE, FALSE);
|
||||
|
@ -941,7 +990,7 @@ static void ProcessSpiceModel(ezxml_t Parent,
|
|||
} else if (0 == strcmp(FindProperty(Node,"type",TRUE),"rram")) {
|
||||
spice_model->design_tech = SPICE_MODEL_DESIGN_RRAM;
|
||||
/* Malloc RRAM info */
|
||||
spice_model->design_tech_info.rram_info = (t_spice_model_rram*)my_malloc(sizeof(t_spice_model_rram));
|
||||
spice_model->design_tech_info.rram_info = (t_spice_model_rram*)my_calloc(1, sizeof(t_spice_model_rram));
|
||||
/* Fill information */
|
||||
ProcessSpiceModelRRAM(Node, spice_model->design_tech_info.rram_info);
|
||||
} else {
|
||||
|
@ -955,7 +1004,7 @@ static void ProcessSpiceModel(ezxml_t Parent,
|
|||
spice_model->design_tech_info.mux_info = NULL;
|
||||
if (SPICE_MODEL_MUX == spice_model->type) {
|
||||
/* Malloc */
|
||||
spice_model->design_tech_info.mux_info = (t_spice_model_mux*)my_malloc(sizeof(t_spice_model_mux));
|
||||
spice_model->design_tech_info.mux_info = (t_spice_model_mux*)my_calloc(1, sizeof(t_spice_model_mux));
|
||||
/* Fill information */
|
||||
ProcessSpiceModelMUX(Node, spice_model, spice_model->design_tech_info.mux_info);
|
||||
}
|
||||
|
@ -964,11 +1013,11 @@ static void ProcessSpiceModel(ezxml_t Parent,
|
|||
spice_model->design_tech_info.lut_info = NULL;
|
||||
if (SPICE_MODEL_LUT == spice_model->type) {
|
||||
/* Malloc */
|
||||
spice_model->design_tech_info.lut_info = (t_spice_model_lut*)my_malloc(sizeof(t_spice_model_lut));
|
||||
spice_model->design_tech_info.lut_info = (t_spice_model_lut*)my_calloc(1, sizeof(t_spice_model_lut));
|
||||
/* Fill information */
|
||||
ProcessSpiceModelLUT(Node, spice_model->design_tech_info.lut_info);
|
||||
/* Malloc */
|
||||
spice_model->design_tech_info.mux_info = (t_spice_model_mux*)my_malloc(sizeof(t_spice_model_mux));
|
||||
spice_model->design_tech_info.mux_info = (t_spice_model_mux*)my_calloc(1, sizeof(t_spice_model_mux));
|
||||
/* Fill information */
|
||||
/* Default: tree, no const_inputs */
|
||||
spice_model->design_tech_info.mux_info->structure = SPICE_MODEL_STRUCTURE_TREE;
|
||||
|
@ -1041,7 +1090,7 @@ static void ProcessSpiceModel(ezxml_t Parent,
|
|||
spice_model->input_buffer = NULL;
|
||||
if (Node) {
|
||||
/*Alloc*/
|
||||
spice_model->input_buffer = (t_spice_model_buffer*)my_malloc(sizeof(t_spice_model_buffer));
|
||||
spice_model->input_buffer = (t_spice_model_buffer*)my_calloc(1, sizeof(t_spice_model_buffer));
|
||||
ProcessSpiceModelBuffer(Node,spice_model->input_buffer);
|
||||
FreeNode(Node);
|
||||
} else if (SPICE_MODEL_INVBUF != spice_model->type) {
|
||||
|
@ -1053,7 +1102,7 @@ static void ProcessSpiceModel(ezxml_t Parent,
|
|||
Node = ezxml_child(Parent, "output_buffer");
|
||||
spice_model->output_buffer = NULL;
|
||||
if (Node) {
|
||||
spice_model->output_buffer = (t_spice_model_buffer*)my_malloc(sizeof(t_spice_model_buffer));
|
||||
spice_model->output_buffer = (t_spice_model_buffer*)my_calloc(1, sizeof(t_spice_model_buffer));
|
||||
ProcessSpiceModelBuffer(Node,spice_model->output_buffer);
|
||||
FreeNode(Node);
|
||||
} else if (SPICE_MODEL_INVBUF != spice_model->type) {
|
||||
|
@ -1066,7 +1115,7 @@ static void ProcessSpiceModel(ezxml_t Parent,
|
|||
Node = ezxml_child(Parent, "pass_gate_logic");
|
||||
spice_model->pass_gate_logic = NULL;
|
||||
if (Node) {
|
||||
spice_model->pass_gate_logic = (t_spice_model_pass_gate_logic*)my_malloc(sizeof(t_spice_model_pass_gate_logic));
|
||||
spice_model->pass_gate_logic = (t_spice_model_pass_gate_logic*)my_calloc(1, sizeof(t_spice_model_pass_gate_logic));
|
||||
/* Find spice_model_name */
|
||||
spice_model->pass_gate_logic->spice_model_name = my_strdup(FindProperty(Node, "circuit_model_name", TRUE));
|
||||
ezxml_set_attr(Node, "circuit_model_name", NULL);
|
||||
|
@ -1082,7 +1131,7 @@ static void ProcessSpiceModel(ezxml_t Parent,
|
|||
/* Find All the ports*/
|
||||
spice_model->num_port = CountChildren(Parent, "port", 1);
|
||||
/*Alloc*/
|
||||
spice_model->ports = (t_spice_model_port*)my_malloc(spice_model->num_port*sizeof(t_spice_model_port));
|
||||
spice_model->ports = (t_spice_model_port*)my_calloc(spice_model->num_port, sizeof(t_spice_model_port));
|
||||
/* Assign each found spice model*/
|
||||
for (iport = 0; iport < spice_model->num_port; iport++) {
|
||||
Cur = FindFirstElement(Parent, "port", TRUE);
|
||||
|
@ -1091,8 +1140,9 @@ static void ProcessSpiceModel(ezxml_t Parent,
|
|||
}
|
||||
|
||||
/* Read in wire parameters */
|
||||
spice_model->wire_param = NULL;
|
||||
if ((SPICE_MODEL_CHAN_WIRE == spice_model->type)||(SPICE_MODEL_WIRE == spice_model->type)) {
|
||||
spice_model->wire_param = (t_spice_model_wire_param*)my_malloc(sizeof(t_spice_model_wire_param));
|
||||
spice_model->wire_param = (t_spice_model_wire_param*)my_calloc(1, sizeof(t_spice_model_wire_param));
|
||||
Node = ezxml_child(Parent, "wire_param");
|
||||
if (Node) {
|
||||
ProcessSpiceModelWireParam(Node,spice_model->wire_param);
|
||||
|
@ -1107,7 +1157,7 @@ static void ProcessSpiceModel(ezxml_t Parent,
|
|||
/* Find delay info */
|
||||
spice_model->num_delay_info = CountChildren(Parent, "delay_matrix", 0);
|
||||
/*Alloc*/
|
||||
spice_model->delay_info = (t_spice_model_delay_info*) my_malloc(spice_model->num_delay_info * sizeof(t_spice_model_delay_info));
|
||||
spice_model->delay_info = (t_spice_model_delay_info*) my_calloc(spice_model->num_delay_info, sizeof(t_spice_model_delay_info));
|
||||
/* Assign each found spice model*/
|
||||
for (i = 0; i < spice_model->num_delay_info; i++) {
|
||||
Cur = FindFirstElement(Parent, "delay_matrix", TRUE);
|
||||
|
@ -1508,6 +1558,238 @@ static void ProcessSpiceTechLibTransistors(ezxml_t Parent,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Build a circuit library based on the spice_models
|
||||
* This function does a quick conversion, so that we can proceed to update the downstream codes
|
||||
* TODO: The circuit library should be incrementally built during XML parsing
|
||||
* when the downstream is updated, the legacy spice_models will be removed
|
||||
*/
|
||||
static
|
||||
CircuitLibrary build_circuit_library(int num_spice_model, t_spice_model* spice_models) {
|
||||
CircuitLibrary circuit_lib;
|
||||
|
||||
/* Go spice_model by spice_model */
|
||||
for (int imodel = 0; imodel < num_spice_model; ++imodel) {
|
||||
/* Add a spice model to the circuit_lib */
|
||||
CircuitModelId model_id = circuit_lib.add_circuit_model();
|
||||
/* Fill fundamental attributes */
|
||||
/* Basic information*/
|
||||
circuit_lib.set_circuit_model_type(model_id, spice_models[imodel].type);
|
||||
|
||||
std::string name(spice_models[imodel].name);
|
||||
circuit_lib.set_circuit_model_name(model_id, name);
|
||||
|
||||
std::string prefix(spice_models[imodel].prefix);
|
||||
circuit_lib.set_circuit_model_prefix(model_id, prefix);
|
||||
|
||||
if (NULL != spice_models[imodel].verilog_netlist) {
|
||||
std::string verilog_netlist(spice_models[imodel].verilog_netlist);
|
||||
circuit_lib.set_circuit_model_verilog_netlist(model_id, verilog_netlist);
|
||||
}
|
||||
|
||||
if (NULL != spice_models[imodel].model_netlist) {
|
||||
std::string spice_netlist(spice_models[imodel].model_netlist);
|
||||
circuit_lib.set_circuit_model_spice_netlist(model_id, spice_netlist);
|
||||
}
|
||||
|
||||
circuit_lib.set_circuit_model_is_default(model_id, 0 != spice_models[imodel].is_default);
|
||||
|
||||
/* Verilog generatioin options */
|
||||
circuit_lib.set_circuit_model_dump_structural_verilog(model_id, TRUE == spice_models[imodel].dump_structural_verilog);
|
||||
|
||||
circuit_lib.set_circuit_model_dump_explicit_port_map(model_id, TRUE == spice_models[imodel].dump_explicit_port_map);
|
||||
|
||||
/* Design technology information */
|
||||
circuit_lib.set_circuit_model_design_tech_type(model_id, spice_models[imodel].design_tech);
|
||||
|
||||
circuit_lib.set_circuit_model_is_power_gated(model_id, TRUE == spice_models[imodel].design_tech_info.power_gated);
|
||||
|
||||
/* Buffer linking information */
|
||||
if (NULL != spice_models[imodel].input_buffer) {
|
||||
std::string model_name;
|
||||
if (NULL != spice_models[imodel].input_buffer->spice_model_name) {
|
||||
model_name = spice_models[imodel].input_buffer->spice_model_name;
|
||||
}
|
||||
circuit_lib.set_circuit_model_input_buffer(model_id, 0 != spice_models[imodel].input_buffer->exist, model_name);
|
||||
}
|
||||
if (NULL != spice_models[imodel].output_buffer) {
|
||||
std::string model_name;
|
||||
if (NULL != spice_models[imodel].output_buffer->spice_model_name) {
|
||||
model_name = spice_models[imodel].output_buffer->spice_model_name;
|
||||
}
|
||||
circuit_lib.set_circuit_model_output_buffer(model_id, 0 != spice_models[imodel].output_buffer->exist, model_name);
|
||||
}
|
||||
if (NULL != spice_models[imodel].lut_input_buffer) {
|
||||
std::string model_name;
|
||||
if (NULL != spice_models[imodel].lut_input_buffer->spice_model_name) {
|
||||
model_name = spice_models[imodel].lut_input_buffer->spice_model_name;
|
||||
}
|
||||
circuit_lib.set_circuit_model_lut_input_buffer(model_id, 0 != spice_models[imodel].lut_input_buffer->exist, model_name);
|
||||
}
|
||||
if (NULL != spice_models[imodel].lut_input_inverter) {
|
||||
std::string model_name;
|
||||
if (NULL != spice_models[imodel].lut_input_inverter->spice_model_name) {
|
||||
model_name = spice_models[imodel].lut_input_inverter->spice_model_name;
|
||||
}
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
circuit_lib.set_circuit_model_lut_intermediate_buffer(model_id, 0 != spice_models[imodel].lut_intermediate_buffer->exist, model_name);
|
||||
|
||||
std::string model_location_map;
|
||||
if (NULL != spice_models[imodel].lut_intermediate_buffer->location_map) {
|
||||
model_location_map = spice_models[imodel].lut_intermediate_buffer->location_map;
|
||||
}
|
||||
circuit_lib.set_circuit_model_lut_intermediate_buffer_location_map(model_id, model_location_map);
|
||||
}
|
||||
|
||||
/* Pass-gate-logic linking information */
|
||||
if (NULL != spice_models[imodel].pass_gate_logic) {
|
||||
std::string model_name(spice_models[imodel].pass_gate_logic->spice_model_name);
|
||||
circuit_lib.set_circuit_model_pass_gate_logic(model_id, model_name);
|
||||
}
|
||||
|
||||
/* Buffer information */
|
||||
if (NULL != spice_models[imodel].design_tech_info.buffer_info) {
|
||||
circuit_lib.set_buffer_type(model_id, spice_models[imodel].design_tech_info.buffer_info->type);
|
||||
circuit_lib.set_buffer_size(model_id, spice_models[imodel].design_tech_info.buffer_info->size);
|
||||
if (TRUE == spice_models[imodel].design_tech_info.buffer_info->tapered_buf) {
|
||||
circuit_lib.set_buffer_num_levels(model_id, spice_models[imodel].design_tech_info.buffer_info->tap_buf_level);
|
||||
circuit_lib.set_buffer_f_per_stage(model_id, spice_models[imodel].design_tech_info.buffer_info->f_per_stage);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass-gate information */
|
||||
if (NULL != spice_models[imodel].design_tech_info.pass_gate_info) {
|
||||
circuit_lib.set_pass_gate_logic_type(model_id, spice_models[imodel].design_tech_info.pass_gate_info->type);
|
||||
circuit_lib.set_pass_gate_logic_nmos_size(model_id, spice_models[imodel].design_tech_info.pass_gate_info->nmos_size);
|
||||
circuit_lib.set_pass_gate_logic_pmos_size(model_id, spice_models[imodel].design_tech_info.pass_gate_info->pmos_size);
|
||||
}
|
||||
|
||||
/* Multiplexer information */
|
||||
if (NULL != spice_models[imodel].design_tech_info.mux_info) {
|
||||
circuit_lib.set_mux_structure(model_id, spice_models[imodel].design_tech_info.mux_info->structure);
|
||||
circuit_lib.set_mux_num_levels(model_id, spice_models[imodel].design_tech_info.mux_info->mux_num_level);
|
||||
if (TRUE == spice_models[imodel].design_tech_info.mux_info->add_const_input) {
|
||||
circuit_lib.set_mux_const_input_value(model_id, spice_models[imodel].design_tech_info.mux_info->const_input_val);
|
||||
}
|
||||
circuit_lib.set_mux_use_local_encoder(model_id, TRUE == spice_models[imodel].design_tech_info.mux_info->local_encoder);
|
||||
circuit_lib.set_mux_use_advanced_rram_design(model_id, TRUE == spice_models[imodel].design_tech_info.mux_info->advanced_rram_design);
|
||||
}
|
||||
|
||||
/* LUT information */
|
||||
if (NULL != spice_models[imodel].design_tech_info.lut_info) {
|
||||
circuit_lib.set_lut_is_fracturable(model_id, TRUE == spice_models[imodel].design_tech_info.lut_info->frac_lut);
|
||||
}
|
||||
|
||||
/* Gate information */
|
||||
if (NULL != spice_models[imodel].design_tech_info.gate_info) {
|
||||
circuit_lib.set_gate_type(model_id, spice_models[imodel].design_tech_info.gate_info->type);
|
||||
}
|
||||
|
||||
/* RRAM information */
|
||||
if (NULL != spice_models[imodel].design_tech_info.rram_info) {
|
||||
circuit_lib.set_rram_rlrs(model_id, spice_models[imodel].design_tech_info.rram_info->ron);
|
||||
circuit_lib.set_rram_rhrs(model_id, spice_models[imodel].design_tech_info.rram_info->roff);
|
||||
circuit_lib.set_rram_wprog_set_nmos(model_id, spice_models[imodel].design_tech_info.rram_info->wprog_set_nmos);
|
||||
circuit_lib.set_rram_wprog_set_pmos(model_id, spice_models[imodel].design_tech_info.rram_info->wprog_set_pmos);
|
||||
circuit_lib.set_rram_wprog_reset_nmos(model_id, spice_models[imodel].design_tech_info.rram_info->wprog_reset_nmos);
|
||||
circuit_lib.set_rram_wprog_reset_pmos(model_id, spice_models[imodel].design_tech_info.rram_info->wprog_reset_pmos);
|
||||
}
|
||||
|
||||
/* Delay information */
|
||||
for (int idelay = 0; idelay < spice_models[imodel].num_delay_info; ++idelay) {
|
||||
circuit_lib.add_delay_info(model_id, spice_models[imodel].delay_info[idelay].type);
|
||||
|
||||
std::string in_port_names(spice_models[imodel].delay_info[idelay].in_port_name);
|
||||
circuit_lib.set_delay_in_port_names(model_id, spice_models[imodel].delay_info[idelay].type, in_port_names);
|
||||
|
||||
std::string out_port_names(spice_models[imodel].delay_info[idelay].out_port_name);
|
||||
circuit_lib.set_delay_out_port_names(model_id, spice_models[imodel].delay_info[idelay].type, out_port_names);
|
||||
|
||||
std::string delay_values(spice_models[imodel].delay_info[idelay].value);
|
||||
circuit_lib.set_delay_values(model_id, spice_models[imodel].delay_info[idelay].type, delay_values);
|
||||
}
|
||||
|
||||
/* Wire parameters */
|
||||
if (NULL != spice_models[imodel].wire_param) {
|
||||
circuit_lib.set_wire_type(model_id, spice_models[imodel].wire_param->type);
|
||||
circuit_lib.set_wire_r(model_id, spice_models[imodel].wire_param->res_val);
|
||||
circuit_lib.set_wire_c(model_id, spice_models[imodel].wire_param->cap_val);
|
||||
circuit_lib.set_wire_num_levels(model_id, spice_models[imodel].wire_param->level);
|
||||
}
|
||||
|
||||
/* Ports */
|
||||
for (int iport = 0; iport < spice_models[imodel].num_port; ++iport) {
|
||||
CircuitPortId port_id = circuit_lib.add_circuit_model_port(model_id);
|
||||
/* Fill fundamental attributes */
|
||||
circuit_lib.set_port_type(model_id, port_id, spice_models[imodel].ports[iport].type);
|
||||
|
||||
circuit_lib.set_port_size(model_id, port_id, spice_models[imodel].ports[iport].size);
|
||||
|
||||
std::string port_prefix(spice_models[imodel].ports[iport].prefix);
|
||||
circuit_lib.set_port_prefix(model_id, port_id, port_prefix);
|
||||
|
||||
std::string port_lib_name(spice_models[imodel].ports[iport].lib_name);
|
||||
circuit_lib.set_port_lib_name(model_id, port_id, port_lib_name);
|
||||
|
||||
if (NULL != spice_models[imodel].ports[iport].inv_prefix) {
|
||||
std::string port_inv_prefix(spice_models[imodel].ports[iport].inv_prefix);
|
||||
circuit_lib.set_port_inv_prefix(model_id, port_id, port_inv_prefix);
|
||||
}
|
||||
|
||||
circuit_lib.set_port_default_value(model_id, port_id, spice_models[imodel].ports[iport].default_val);
|
||||
|
||||
circuit_lib.set_port_is_mode_select(model_id, port_id, TRUE == spice_models[imodel].ports[iport].mode_select);
|
||||
circuit_lib.set_port_is_global(model_id, port_id, TRUE == spice_models[imodel].ports[iport].is_global);
|
||||
circuit_lib.set_port_is_reset(model_id, port_id, TRUE == spice_models[imodel].ports[iport].is_reset);
|
||||
circuit_lib.set_port_is_set(model_id, port_id, TRUE == spice_models[imodel].ports[iport].is_set);
|
||||
circuit_lib.set_port_is_config_enable(model_id, port_id, TRUE == spice_models[imodel].ports[iport].is_config_enable);
|
||||
circuit_lib.set_port_is_prog(model_id, port_id, TRUE == spice_models[imodel].ports[iport].is_prog);
|
||||
|
||||
if (NULL != spice_models[imodel].ports[iport].spice_model_name) {
|
||||
std::string port_model_name(spice_models[imodel].ports[iport].spice_model_name);
|
||||
circuit_lib.set_port_circuit_model_name(model_id, port_id, port_model_name);
|
||||
}
|
||||
|
||||
if (NULL != spice_models[imodel].ports[iport].inv_spice_model_name) {
|
||||
std::string port_inv_model_name(spice_models[imodel].ports[iport].inv_spice_model_name);
|
||||
circuit_lib.set_port_inv_circuit_model_name(model_id, port_id, port_inv_model_name);
|
||||
}
|
||||
|
||||
if (NULL != spice_models[imodel].ports[iport].tri_state_map) {
|
||||
std::string port_tri_state_map(spice_models[imodel].ports[iport].tri_state_map);
|
||||
circuit_lib.set_port_tri_state_map(model_id, port_id, port_tri_state_map);
|
||||
}
|
||||
|
||||
if (SPICE_MODEL_LUT == spice_models[imodel].type) {
|
||||
circuit_lib.set_port_lut_frac_level(model_id, port_id, spice_models[imodel].ports[iport].lut_frac_level);
|
||||
|
||||
std::vector<size_t> port_lut_output_mask;
|
||||
for (int ipin = 0; ipin < spice_models[imodel].ports[iport].size; ++ipin) {
|
||||
port_lut_output_mask.push_back(spice_models[imodel].ports[iport].lut_output_mask[ipin]);
|
||||
}
|
||||
circuit_lib.set_port_lut_output_mask(model_id, port_id, port_lut_output_mask);
|
||||
}
|
||||
|
||||
if (SPICE_MODEL_PORT_SRAM == spice_models[imodel].ports[iport].type) {
|
||||
circuit_lib.set_port_sram_orgz(model_id, port_id, spice_models[imodel].ports[iport].organization);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Build circuit_model links */
|
||||
circuit_lib.build_circuit_model_links();
|
||||
|
||||
/* Build timing graph */
|
||||
circuit_lib.build_timing_graphs();
|
||||
|
||||
return circuit_lib;
|
||||
}
|
||||
|
||||
/* Process the SPICE Settings*/
|
||||
void ProcessSpiceSettings(ezxml_t Parent,
|
||||
t_spice* spice) {
|
||||
|
@ -1541,6 +1823,9 @@ void ProcessSpiceSettings(ezxml_t Parent,
|
|||
assert(imodel == spice->num_spice_model);
|
||||
FreeNode(Node);
|
||||
}
|
||||
/* Build the CircuitLibrary here from spice_models */
|
||||
spice->circuit_lib = build_circuit_library(spice->num_spice_model, spice->spice_models);
|
||||
check_circuit_library(spice->circuit_lib);
|
||||
|
||||
/* Check codes*/
|
||||
check_tech_lib(spice->tech_lib, spice->num_spice_model, spice->spice_models);
|
||||
|
@ -1549,4 +1834,6 @@ void ProcessSpiceSettings(ezxml_t Parent,
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* End of file : read_xml_spice.c
|
||||
***********************************************************************/
|
||||
|
|
|
@ -411,3 +411,7 @@ class DeviceRRGSB {
|
|||
|
||||
#endif
|
||||
|
||||
/************************************************************************
|
||||
* End of file : rr_blocks.h
|
||||
***********************************************************************/
|
||||
|
||||
|
|
Loading…
Reference in New Issue