vpr: Allow creation of clock to output pin edges in the timing graph
These edges are used to represent black-box buffers in the clock
network.
diff --git a/vpr/src/timing/PreClusterDelayCalculator.h b/vpr/src/timing/PreClusterDelayCalculator.h
index 24a1b3a..54e97e6 100644
--- a/vpr/src/timing/PreClusterDelayCalculator.h
+++ b/vpr/src/timing/PreClusterDelayCalculator.h
@@ -101,8 +101,9 @@
VTR_ASSERT_MSG((src_node_type == tatum::NodeType::IPIN && sink_node_type == tatum::NodeType::OPIN)
|| (src_node_type == tatum::NodeType::SOURCE && sink_node_type == tatum::NodeType::SINK)
|| (src_node_type == tatum::NodeType::SOURCE && sink_node_type == tatum::NodeType::OPIN)
+ || (src_node_type == tatum::NodeType::CPIN && sink_node_type == tatum::NodeType::OPIN)
|| (src_node_type == tatum::NodeType::IPIN && sink_node_type == tatum::NodeType::SINK),
- "Primitive combinational delay must be between {SOURCE, IPIN} and {SINK, OPIN}");
+ "Primitive combinational delay must be between {SOURCE, IPIN} and {SINK, OPIN}, or CPIN/OPIN");
//Primitive internal combinational delay
AtomPinId input_pin = netlist_lookup_.tnode_atom_pin(src_node);
diff --git a/vpr/src/timing/atom_delay_calc.inl b/vpr/src/timing/atom_delay_calc.inl
index 407602c..ec32aa9 100644
--- a/vpr/src/timing/atom_delay_calc.inl
+++ b/vpr/src/timing/atom_delay_calc.inl
@@ -10,8 +10,10 @@
inline float AtomDelayCalc::atom_combinational_delay(const AtomPinId src_pin, const AtomPinId sink_pin, const DelayType delay_type) const {
VTR_ASSERT_MSG(netlist_.pin_block(src_pin) == netlist_.pin_block(sink_pin), "Combinational primitive delay must be between pins on the same block");
- VTR_ASSERT_MSG( netlist_.port_type(netlist_.pin_port(src_pin)) == PortType::INPUT
- && netlist_.port_type(netlist_.pin_port(sink_pin)) == PortType::OUTPUT,
+ auto src_pin_type = netlist_.port_type(netlist_.pin_port(src_pin));
+ auto sink_pin_type = netlist_.port_type(netlist_.pin_port(sink_pin));
+ VTR_ASSERT_MSG((src_pin_type == PortType::INPUT && sink_pin_type == PortType::OUTPUT)
+ || (src_pin_type == PortType::CLOCK && sink_pin_type == PortType::OUTPUT),
"Combinational connections must go from primitive input to output");
//Determine the combinational delay from the pb_graph_pin.
diff --git a/vpr/src/timing/timing_graph_builder.cpp b/vpr/src/timing/timing_graph_builder.cpp
index 86ff555..4d4ac33 100644
--- a/vpr/src/timing/timing_graph_builder.cpp
+++ b/vpr/src/timing/timing_graph_builder.cpp
@@ -267,7 +267,7 @@
}
}
- //Connect the combinational edges
+ //Connect the combinational edges from input pins
for (AtomPinId src_pin : netlist_.block_input_pins(blk)) {
//Combinational edges go between IPINs and OPINs for combinational blocks
//and between the internal SOURCEs and SINKS for sequential blocks
@@ -327,6 +327,34 @@
}
}
}
+
+ //Connect the combinational edges from clock pins
+ //
+ //These are typically used to represent clock buffers
+ for (AtomPinId src_clock_pin : netlist_.block_clock_pins(blk)) {
+ NodeId src_tnode = netlist_lookup_.atom_pin_tnode(src_clock_pin, BlockTnode::EXTERNAL);
+
+ if (!src_tnode) continue;
+
+ //Look-up the combinationally connected sink ports name on the port model
+ AtomPortId src_port = netlist_.pin_port(src_clock_pin);
+ const t_model_ports* model_port = netlist_.port_model(src_port);
+
+ for (const std::string& sink_port_name : model_port->combinational_sink_ports) {
+ AtomPortId sink_port = netlist_.find_port(blk, sink_port_name);
+ if (!sink_port) continue; //Port may not be connected
+
+ //We now need to create edges between the source pin, and all the pins in the
+ //output port
+ for (AtomPinId sink_pin : netlist_.port_pins(sink_port)) {
+ //Get the tnode of the sink
+ NodeId sink_tnode = netlist_lookup_.atom_pin_tnode(sink_pin, BlockTnode::EXTERNAL);
+
+ tg_->add_edge(tatum::EdgeType::PRIMITIVE_COMBINATIONAL, src_tnode, sink_tnode);
+ VTR_LOG("Adding edge from '%s' (%zu) -> '%s' (%zu)\n", netlist_.pin_name(src_clock_pin).c_str(), size_t(src_tnode), netlist_.pin_name(sink_pin).c_str(), size_t(sink_tnode));
+ }
+ }
+ }
}
void TimingGraphBuilder::add_net_to_timing_graph(const AtomNetId net) {