blob: 7520c3277429700bbf34cd4b89bc8819a570e4a8 [file] [log] [blame]
#ifndef VPR_PACK_PATTERNS_H
#define VPR_PACK_PATTERNS_H
#include "vpr_context.h"
//An edge in a pack pattern graph
struct t_arch_pack_pattern_edge {
int from_node_id = OPEN; //From node's id in t_arch_pack_pattern::nodes
int to_node_id = OPEN; //To node's id in t_arch_pack_pattern::nodes
};
//A node in a pack pattern graph
struct t_arch_pack_pattern_node {
t_arch_pack_pattern_node(t_pb_graph_pin* pin)
: pb_graph_pin(pin) {}
t_pb_graph_pin* pb_graph_pin = nullptr; //Associated PB graph pin
std::vector<int> in_edge_ids; //Incoming edge ids in t_arch_pack_pattern::edges
std::vector<int> out_edge_ids; //Outgoing edge ids in t_arch_pack_pattern::edges
};
//A pack pattern represented as a graph
//
//This is usually a strict tree, unless is_chain is true
struct t_arch_pack_pattern {
//The name of the pack pattern
std::string name;
//The root node id of the pattern
std::vector<int> root_node_ids;
//If true represents a chain-like structure which
//stretches accross multiple logic blocks
//
//Note that if this is a chain, then the graph is not
//strictly a tree, but the root (top-level) will have both
//in-coming and out-going edges forming a loop.
bool is_chain = false;
//The set of pins in the pack pattern graph
std::vector<t_arch_pack_pattern_node> nodes;
//The set of edges in the pack pattern graph
std::vector<t_arch_pack_pattern_edge> edges;
float base_cost = 0.;
};
struct t_netlist_pack_pattern_pin {
int node_id = OPEN; //Associated node in netlist pack pattern graph
t_model* model = nullptr;
t_model_ports* model_port = nullptr;
int port_pin = OPEN; //Pin index within model_port
bool required = false;
};
struct t_netlist_pack_pattern_edge {
t_netlist_pack_pattern_pin from_pin;
std::vector<t_netlist_pack_pattern_pin> to_pins;
};
struct t_netlist_pack_pattern_node {
t_netlist_pack_pattern_node(bool external)
: is_external_(external) {}
t_model* model_type = nullptr;
std::vector<int> in_edge_ids;
std::vector<int> out_edge_ids;
bool is_leaf() const { return out_edge_ids.size() == 0; }
bool is_root() const { return in_edge_ids.size() == 0; }
bool is_external() const { return is_external_; }
bool is_internal() const { return !is_external(); }
private:
bool is_external_; //Indicates node is external (i.e. outside a cluster)
};
struct t_netlist_pack_pattern {
std::string name;
int root_node = OPEN;
float base_cost = 0.;
std::vector<t_netlist_pack_pattern_node> nodes;
std::vector<t_netlist_pack_pattern_edge> edges;
int create_node(bool external) {
nodes.emplace_back(external);
return nodes.size() - 1;
}
int create_edge() {
edges.emplace_back();
return edges.size() - 1;
}
bool node_required(int node_id) const {
//A node is required if any of it's out-going edge to_pins
//are required
for (auto edge_id : nodes[node_id].out_edge_ids) {
for (auto& pin : edges[edge_id].to_pins) {
if (pin.required) return true;
}
}
return false;
}
};
struct NetlistPatternMatch {
struct Edge {
Edge(AtomPinId from, AtomPinId to, int edge_id, int sink_idx)
: from_pin(from)
, to_pin(to)
, pattern_edge_id(edge_id)
, pattern_edge_sink(sink_idx) {}
AtomPinId from_pin;
AtomPinId to_pin;
int pattern_edge_id = OPEN; //Pattern edge which matched these pins
int pattern_edge_sink = OPEN; //Matching sink number within pattern edge
};
//Evaluates true when the match is non-empty
operator bool() {
return netlist_edges.size() > 0 || internal_blocks.size() > 0;
}
std::string pattern_name;
std::vector<Edge> netlist_edges;
std::vector<AtomBlockId> internal_blocks;
std::vector<AtomBlockId> external_blocks;
float base_cost = 0.;
};
constexpr auto ATOM_DEFAULT_PACK_PATTERN_NAME = "vpr_default_atom_pattern";
std::vector<t_arch_pack_pattern> identify_arch_pack_patterns(const DeviceContext& device_ctx);
std::vector<t_netlist_pack_pattern> abstract_arch_pack_patterns(const std::vector<t_arch_pack_pattern>& arch_pack_patterns);
t_netlist_pack_pattern create_atom_default_pack_pattern();
std::vector<NetlistPatternMatch> collect_pattern_matches_in_netlist(const t_netlist_pack_pattern& pattern, const AtomNetlist& netlist);
std::vector<NetlistPatternMatch> filter_netlist_pattern_matches(std::vector<NetlistPatternMatch> matches);
void print_match(const NetlistPatternMatch& match, const AtomNetlist& netlist);
void write_arch_pack_pattern_dot(std::ostream& os, const t_arch_pack_pattern& arch_pattern);
void write_netlist_pack_pattern_dot(std::ostream& os, const t_netlist_pack_pattern& netlist_pattern);
#endif