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 <algorithm>
|
||||||
|
|
||||||
#include "vtr_assert.h"
|
#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());
|
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
|
* Public Accessors : Basic data query on Circuit Models
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -356,9 +400,9 @@ CircuitModelId CircuitLibrary::add_circuit_model() {
|
||||||
edge_ids_.emplace_back();
|
edge_ids_.emplace_back();
|
||||||
port_in_edge_ids_.emplace_back();
|
port_in_edge_ids_.emplace_back();
|
||||||
port_out_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_src_pin_ids_.emplace_back();
|
||||||
edge_sink_ports_.emplace_back();
|
edge_sink_port_ids_.emplace_back();
|
||||||
edge_sink_pin_ids_.emplace_back();
|
edge_sink_pin_ids_.emplace_back();
|
||||||
edge_trise_.emplace_back();
|
edge_trise_.emplace_back();
|
||||||
edge_tfall_.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_lut_output_masks_[circuit_model_id].emplace_back();
|
||||||
port_sram_orgz_[circuit_model_id].push_back(NUM_CIRCUIT_MODEL_SRAM_ORGZ_TYPES);
|
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;
|
return circuit_port_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1229,6 +1277,25 @@ void CircuitLibrary::build_circuit_model_links() {
|
||||||
|
|
||||||
/* Build the timing graph for a circuit models*/
|
/* Build the timing graph for a circuit models*/
|
||||||
void CircuitLibrary::build_circuit_model_timing_graph(const CircuitModelId& circuit_model_id) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1236,11 +1303,77 @@ void CircuitLibrary::build_circuit_model_timing_graph(const CircuitModelId& circ
|
||||||
void CircuitLibrary::build_timing_graphs() {
|
void CircuitLibrary::build_timing_graphs() {
|
||||||
/* Walk through each circuit model, build timing graph one by one */
|
/* Walk through each circuit model, build timing graph one by one */
|
||||||
for (auto& circuit_model_id : circuit_models()) {
|
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);
|
build_circuit_model_timing_graph(circuit_model_id);
|
||||||
|
/* Annotate timing information */
|
||||||
}
|
}
|
||||||
return;
|
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
|
* Internal mutators: build fast look-ups
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -1290,7 +1423,6 @@ void CircuitLibrary::build_circuit_model_port_lookup(const CircuitModelId& circu
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Internal invalidators/validators
|
* 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)] );
|
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 */
|
/* Invalidators */
|
||||||
/* Empty fast lookup for circuit_models*/
|
/* Empty fast lookup for circuit_models*/
|
||||||
void CircuitLibrary::invalidate_circuit_model_lookup() const {
|
void CircuitLibrary::invalidate_circuit_model_lookup() const {
|
||||||
|
@ -1326,6 +1464,28 @@ void CircuitLibrary::invalidate_circuit_model_port_lookup(const CircuitModelId&
|
||||||
return;
|
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
|
* End of file : circuit_library.cpp
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
|
@ -217,8 +217,12 @@ class CircuitLibrary {
|
||||||
};
|
};
|
||||||
public: /* Constructors */
|
public: /* Constructors */
|
||||||
public: /* Accessors: aggregates */
|
public: /* Accessors: aggregates */
|
||||||
public: /* Public Accessors: Basic data query on Circuit Models*/
|
|
||||||
circuit_model_range circuit_models() const;
|
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;
|
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_name(const CircuitModelId& circuit_model_id) const;
|
||||||
std::string circuit_model_prefix(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_output_buffered(const CircuitModelId& circuit_model_id) const;
|
||||||
bool is_lut_intermediate_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*/
|
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;
|
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;
|
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;
|
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_links();
|
||||||
void build_circuit_model_timing_graph(const CircuitModelId& circuit_model_id);
|
void build_circuit_model_timing_graph(const CircuitModelId& circuit_model_id);
|
||||||
void build_timing_graphs();
|
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 */
|
public: /* Internal mutators: build fast look-ups */
|
||||||
void build_circuit_model_lookup();
|
void build_circuit_model_lookup();
|
||||||
void build_circuit_model_port_lookup(const CircuitModelId& circuit_model_id);
|
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_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_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_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 */
|
/* Invalidators */
|
||||||
void invalidate_circuit_model_lookup() const;
|
void invalidate_circuit_model_lookup() const;
|
||||||
void invalidate_circuit_model_port_lookup(const CircuitModelId& circuit_model_id) 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 */
|
private: /* Internal data */
|
||||||
/* Fundamental information */
|
/* Fundamental information */
|
||||||
vtr::vector<CircuitModelId, CircuitModelId> circuit_model_ids_;
|
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<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_in_edge_ids_;
|
||||||
vtr::vector<CircuitModelId, vtr::vector<CircuitPortId, vtr::vector<size_t, CircuitEdgeId>>> port_out_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, 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, size_t>> edge_sink_pin_ids_;
|
||||||
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, float>> edge_trise_;
|
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, float>> edge_trise_;
|
||||||
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, float>> edge_tfall_;
|
vtr::vector<CircuitModelId, vtr::vector<CircuitEdgeId, float>> edge_tfall_;
|
||||||
|
|
Loading…
Reference in New Issue