Ported fixes related to timing graph node remapping.

Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
This commit is contained in:
Maciej Kurc 2022-07-21 10:29:58 +02:00
parent 2a73b60afb
commit 22f8d968cc
4 changed files with 80 additions and 11 deletions

View File

@ -150,6 +150,15 @@ AtomLookup::tnode_pin_range AtomLookup::tnode_atom_pins() const {
return vtr::make_range(tnode_atom_pin_.begin(), tnode_atom_pin_.end());
}
AtomLookup::pin_tnode_range AtomLookup::atom_pin_tnodes(BlockTnode block_tnode_type) const {
if (block_tnode_type == BlockTnode::EXTERNAL) {
return vtr::make_range(atom_pin_tnode_external_.begin(), atom_pin_tnode_external_.end());
} else {
VTR_ASSERT(block_tnode_type == BlockTnode::INTERNAL);
return vtr::make_range(atom_pin_tnode_internal_.begin(), atom_pin_tnode_internal_.end());
}
}
void AtomLookup::set_atom_pin_tnode(const AtomPinId pin, const tatum::NodeId node, BlockTnode block_tnode_type) {
//A pin always expands to an external tnode (i.e. it's external connectivity in the netlist)
//but some pins may expand to an additional tnode (i.e. to SOURCE/SINK to cover internal sequential paths within a block)

View File

@ -18,8 +18,10 @@
*/
class AtomLookup {
public:
typedef vtr::linear_map<AtomPinId, tatum::NodeId>::const_iterator pin_tnode_iterator;
typedef vtr::linear_map<tatum::NodeId, AtomPinId>::const_iterator tnode_pin_iterator;
typedef vtr::Range<pin_tnode_iterator> pin_tnode_range;
typedef vtr::Range<tnode_pin_iterator> tnode_pin_range;
public:
@ -86,6 +88,9 @@ class AtomLookup {
//Returns a range of all tnode to pin mappings
tnode_pin_range tnode_atom_pins() const;
///@brief Returns a range of all pin to tnode mappingsg of the specified type
AtomLookup::pin_tnode_range atom_pin_tnodes(BlockTnode block_tnode_type) const;
//Sets the bi-directional mapping between an atom netlist pin and timing graph node
void set_atom_pin_tnode(const AtomPinId pin, const tatum::NodeId node, BlockTnode block_tnode_type = BlockTnode::EXTERNAL);

View File

@ -47,6 +47,8 @@ std::unique_ptr<TimingGraph> TimingGraphBuilder::timing_graph(bool allow_danglin
VTR_ASSERT(tg_);
tg_->validate();
validate_netlist_timing_graph_consistency();
return std::move(tg_);
}
@ -421,22 +423,73 @@ tatum::EdgeId TimingGraphBuilder::find_scc_edge_to_break(std::vector<tatum::Node
void TimingGraphBuilder::remap_ids(const tatum::GraphIdMaps& id_mapping) {
//Update the pin-tnode mapping
vtr::linear_map<tatum::NodeId, AtomPinId> new_tnode_atom_pin;
for (auto kv : netlist_lookup_.tnode_atom_pins()) {
tatum::NodeId old_tnode = kv.first;
AtomPinId pin = kv.second;
tatum::NodeId new_tnode = id_mapping.node_id_map[old_tnode];
for (BlockTnode type : {BlockTnode::EXTERNAL, BlockTnode::INTERNAL}) {
for (auto kv : netlist_lookup_.atom_pin_tnodes(type)) {
AtomPinId pin = kv.first;
tatum::NodeId old_tnode = kv.second;
new_tnode_atom_pin.emplace(new_tnode, pin);
}
if (!old_tnode) continue;
for (auto kv : new_tnode_atom_pin) {
tatum::NodeId tnode = kv.first;
AtomPinId pin = kv.second;
netlist_lookup_.set_atom_pin_tnode(pin, tnode);
tatum::NodeId new_tnode = id_mapping.node_id_map[old_tnode];
netlist_lookup_.set_atom_pin_tnode(pin, new_tnode, type);
}
}
}
bool TimingGraphBuilder::is_netlist_clock_source(const AtomPinId pin) const {
return netlist_clock_drivers_.count(pin);
}
bool TimingGraphBuilder::validate_netlist_timing_graph_consistency() const {
for (AtomPinId pin : netlist_.pins()) {
tatum::NodeId ext_tnode = netlist_lookup_.atom_pin_tnode(pin, BlockTnode::EXTERNAL);
if (!ext_tnode) VPR_ERROR(VPR_ERROR_TIMING, "Found no external tnode for atom pin '%zu'", size_t(pin));
tatum::NodeId int_tnode = netlist_lookup_.atom_pin_tnode(pin, BlockTnode::INTERNAL);
/*
* Sanity check look-up consistency
*/
AtomPinId ext_tnode_pin = netlist_lookup_.tnode_atom_pin(ext_tnode);
if (ext_tnode_pin != pin) {
VPR_ERROR(VPR_ERROR_TIMING, "Inconsistent external tnode -> atom pin lookup: atom pin %zu -> tnode %zu, but tnode %zu -> atom pin %zu",
size_t(pin), size_t(ext_tnode), size_t(ext_tnode), size_t(ext_tnode_pin));
}
if (int_tnode) {
AtomPinId int_tnode_pin = netlist_lookup_.tnode_atom_pin(int_tnode);
if (int_tnode_pin != pin) {
VPR_ERROR(VPR_ERROR_TIMING, "Inconsistent internal tnode -> atom pin lookup: atom pin %zu -> tnode %zu, but tnode %zu -> atom pin %zu",
size_t(pin), size_t(int_tnode), size_t(int_tnode), size_t(int_tnode_pin));
}
}
/*
* Sanity check internal/external tnode types
*/
tatum::NodeType ext_tnode_type = tg_->node_type(ext_tnode);
if (ext_tnode_type == tatum::NodeType::IPIN || ext_tnode_type == tatum::NodeType::OPIN) {
if (!int_tnode) VPR_ERROR(VPR_ERROR_TIMING, "Missing expected internal tnode for combinational atom pin %zu", size_t(pin));
if (int_tnode != ext_tnode) VPR_ERROR(VPR_ERROR_TIMING, "Mismatch external/internal tnodes (%zu vs %zu) for combinational atom pin %zu",
size_t(ext_tnode), size_t(int_tnode), size_t(pin));
} else if (ext_tnode_type == tatum::NodeType::CPIN) {
if (int_tnode) VPR_ERROR(VPR_ERROR_TIMING, "Unexpected internal tnode (%zu) for clock pin: atom pin %zu ,external tnode %zu",
size_t(int_tnode), size_t(pin), size_t(ext_tnode));
} else if (ext_tnode_type == tatum::NodeType::SOURCE) {
if (int_tnode && tg_->node_type(int_tnode) != tatum::NodeType::SINK) {
VPR_ERROR(VPR_ERROR_TIMING, "Found internal tnode (%zu) associated with atom pin %zu, but it is not a SINK (external tnode %zu was a SOURCE)",
size_t(int_tnode), size_t(pin), size_t(ext_tnode));
}
} else if (ext_tnode_type == tatum::NodeType::SINK) {
if (int_tnode && tg_->node_type(int_tnode) != tatum::NodeType::SOURCE) {
VPR_ERROR(VPR_ERROR_TIMING, "Found internal tnode (%zu) associated with atom pin %zu, but it is not a SOURCE (external tnode %zu was a SINK)",
size_t(int_tnode), size_t(pin), size_t(ext_tnode));
}
} else {
VPR_ERROR(VPR_ERROR_TIMING, "Unexpected timing node type for atom pin %zu", size_t(pin));
}
}
return true; //success
}

View File

@ -32,6 +32,8 @@ class TimingGraphBuilder {
bool is_netlist_clock_source(const AtomPinId pin) const;
bool validate_netlist_timing_graph_consistency() const;
private:
std::unique_ptr<tatum::TimingGraph> tg_;