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) << "}";