SDC: Refactor and remove unused code Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
diff --git a/sdc-plugin/buffers.cc b/sdc-plugin/buffers.cc index 919de28..af28eaf 100644 --- a/sdc-plugin/buffers.cc +++ b/sdc-plugin/buffers.cc
@@ -25,7 +25,9 @@ const float Pll::delay = 0; const std::string Pll::name = "PLLE2_ADV"; -Pll::Pll(RTLIL::Cell* cell, float input_clock_period, float input_clock_rising_edge) { +Pll::Pll(RTLIL::Cell* cell, float input_clock_period, float input_clock_rising_edge) + : ClockDivider({"PLLE2_ADV"}) +{ assert(RTLIL::unescape_id(cell->type) == "PLLE2_ADV"); FetchParams(cell); CheckInputClockPeriod(cell, input_clock_period);
diff --git a/sdc-plugin/buffers.h b/sdc-plugin/buffers.h index 5f51535..b0ab049 100644 --- a/sdc-plugin/buffers.h +++ b/sdc-plugin/buffers.h
@@ -26,10 +26,10 @@ USING_YOSYS_NAMESPACE struct Buffer { - Buffer(float delay, const std::string& name, const std::string& output) - : delay(delay), name(name), output(output) {} + Buffer(float delay, const std::string& type, const std::string& output) + : delay(delay), type(type), output(output) {} float delay; - std::string name; + std::string type; std::string output; }; @@ -41,7 +41,12 @@ Bufg() : Buffer(0, "BUFG", "O"){}; }; -struct Pll { +struct ClockDivider { + std::string type; +}; + +struct Pll: public ClockDivider { + Pll():ClockDivider({"PLLE2_ADV"}){} Pll(RTLIL::Cell* cell, float input_clock_period, float input_clock_rising_edge); // Helper function to fetch a cell parameter or return a default value
diff --git a/sdc-plugin/clocks.cc b/sdc-plugin/clocks.cc index 3a856c3..2c12ccd 100644 --- a/sdc-plugin/clocks.cc +++ b/sdc-plugin/clocks.cc
@@ -23,6 +23,48 @@ #include "kernel/register.h" #include "propagation.h" +float Clock::Period(RTLIL::Wire* clock_wire) { + if (!clock_wire->has_attribute(RTLIL::escape_id("PERIOD"))) { + log_warning("Period has not been specified\n Default value 0 will be used\n"); + return 0; + } + return std::stof(clock_wire->get_string_attribute(RTLIL::escape_id("PERIOD"))); +} + +std::pair<float, float> Clock::Waveform(RTLIL::Wire* clock_wire) { + if (!clock_wire->has_attribute(RTLIL::escape_id("WAVEFORM"))) { + float period(Period(clock_wire)); + if (!period) { + log_cmd_error("Neither PERIOD nor WAVEFORM has been specified for wire %s\n", ClockWireName(clock_wire).c_str()); + return std::make_pair(0,0); + } + float falling_edge = period / 2; + log_warning("Waveform has not been specified\n Default value {0 %f} will be used\n", falling_edge); + return std::make_pair(0, falling_edge); + } + float rising_edge(0); + float falling_edge(0); + std::string waveform(clock_wire->get_string_attribute(RTLIL::escape_id("WAVEFORM"))); + std::sscanf(waveform.c_str(), "%f %f", &rising_edge, &falling_edge); + return std::make_pair(rising_edge, falling_edge); +} + +float Clock::RisingEdge(RTLIL::Wire* clock_wire) { + return Waveform(clock_wire).first; +} + +float Clock::FallingEdge(RTLIL::Wire* clock_wire) { + return Waveform(clock_wire).second; +} + +std::string Clock::ClockWireName(RTLIL::Wire* wire) { + if (!wire) { + return std::string(); + } + std::string wire_name(RTLIL::unescape_id(wire->name)); + return std::regex_replace(wire_name, std::regex{"\\$"}, "\\$"); +} + void Clocks::AddClock(const std::string& name, std::vector<RTLIL::Wire*> wires, float period, float rising_edge, float falling_edge) { std::for_each(wires.begin(), wires.end(), [&](RTLIL::Wire* wire) { @@ -97,13 +139,8 @@ #ifdef SDC_DEBUG log("Start clock divider clock propagation\n"); #endif - for (auto& clock_wire : Clocks::GetClocks(design)) { -#ifdef SDC_DEBUG - log("Processing clock %s\n", RTLIL::id2cstr(clock_wire->name)); -#endif - pass->PropagateClocksForCellType(clock_wire, "PLLE2_ADV"); - PropagateThroughBuffers(pass, design, Bufg()); - } + PropagateThroughClockDividers(pass, design, Pll()); + PropagateThroughBuffers(pass, design, Bufg()); #ifdef SDC_DEBUG log("Finish clock divider clock propagation\n\n"); #endif @@ -115,12 +152,12 @@ #ifdef SDC_DEBUG log("Clock wire %s\n", Clock::ClockWireName(clock_wire).c_str()); #endif - auto buf_wires = pass->FindSinkWiresForCellType(clock_wire, buffer.name, + auto buf_wires = pass->FindSinkWiresForCellType(clock_wire, buffer.type, buffer.output); int path_delay(0); for (auto wire : buf_wires) { #ifdef SDC_DEBUG - log("%s wire: %s\n", buffer.name.c_str(), + log("%s wire: %s\n", buffer.type.c_str(), RTLIL::id2cstr(wire->name)); #endif path_delay += buffer.delay; @@ -131,90 +168,12 @@ } } -Clock::Clock(const std::string& name, RTLIL::Wire* wire, float period, - float rising_edge, float falling_edge) - : name_(name), - period_(period), - rising_edge_(rising_edge), - falling_edge_(falling_edge) { - UpdateWires(wire); -} - -Clock::Clock(const std::string& name, std::vector<RTLIL::Wire*> wires, - float period, float rising_edge, float falling_edge) - : name_(name), - period_(period), - rising_edge_(rising_edge), - falling_edge_(falling_edge) { - std::for_each(wires.begin(), wires.end(), - [&, this](RTLIL::Wire* wire) { UpdateWires(wire); }); -} - -Clock::Clock(RTLIL::Wire* wire, float period, - float rising_edge, float falling_edge) - : Clock(RTLIL::unescape_id(wire->name), wire, period, rising_edge, falling_edge) {} - -float Clock::Period(RTLIL::Wire* clock_wire) { - if (!clock_wire->has_attribute(RTLIL::escape_id("PERIOD"))) { - log_warning("Period has not been specified\n Default value 0 will be used\n"); - return 0; +void Clocks::PropagateThroughClockDividers(ClockDividerPropagation* pass, RTLIL::Design* design, + ClockDivider divider) { + for (auto& clock_wire : Clocks::GetClocks(design)) { +#ifdef SDC_DEBUG + log("Processing clock %s\n", Clock::ClockWireName(clock_wire).c_str()); +#endif + pass->PropagateClocksForCellType(clock_wire, divider.type); } - return std::stof(clock_wire->get_string_attribute(RTLIL::escape_id("PERIOD"))); -} - -std::pair<float, float> Clock::Waveform(RTLIL::Wire* clock_wire) { - if (!clock_wire->has_attribute(RTLIL::escape_id("WAVEFORM"))) { - float period(Period(clock_wire)); - if (!period) { - log_cmd_error("Neither PERIOD nor WAVEFORM has been specified for wire %s\n", ClockWireName(clock_wire).c_str()); - return std::make_pair(0,0); - } - float falling_edge = period / 2; - log_warning("Waveform has not been specified\n Default value {0 %f} will be used\n", falling_edge); - return std::make_pair(0, falling_edge); - } - float rising_edge(0); - float falling_edge(0); - std::string waveform(clock_wire->get_string_attribute(RTLIL::escape_id("WAVEFORM"))); - std::sscanf(waveform.c_str(), "%f %f", &rising_edge, &falling_edge); - return std::make_pair(rising_edge, falling_edge); -} - -float Clock::RisingEdge(RTLIL::Wire* clock_wire) { - return Waveform(clock_wire).first; -} - -float Clock::FallingEdge(RTLIL::Wire* clock_wire) { - return Waveform(clock_wire).second; -} - -void Clock::UpdateClock(RTLIL::Wire* wire, float period, float rising_edge, - float falling_edge) { - UpdateWires(wire); - UpdatePeriod(period); - UpdateWaveform(rising_edge, falling_edge); -} - -void Clock::UpdateWires(RTLIL::Wire* wire) { - if (std::find(clock_wires_.begin(), clock_wires_.end(), wire) == - clock_wires_.end()) { - clock_wires_.push_back(wire); - } -} - -void Clock::UpdatePeriod(float period) { - period_ = period; -} - -void Clock::UpdateWaveform(float rising_edge, float falling_edge) { - rising_edge_ = fmod(rising_edge, period_); - falling_edge_ = fmod(falling_edge, period_); -} - -std::string Clock::ClockWireName(RTLIL::Wire* wire) { - if (!wire) { - return std::string(); - } - std::string wire_name(RTLIL::unescape_id(wire->name)); - return std::regex_replace(wire_name, std::regex{"\\$"}, "\\$"); }
diff --git a/sdc-plugin/clocks.h b/sdc-plugin/clocks.h index 9a74b4a..4b8a9e4 100644 --- a/sdc-plugin/clocks.h +++ b/sdc-plugin/clocks.h
@@ -31,36 +31,13 @@ class Clock { public: - Clock(const std::string& name, RTLIL::Wire* wire, float period, - float rising_edge, float falling_edge); - Clock(const std::string& name, std::vector<RTLIL::Wire*> wires, - float period, float rising_edge, float falling_edge); - Clock(RTLIL::Wire* wire, float period, - float rising_edge, float falling_edge); - std::vector<RTLIL::Wire*> GetClockWires() { return clock_wires_; } - const std::string& Name() const { return name_; } static float Period(RTLIL::Wire* clock_wire); - float RisingEdge() { return rising_edge_; } static float RisingEdge(RTLIL::Wire* clock_wire); - float FallingEdge() { return falling_edge_; } static float FallingEdge(RTLIL::Wire* clock_wire); - RTLIL::Wire* ClockWire() { return clock_wire_; } - void UpdateClock(RTLIL::Wire* wire, float period, float rising_edge, - float falling_edge); static std::string ClockWireName(RTLIL::Wire* wire); private: - std::string name_; - std::vector<RTLIL::Wire*> clock_wires_; - RTLIL::Wire* clock_wire_; - float period_; - float rising_edge_; - float falling_edge_; - static std::pair<float, float> Waveform(RTLIL::Wire* clock_wire); - void UpdateWires(RTLIL::Wire* wire); - void UpdatePeriod(float period); - void UpdateWaveform(float rising_edge, float falling_edge); }; class Clocks { @@ -79,6 +56,8 @@ private: void PropagateThroughBuffers(Propagation* pass, RTLIL::Design* design, Buffer buffer); + void PropagateThroughClockDividers(ClockDividerPropagation* pass, RTLIL::Design* design, + ClockDivider divider); }; #endif // _CLOCKS_H_