adding mux graph data structures

This commit is contained in:
tangxifan 2019-08-17 14:37:22 -06:00
parent 0b8473e960
commit 638969c3c9
8 changed files with 255 additions and 8 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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
};

View File

@ -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
*************************************************/

View File

@ -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 <vector>
#include "mux_graph_fwd.h"
#include "circuit_library.h"
/* Strong Ids for MUXes */
struct mux_id_tag;
typedef vtr::StrongId<mux_id_tag> 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<size_t> node_ids_; /* Unique ids for each node */
std::vector<size_t> node_levels_; /* at which level, each node belongs to */
@ -35,14 +46,14 @@ class MuxGraph {
std::vector<size_t> sram_ids_; /* ids of SRAMs (configuration memories) */
/* fast look-up */
typedef std::vector<std::vector<std::vector>>> NodeLookup;
typedef std::vector<std::vector<std::vector<size_t>>> NodeLookup;
mutable NodeLookup node_lookup_; /* [num_levels][num_branches][num_nodes_per_branch] */
};
class MuxLib {
class MuxLibrary {
private: /* Internal data */
vtr::vector<MuxId, MuxGraph> mux_graphs_; /* Graphs describing MUX internal structures */
vtr::vector<MuxId, CircuitModelId> circuit_model_ids_; /* ids in the circuit library, each MUX graph belongs to*/
}
};
#endif

View File

@ -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<mux_id_tag> MuxId;
class MuxGraph;
class MuxLibrary;
#endif

View File

@ -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);
}

View File

@ -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