SDC: Distinguish GENERATED, PROPAGATED and EXPLICIT clocks
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
diff --git a/sdc-plugin/clocks.cc b/sdc-plugin/clocks.cc
index adcb6b1..4147174 100644
--- a/sdc-plugin/clocks.cc
+++ b/sdc-plugin/clocks.cc
@@ -23,8 +23,11 @@
#include "propagation.h"
void Clock::Add(const std::string& name, RTLIL::Wire* wire, float period,
- float rising_edge, float falling_edge) {
+ float rising_edge, float falling_edge, ClockType type) {
wire->set_string_attribute(RTLIL::escape_id("CLOCK_SIGNAL"), "yes");
+ wire->set_bool_attribute(RTLIL::escape_id("IS_GENERATED"), type == GENERATED);
+ wire->set_bool_attribute(RTLIL::escape_id("IS_EXPLICIT"), type == EXPLICIT);
+ wire->set_bool_attribute(RTLIL::escape_id("IS_PROPAGATED"), type == PROPAGATED);
wire->set_string_attribute(RTLIL::escape_id("CLASS"), "clock");
wire->set_string_attribute(RTLIL::escape_id("NAME"), name);
wire->set_string_attribute(RTLIL::escape_id("SOURCE_PINS"),
@@ -37,15 +40,15 @@
}
void Clock::Add(const std::string& name, std::vector<RTLIL::Wire*> wires,
- float period, float rising_edge, float falling_edge) {
+ float period, float rising_edge, float falling_edge, ClockType type) {
std::for_each(wires.begin(), wires.end(), [&](RTLIL::Wire* wire) {
- Add(name, wire, period, rising_edge, falling_edge);
+ Add(name, wire, period, rising_edge, falling_edge, type);
});
}
void Clock::Add(RTLIL::Wire* wire, float period, float rising_edge,
- float falling_edge) {
- Add(Clock::WireName(wire), wire, period, rising_edge, falling_edge);
+ float falling_edge, ClockType type) {
+ Add(Clock::WireName(wire), wire, period, rising_edge, falling_edge, type);
}
float Clock::Period(RTLIL::Wire* clock_wire) {
@@ -128,6 +131,13 @@
return Name(clock_wire);
}
+bool Clock::GetClockWireBoolAttribute(RTLIL::Wire* wire, const std::string& attribute_name) {
+ if (wire->has_attribute(RTLIL::escape_id(attribute_name))) {
+ return wire->get_bool_attribute(RTLIL::escape_id(attribute_name));
+ }
+ return false;
+}
+
const std::map<std::string, RTLIL::Wire*> Clocks::GetClocks(
RTLIL::Design* design) {
std::map<std::string, RTLIL::Wire*> clock_wires;
diff --git a/sdc-plugin/clocks.h b/sdc-plugin/clocks.h
index 846a2af..d9208e0 100644
--- a/sdc-plugin/clocks.h
+++ b/sdc-plugin/clocks.h
@@ -32,12 +32,13 @@
class Clock {
public:
+ enum ClockType { EXPLICIT, GENERATED, PROPAGATED };
static void Add(const std::string& name, RTLIL::Wire* wire, float period,
- float rising_edge, float falling_edge);
+ float rising_edge, float falling_edge, ClockType type);
static void Add(const std::string& name, std::vector<RTLIL::Wire*> wires,
- float period, float rising_edge, float falling_edge);
+ float period, float rising_edge, float falling_edge, ClockType type);
static void Add(RTLIL::Wire* wire, float period, float rising_edge,
- float falling_edge);
+ float falling_edge, ClockType type);
static float Period(RTLIL::Wire* clock_wire);
static float RisingEdge(RTLIL::Wire* clock_wire);
static float FallingEdge(RTLIL::Wire* clock_wire);
@@ -47,9 +48,22 @@
return std::regex_replace(name, std::regex{"\\$"}, "\\$");
}
static std::string SourcePinName(RTLIL::Wire* clock_wire);
+ static bool IsPropagated(RTLIL::Wire* wire) {
+ return GetClockWireBoolAttribute(wire, "IS_PROPAGATED");
+ }
+
+ static bool IsGenerated(RTLIL::Wire* wire) {
+ return GetClockWireBoolAttribute(wire, "IS_GENERATED");
+ }
+
+ static bool IsExplicit(RTLIL::Wire* wire) {
+ return GetClockWireBoolAttribute(wire, "IS_EXPLICIT");
+ }
private:
static std::pair<float, float> Waveform(RTLIL::Wire* clock_wire);
+
+ static bool GetClockWireBoolAttribute(RTLIL::Wire* wire, const std::string& attribute_name);
};
class Clocks {
diff --git a/sdc-plugin/propagation.cc b/sdc-plugin/propagation.cc
index f7e59d8..1982aef 100644
--- a/sdc-plugin/propagation.cc
+++ b/sdc-plugin/propagation.cc
@@ -37,7 +37,7 @@
path_delay += buffer.delay;
Clock::Add(wire, Clock::Period(clock_wire),
Clock::RisingEdge(clock_wire) + path_delay,
- Clock::FallingEdge(clock_wire) + path_delay);
+ Clock::FallingEdge(clock_wire) + path_delay, Clock::PROPAGATED);
}
}
}
@@ -169,7 +169,7 @@
auto aliases = FindAliasWires(clock_wire);
Clock::Add(Clock::WireName(clock_wire), aliases,
Clock::Period(clock_wire), Clock::RisingEdge(clock_wire),
- Clock::FallingEdge(clock_wire));
+ Clock::FallingEdge(clock_wire), Clock::PROPAGATED);
}
#ifdef SDC_DEBUG
log("Finish natural clock propagation\n\n");
@@ -253,7 +253,7 @@
float clkout_rising_edge(pll.clkout_rising_edge.at(output));
float clkout_falling_edge(pll.clkout_falling_edge.at(output));
Clock::Add(wire, clkout_period, clkout_rising_edge,
- clkout_falling_edge);
+ clkout_falling_edge, Clock::GENERATED);
}
}
}
diff --git a/sdc-plugin/propagation.h b/sdc-plugin/propagation.h
index 29ee07f..3efd984 100644
--- a/sdc-plugin/propagation.h
+++ b/sdc-plugin/propagation.h
@@ -34,6 +34,8 @@
RTLIL::Design* design_;
Pass* pass_;
+ // This propagation doesn't change the clock so the sink wire is only marked
+ // as propagated clock signal, but has the properties of the driving clock
void PropagateThroughBuffers(Buffer buffer);
std::vector<RTLIL::Wire*> FindSinkWiresForCellType(
RTLIL::Wire* driver_wire, const std::string& cell_type,
diff --git a/sdc-plugin/sdc.cc b/sdc-plugin/sdc.cc
index a9b7f6a..83fb61b 100644
--- a/sdc-plugin/sdc.cc
+++ b/sdc-plugin/sdc.cc
@@ -169,7 +169,7 @@
rising_edge = 0;
falling_edge = period / 2;
}
- Clock::Add(name, selected_wires, period, rising_edge, falling_edge);
+ Clock::Add(name, selected_wires, period, rising_edge, falling_edge, Clock::EXPLICIT);
}
void AddWirePrefix(std::vector<std::string>& args, size_t argidx) {
diff --git a/sdc-plugin/sdc_writer.cc b/sdc-plugin/sdc_writer.cc
index 6f7a760..4c3e093 100644
--- a/sdc-plugin/sdc_writer.cc
+++ b/sdc-plugin/sdc_writer.cc
@@ -46,11 +46,15 @@
void SdcWriter::WriteClocks(RTLIL::Design* design, std::ostream& file) {
for (auto& clock : Clocks::GetClocks(design)) {
- // FIXME: Input port nets are not found in VPR
auto& clock_wire = clock.second;
+ // FIXME: Input port nets are not found in VPR
if (clock_wire->port_input) {
continue;
}
+ // Write out only GENERATED and EXPLICIT clocks
+ if (Clock::IsPropagated(clock_wire)) {
+ continue;
+ }
file << "create_clock -period " << Clock::Period(clock_wire);
file << " -waveform {" << Clock::RisingEdge(clock_wire) << " "
<< Clock::FallingEdge(clock_wire) << "}";