diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp b/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp index 4da76e417..2230680b6 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library.cpp @@ -266,6 +266,34 @@ enum e_spice_model_structure CircuitLibrary::mux_structure(const CircuitModelId& return mux_structure_[circuit_model_id]; } +/* Return if additional constant inputs are required for a circuit model + * Only applicable for MUX circuit model + */ +bool CircuitLibrary::mux_add_const_input(const CircuitModelId& circuit_model_id) const { + /* validate the circuit_model_id */ + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); + /* validate the circuit model type is MUX */ + VTR_ASSERT( (SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)) + || (SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)) ); + /* A -1 value for the const values means there is no const inputs */ + return ( size_t(-1) != mux_const_input_values_[circuit_model_id] ); +} + +/* Return if additional constant inputs are required for a circuit model + * Only applicable for MUX circuit model + */ +size_t CircuitLibrary::mux_const_input_value(const CircuitModelId& circuit_model_id) const { + /* validate the circuit_model_id */ + VTR_ASSERT(valid_circuit_model_id(circuit_model_id)); + /* validate the circuit model type is MUX */ + VTR_ASSERT( (SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)) + || (SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)) ); + /* A -1 value for the const values means there is no const inputs */ + /* A 0 value for the const values means it is logic 0 */ + /* A 1 value for the const values means it is logic 1 */ + return mux_const_input_values_[circuit_model_id]; +} + /************************************************************************ * Public Accessors : Basic data query on Circuit Porst ***********************************************************************/ @@ -1158,6 +1186,8 @@ void CircuitLibrary::set_mux_const_input_value(const CircuitModelId& circuit_mod /* validate that the type of this circuit_model should be MUX or LUT */ VTR_ASSERT( (SPICE_MODEL_MUX == circuit_model_type(circuit_model_id)) || (SPICE_MODEL_LUT == circuit_model_type(circuit_model_id)) ); + /* validate the const input values */ + VTR_ASSERT( valid_mux_const_input_value(const_input_value) ); mux_const_input_values_[circuit_model_id] = const_input_value; return; } @@ -1700,6 +1730,18 @@ bool CircuitLibrary::valid_circuit_edge_id(const CircuitModelId& circuit_model_i return ( size_t(circuit_edge_id) < edge_ids_[circuit_model_id].size() ) && ( circuit_edge_id == edge_ids_[circuit_model_id][circuit_edge_id] ); } +/* Validate the value of constant input + * A -1 value for the const values means there is no const inputs + * A 0 value for the const values means it is logic 0 + * A 1 value for the const values means it is logic 1 + * Others are invalid + */ +bool CircuitLibrary::valid_mux_const_input_value(const size_t& const_input_value) const { + return ( (size_t(-1) == const_input_value) + || (0 == const_input_value) + || (1 == const_input_value) ); +} + /* Invalidators */ /* Empty fast lookup for circuit_models*/ void CircuitLibrary::invalidate_circuit_model_lookup() const { diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_library.h b/vpr7_x2p/libarchfpga/SRC/circuit_library.h index 1717bb60f..6bfcb5a92 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_library.h +++ b/vpr7_x2p/libarchfpga/SRC/circuit_library.h @@ -242,6 +242,8 @@ class CircuitLibrary { bool is_output_buffered(const CircuitModelId& circuit_model_id) const; bool is_lut_intermediate_buffered(const CircuitModelId& circuit_model_id) const; enum e_spice_model_structure mux_structure(const CircuitModelId& circuit_model_id) const; + bool mux_add_const_input(const CircuitModelId& circuit_model_id) const; + size_t mux_const_input_value(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; @@ -457,6 +459,7 @@ class CircuitLibrary { 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; + bool valid_mux_const_input_value(const size_t& const_input_value) const; /* Invalidators */ void invalidate_circuit_model_lookup() const; void invalidate_circuit_model_port_lookup(const CircuitModelId& circuit_model_id) const; diff --git a/vpr7_x2p/libarchfpga/SRC/circuit_types.h b/vpr7_x2p/libarchfpga/SRC/circuit_types.h index a2b86f38f..eff20f141 100644 --- a/vpr7_x2p/libarchfpga/SRC/circuit_types.h +++ b/vpr7_x2p/libarchfpga/SRC/circuit_types.h @@ -101,6 +101,7 @@ enum e_spice_model_buffer_type { enum e_spice_model_pass_gate_logic_type { SPICE_MODEL_PASS_GATE_TRANSMISSION, SPICE_MODEL_PASS_GATE_TRANSISTOR, + SPICE_MODEL_PASS_GATE_RRAM, /* RRAM can be treated as a special type of pass-gate logic */ NUM_CIRCUIT_MODEL_PASS_GATE_TYPES }; diff --git a/vpr7_x2p/vpr/SRC/device/mux_graph.cpp b/vpr7_x2p/vpr/SRC/device/mux_graph.cpp new file mode 100644 index 000000000..8873fd969 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/device/mux_graph.cpp @@ -0,0 +1,79 @@ +/************************************************** + * This file includes member functions for the + * data structures in mux_graph.h + *************************************************/ +#include "util.h" +#include "vtr_assert.h" +#include "mux_utils.h" +#include "mux_graph.h" + +/************************************************** + * Member functions for the class MuxGraph + *************************************************/ + +/************************************************** + * Constructor + *************************************************/ + +/* Create an object based on a Circuit Model which is MUX */ +MuxGraph::MuxGraph(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const size_t& mux_size) { + /* Build the graph for a given multiplexer model */ + build_mux_graph(circuit_lib, circuit_model, mux_size); +} + +/************************************************** + * Private mutators + *************************************************/ + +/* Build the graph for a given multiplexer model */ +void MuxGraph::build_mux_graph(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const size_t& mux_size) { + /* Make sure this model is a MUX */ + VTR_ASSERT(SPICE_MODEL_MUX == circuit_lib.circuit_model_type(circuit_model)); + + /* Make sure mux_size is valid */ + VTR_ASSERT(valid_mux_implementation_num_inputs(mux_size)); + + /* Depends on the mux size, the actual multiplexer structure may change! */ + + /* Branch on multiplexer structures, leading to different building strategies */ + switch (circuit_lib.mux_structure(circuit_model)) { + case SPICE_MODEL_STRUCTURE_ONELEVEL: + break; + case SPICE_MODEL_STRUCTURE_MULTILEVEL: + break; + case SPICE_MODEL_STRUCTURE_TREE: + break; + default: + vpr_printf(TIO_MESSAGE_ERROR, + "(File:%s, [LINE%d]) Invalid multiplexer structure for circuit model (name=%s)!\n", + __FILE__, __LINE__, circuit_lib.circuit_model_name(circuit_model)); + exit(1); + } +} + +/************************************************** + * Private validartors + *************************************************/ + +/* valid ids */ +bool MuxGraph::valid_node_id(const size_t& node_id) const { + return (node_id < node_ids_.size()); +} + + +/************************************************** + * End of Member functions for the class MuxGraph + *************************************************/ + +/************************************************** + * Member functions for the class MuxLibrary + *************************************************/ + +/************************************************** + * End of Member functions for the class MuxLibrary + *************************************************/ + diff --git a/vpr7_x2p/vpr/SRC/device/mux_graph.h b/vpr7_x2p/vpr/SRC/device/mux_graph.h index 1b57a9d58..8ded42e62 100644 --- a/vpr7_x2p/vpr/SRC/device/mux_graph.h +++ b/vpr7_x2p/vpr/SRC/device/mux_graph.h @@ -1,5 +1,5 @@ /************************************************** - * This file include a data structure to describe + * This file includes a data structure to describe * the internal structure of a multiplexer * using a generic graph representation *************************************************/ @@ -8,12 +8,9 @@ #define MUX_ARCH_H #include +#include "mux_graph_fwd.h" #include "circuit_library.h" -/* Strong Ids for MUXes */ -struct mux_id_tag; -typedef vtr::StrongId MuxId; - class MuxGraph { private: /* data types used only in this class */ enum e_mux_graph_node_type { @@ -21,6 +18,20 @@ class MuxGraph { MUX_INTERNAL_NODE, MUX_OUTPUT_NODE }; + public: /* Constructors */ + /* Create an object based on a Circuit Model which is MUX */ + MuxGraph(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const size_t& mux_size); + public: /* Public accessors */ + private: /* Private mutators*/ + /* Build the graph for a given multiplexer model */ + void build_mux_graph(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const size_t& mux_size); + private: /* Private validators */ + /* valid ids */ + bool valid_node_id(const size_t& node_id) const; private: /* Internal data */ std::vector node_ids_; /* Unique ids for each node */ std::vector node_levels_; /* at which level, each node belongs to */ @@ -35,14 +46,14 @@ class MuxGraph { std::vector sram_ids_; /* ids of SRAMs (configuration memories) */ /* fast look-up */ - typedef std::vector>> NodeLookup; + typedef std::vector>> NodeLookup; mutable NodeLookup node_lookup_; /* [num_levels][num_branches][num_nodes_per_branch] */ }; -class MuxLib { +class MuxLibrary { private: /* Internal data */ vtr::vector mux_graphs_; /* Graphs describing MUX internal structures */ vtr::vector circuit_model_ids_; /* ids in the circuit library, each MUX graph belongs to*/ -} +}; #endif diff --git a/vpr7_x2p/vpr/SRC/device/mux_graph_fwd.h b/vpr7_x2p/vpr/SRC/device/mux_graph_fwd.h new file mode 100644 index 000000000..bf6fd3a5b --- /dev/null +++ b/vpr7_x2p/vpr/SRC/device/mux_graph_fwd.h @@ -0,0 +1,16 @@ +/************************************************** + * This file includes only declarations for + * the data structures to describe multiplexer structures + * Please refer to mux_graph.h for more details + *************************************************/ +#ifndef MUX_GRAPH_FWD_H +#define MUX_GRAPH_FWD_H + +/* Strong Ids for MUXes */ +struct mux_id_tag; +typedef vtr::StrongId MuxId; + +class MuxGraph; +class MuxLibrary; + +#endif diff --git a/vpr7_x2p/vpr/SRC/device/mux_utils.cpp b/vpr7_x2p/vpr/SRC/device/mux_utils.cpp new file mode 100644 index 000000000..686e2d1f9 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/device/mux_utils.cpp @@ -0,0 +1,73 @@ +/************************************************** + * This file includes a series of most utilized functions + * that are used to implement a multiplexer + *************************************************/ + +#include "vtr_assert.h" +#include "mux_utils.h" + +/* Validate the number of inputs for a multiplexer implementation, + * the minimum supported size is 2 + * otherwise, there is no need for a MUX + */ +bool valid_mux_implementation_num_inputs(const size_t& mux_size) { + return (2 <= mux_size); +} + +/************************************************** + * Find the actual number of inputs for a multiplexer implementation + * 1. if there are no requirements on constant inputs, mux_size is the actual one + * 2. if there exist constant inputs, mux_size should plus 1 + *************************************************/ +size_t find_mux_implementation_num_inputs(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const size_t& mux_size) { + /* Should be either MUX or LUT + * LUTs do have an tree-like MUX, but there is no need for a constant input! + */ + VTR_ASSERT ((SPICE_MODEL_MUX == circuit_lib.circuit_model_type(circuit_model)) + || (SPICE_MODEL_LUT == circuit_lib.circuit_model_type(circuit_model)) ); + + if (SPICE_MODEL_LUT == circuit_lib.circuit_model_type(circuit_model)) { + return mux_size; + } + + if (true == circuit_lib.mux_add_const_input(circuit_model)) { + return mux_size + 1; + } + return mux_size; +} + +/************************************************** + * Find the structure for a multiplexer implementation + * 1. In most cases, the structure should follow the + * mux_structure defined by users in the CircuitLibrary + * 2. However, a special case may apply when mux_size is 2 + * In such case, we will force a TREE structure + * regardless of users' specification as this is the + * most efficient structure + *************************************************/ +enum e_spice_model_structure find_mux_implementation_structure(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const size_t& mux_size) { + /* Get the number of inputs */ + size_t impl_mux_size = find_mux_implementation_num_inputs(circuit_lib, circuit_model, mux_size); + /* Ensure the mux size is valid ! */ + VTR_ASSERT(valid_mux_implementation_num_inputs(impl_mux_size)); + + /* Branch on the mux sizes */ + if (2 == impl_mux_size) { + /* Tree-like is the best structure of CMOS MUX2 */ + if (SPICE_MODEL_DESIGN_CMOS == circuit_lib.design_tech_type(circuit_model)) { + return SPICE_MODEL_STRUCTURE_TREE; + } + VTR_ASSERT_SAFE(SPICE_MODEL_DESIGN_RRAM == circuit_lib.design_tech_type(circuit_model)); + /* One-level is the best structure of RRAM MUX2 */ + return SPICE_MODEL_STRUCTURE_ONELEVEL; + } + + return circuit_lib.mux_structure(circuit_model); +} + + + diff --git a/vpr7_x2p/vpr/SRC/device/mux_utils.h b/vpr7_x2p/vpr/SRC/device/mux_utils.h new file mode 100644 index 000000000..feba04571 --- /dev/null +++ b/vpr7_x2p/vpr/SRC/device/mux_utils.h @@ -0,0 +1,22 @@ +/************************************************** + * This file includes only declaration for the + * functions in mux_utils.c + * Please refer to the source file for more details + *************************************************/ +#ifndef MUX_UTILS_H +#define MUX_UTILS_H + +#include "circuit_library.h" + +bool valid_mux_implementation_num_inputs(const size_t& mux_size); + +size_t find_mux_implementation_num_inputs(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const size_t& mux_size); + + +enum e_spice_model_structure find_mux_implementation_structure(const CircuitLibrary& circuit_lib, + const CircuitModelId& circuit_model, + const size_t& mux_size); + +#endif