add timing graph builder for circuit models
This commit is contained in:
parent
c8d04c4f00
commit
6b5ac2e1ef
|
@ -33,6 +33,7 @@
|
|||
* +-------------------------------------+
|
||||
***********************************************************************/
|
||||
|
||||
#include <numeric>
|
||||
#include <algorithm>
|
||||
|
||||
#include "vtr_assert.h"
|
||||
|
@ -58,6 +59,49 @@ CircuitLibrary::circuit_port_range CircuitLibrary::ports(const CircuitModelId& c
|
|||
return vtr::make_range(port_ids_[circuit_model_id].begin(), port_ids_[circuit_model_id].end());
|
||||
}
|
||||
|
||||
/* Create a vector for all the ports whose directionality is input
|
||||
* This includes all the ports other than whose types are OUPUT or INOUT
|
||||
*/
|
||||
std::vector<CircuitPortId> CircuitLibrary::input_ports(const CircuitModelId& circuit_model_id) const {
|
||||
std::vector<CircuitPortId> input_ports;
|
||||
for (const auto& port_id : ports(circuit_model_id)) {
|
||||
/* We skip output ports */
|
||||
if ( (SPICE_MODEL_PORT_OUTPUT == port_type(circuit_model_id, port_id))
|
||||
|| (SPICE_MODEL_PORT_INOUT == port_type(circuit_model_id, port_id)) ) {
|
||||
continue;
|
||||
}
|
||||
input_ports.push_back(port_id);
|
||||
}
|
||||
return input_ports;
|
||||
}
|
||||
|
||||
/* Create a vector for all the ports whose directionality is output
|
||||
* This includes all the ports whose types are OUPUT or INOUT
|
||||
*/
|
||||
std::vector<CircuitPortId> CircuitLibrary::output_ports(const CircuitModelId& circuit_model_id) const {
|
||||
std::vector<CircuitPortId> output_ports;
|
||||
for (const auto& port_id : ports(circuit_model_id)) {
|
||||
/* We skip output ports */
|
||||
if ( (SPICE_MODEL_PORT_OUTPUT != port_type(circuit_model_id, port_id))
|
||||
&& (SPICE_MODEL_PORT_INOUT != port_type(circuit_model_id, port_id)) ) {
|
||||
continue;
|
||||
}
|
||||
output_ports.push_back(port_id);
|
||||
}
|
||||
return output_ports;
|
||||
}
|
||||
|
||||
/* Create a vector for the pin indices, which is bounded by the size of a port
|
||||
* Start from 0 and end to port_size - 1
|
||||
*/
|
||||
std::vector<size_t> CircuitLibrary::pins(const CircuitModelId& circuit_model_id, const CircuitPortId& circuit_port_id) const {
|
||||
std::vector<size_t> pin_range(port_size(circuit_model_id, circuit_port_id));
|
||||
/* Create a vector, with sequentially increasing numbers */
|
||||
std::iota(pin_range.begin(), pin_range.end(), 0);
|
||||
return pin_range;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Public Accessors : Basic data query on Circuit Models
|
||||
***********************************************************************/
|
||||
|
@ -356,9 +400,9 @@ CircuitModelId CircuitLibrary::add_circuit_model() {
|
|||
edge_ids_.emplace_back();
|
||||
port_in_edge_ids_.emplace_back();
|
||||
port_out_edge_ids_.emplace_back();
|
||||
edge_src_ports_.emplace_back();
|
||||
edge_src_port_ids_.emplace_back();
|
||||
edge_src_pin_ids_.emplace_back();
|
||||
edge_sink_ports_.emplace_back();
|
||||
edge_sink_port_ids_.emplace_back();
|
||||
edge_sink_pin_ids_.emplace_back();
|
||||
edge_trise_.emplace_back();
|
||||
edge_tfall_.emplace_back();
|
||||
|
@ -594,6 +638,10 @@ CircuitPortId CircuitLibrary::add_circuit_model_port(const CircuitModelId& circu
|
|||
port_lut_output_masks_[circuit_model_id].emplace_back();
|
||||
port_sram_orgz_[circuit_model_id].push_back(NUM_CIRCUIT_MODEL_SRAM_ORGZ_TYPES);
|
||||
|
||||
/* For timing graphs */
|
||||
port_in_edge_ids_[circuit_model_id].emplace_back();
|
||||
port_out_edge_ids_[circuit_model_id].emplace_back();
|
||||
|
||||
return circuit_port_id;
|
||||
}
|
||||
|
||||
|
@ -1229,6 +1277,25 @@ void CircuitLibrary::build_circuit_model_links() {
|
|||
|
||||
/* Build the timing graph for a circuit models*/
|
||||
void CircuitLibrary::build_circuit_model_timing_graph(const CircuitModelId& circuit_model_id) {
|
||||
/* Now we start allocating a timing graph
|
||||
* Add outgoing edges for each input pin of the circuit model
|
||||
*/
|
||||
for (auto& from_port_id : input_ports(circuit_model_id)) {
|
||||
/* Add edges for each input pin */
|
||||
for (auto& from_pin_id : pins(circuit_model_id, from_port_id)) {
|
||||
/* We should walk through output pins here */
|
||||
for (auto& to_port_id : output_ports(circuit_model_id)) {
|
||||
for (auto& to_pin_id : pins(circuit_model_id, to_port_id)) {
|
||||
/* Skip self-loops */
|
||||
if (from_port_id == to_port_id) {
|
||||
continue;
|
||||
}
|
||||
/* Add an edge to bridge the from_pin_id and to_pin_id */
|
||||
add_edge(circuit_model_id, from_port_id, from_pin_id, to_port_id, to_pin_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1236,11 +1303,77 @@ void CircuitLibrary::build_circuit_model_timing_graph(const CircuitModelId& circ
|
|||
void CircuitLibrary::build_timing_graphs() {
|
||||
/* Walk through each circuit model, build timing graph one by one */
|
||||
for (auto& circuit_model_id : circuit_models()) {
|
||||
/* Free the timing graph if it already exists, we will rebuild one */
|
||||
invalidate_circuit_model_timing_graph(circuit_model_id);
|
||||
build_circuit_model_timing_graph(circuit_model_id);
|
||||
/* Annotate timing information */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Internal mutators: build timing graphs
|
||||
***********************************************************************/
|
||||
/* Add an edge between two pins of two ports, and assign an default timing value */
|
||||
void CircuitLibrary::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) {
|
||||
/* validate the circuit_model_id */
|
||||
VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id));
|
||||
|
||||
/* Create an edge in the edge id list */
|
||||
CircuitEdgeId edge_id = CircuitEdgeId(edge_ids_[circuit_model_id].size());
|
||||
/* Expand the edge list */
|
||||
edge_ids_[circuit_model_id].push_back(edge_id);
|
||||
|
||||
/* Initialize other attributes */
|
||||
|
||||
/* Update the list of incoming edges for to_port */
|
||||
/* Resize upon need */
|
||||
if (to_pin >= port_in_edge_ids_[circuit_model_id][to_port].size()) {
|
||||
port_in_edge_ids_[circuit_model_id][to_port].resize(to_pin + 1);
|
||||
}
|
||||
port_in_edge_ids_[circuit_model_id][to_port][to_pin] = edge_id;
|
||||
|
||||
/* Update the list of outgoing edges for from_port */
|
||||
/* Resize upon need */
|
||||
if (from_pin >= port_out_edge_ids_[circuit_model_id][from_port].size()) {
|
||||
port_out_edge_ids_[circuit_model_id][from_port].resize(from_pin + 1);
|
||||
}
|
||||
port_out_edge_ids_[circuit_model_id][from_port][from_pin] = edge_id;
|
||||
|
||||
/* Update source ports and pins of the edge */
|
||||
edge_src_port_ids_[circuit_model_id].push_back(from_port);
|
||||
edge_src_pin_ids_[circuit_model_id].push_back(from_pin);
|
||||
|
||||
/* Update sink ports and pins of the edge */
|
||||
edge_sink_port_ids_[circuit_model_id].push_back(to_port);
|
||||
edge_sink_pin_ids_[circuit_model_id].push_back(to_pin);
|
||||
|
||||
/* Give a default value for timing values */
|
||||
edge_trise_[circuit_model_id].push_back(0);
|
||||
edge_tfall_[circuit_model_id].push_back(0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void CircuitLibrary::set_edge_trise(const CircuitModelId& circuit_model_id, const CircuitEdgeId& circuit_edge_id, const float& trise) {
|
||||
/* validate the circuit_edge_id */
|
||||
VTR_ASSERT_SAFE(valid_circuit_edge_id(circuit_model_id, circuit_edge_id));
|
||||
|
||||
edge_trise_[circuit_model_id][circuit_edge_id] = trise;
|
||||
return;
|
||||
}
|
||||
|
||||
void CircuitLibrary::set_edge_tfall(const CircuitModelId& circuit_model_id, const CircuitEdgeId& circuit_edge_id, const float& tfall) {
|
||||
/* validate the circuit_edge_id */
|
||||
VTR_ASSERT_SAFE(valid_circuit_edge_id(circuit_model_id, circuit_edge_id));
|
||||
|
||||
edge_tfall_[circuit_model_id][circuit_edge_id] = tfall;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Internal mutators: build fast look-ups
|
||||
***********************************************************************/
|
||||
|
@ -1290,7 +1423,6 @@ void CircuitLibrary::build_circuit_model_port_lookup(const CircuitModelId& circu
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Internal invalidators/validators
|
||||
***********************************************************************/
|
||||
|
@ -1311,6 +1443,12 @@ bool CircuitLibrary::valid_delay_type(const CircuitModelId& circuit_model_id, co
|
|||
return ( size_t(delay_type) < delay_types_[circuit_model_id].size() ) && ( delay_type == delay_types_[circuit_model_id][size_t(delay_type)] );
|
||||
}
|
||||
|
||||
bool CircuitLibrary::valid_circuit_edge_id(const CircuitModelId& circuit_model_id, const CircuitEdgeId& circuit_edge_id) const {
|
||||
/* validate the circuit_model_id */
|
||||
VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id));
|
||||
return ( size_t(circuit_edge_id) < edge_ids_[circuit_model_id].size() ) && ( circuit_edge_id == edge_ids_[circuit_model_id][circuit_edge_id] );
|
||||
}
|
||||
|
||||
/* Invalidators */
|
||||
/* Empty fast lookup for circuit_models*/
|
||||
void CircuitLibrary::invalidate_circuit_model_lookup() const {
|
||||
|
@ -1326,6 +1464,28 @@ void CircuitLibrary::invalidate_circuit_model_port_lookup(const CircuitModelId&
|
|||
return;
|
||||
}
|
||||
|
||||
/* Clear all the data structure related to the timing graph */
|
||||
void CircuitLibrary::invalidate_circuit_model_timing_graph(const CircuitModelId& circuit_model_id) {
|
||||
/* validate the circuit_model_id */
|
||||
VTR_ASSERT_SAFE(valid_circuit_model_id(circuit_model_id));
|
||||
edge_ids_[circuit_model_id].clear();
|
||||
|
||||
for (const auto& port_id : ports(circuit_model_id)) {
|
||||
port_in_edge_ids_[circuit_model_id][port_id].clear();
|
||||
port_out_edge_ids_[circuit_model_id][port_id].clear();
|
||||
}
|
||||
|
||||
edge_src_port_ids_[circuit_model_id].clear();
|
||||
edge_src_pin_ids_[circuit_model_id].clear();
|
||||
|
||||
edge_sink_port_ids_[circuit_model_id].clear();
|
||||
edge_sink_pin_ids_[circuit_model_id].clear();
|
||||
|
||||
edge_trise_[circuit_model_id].clear();
|
||||
edge_tfall_[circuit_model_id].clear();
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* End of file : circuit_library.cpp
|
||||
***********************************************************************/
|
||||
|
|
|
@ -217,8 +217,12 @@ class CircuitLibrary {
|
|||
};
|
||||
public: /* Constructors */
|
||||
public: /* Accessors: aggregates */
|
||||
public: /* Public Accessors: Basic data query on Circuit Models*/
|
||||
circuit_model_range circuit_models() const;
|
||||
circuit_port_range ports(const CircuitModelId& circuit_model_id) 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*/
|
||||
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;
|
||||
|
@ -233,7 +237,6 @@ class CircuitLibrary {
|
|||
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*/
|
||||
circuit_port_range ports(const CircuitModelId& circuit_model_id) 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;
|
||||
|
@ -419,6 +422,12 @@ class CircuitLibrary {
|
|||
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_trise(const CircuitModelId& circuit_model_id, const CircuitEdgeId& circuit_edge_id, const float& trise);
|
||||
void set_edge_tfall(const CircuitModelId& circuit_model_id, const CircuitEdgeId& circuit_edge_id, const float& tfall);
|
||||
public: /* Internal mutators: build fast look-ups */
|
||||
void build_circuit_model_lookup();
|
||||
void build_circuit_model_port_lookup(const CircuitModelId& circuit_model_id);
|
||||
|
@ -427,9 +436,11 @@ class CircuitLibrary {
|
|||
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_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_;
|
||||
|
@ -494,9 +505,9 @@ class CircuitLibrary {
|
|||
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_ports_;
|
||||
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_ports_;
|
||||
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, float>> edge_trise_;
|
||||
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, float>> edge_tfall_;
|
||||
|
|
Loading…
Reference in New Issue