SDC: Move the propagation methods to Propagation class Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
diff --git a/Makefile_plugin.common b/Makefile_plugin.common index 6215cbb..4289bd6 100644 --- a/Makefile_plugin.common +++ b/Makefile_plugin.common
@@ -37,7 +37,7 @@ # |-- example2-plugin # |-- ... CXX = $(shell yosys-config --cxx) -CXXFLAGS = $(shell yosys-config --cxxflags) +CXXFLAGS = $(shell yosys-config --cxxflags) #-DSDC_DEBUG LDFLAGS = $(shell yosys-config --ldflags) LDLIBS = $(shell yosys-config --ldlibs) PLUGINS_DIR = $(shell yosys-config --datdir)/plugins
diff --git a/sdc-plugin/buffers.cc b/sdc-plugin/buffers.cc index af28eaf..a48a26a 100644 --- a/sdc-plugin/buffers.cc +++ b/sdc-plugin/buffers.cc
@@ -15,9 +15,9 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "buffers.h" #include <cassert> #include <cmath> -#include "buffers.h" const std::vector<std::string> Pll::inputs = {"CLKIN1", "CLKIN2"}; const std::vector<std::string> Pll::outputs = {"CLKOUT0", "CLKOUT1", "CLKOUT2", @@ -25,9 +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) - : ClockDivider({"PLLE2_ADV"}) -{ +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); @@ -37,7 +37,9 @@ void Pll::CheckInputClockPeriod(RTLIL::Cell* cell, float input_clock_period) { float abs_diff = fabs(ClkinPeriod() - input_clock_period); - bool approx_equal = abs_diff < std::max(ClkinPeriod(), input_clock_period) * 10 * std::numeric_limits<float>::epsilon(); + bool approx_equal = abs_diff < std::max(ClkinPeriod(), input_clock_period) * + 10 * + std::numeric_limits<float>::epsilon(); if (!approx_equal) { log_cmd_error( "CLKIN[1/2]_PERIOD doesn't match the virtual clock constraint " @@ -55,7 +57,8 @@ divclk_divisor = FetchParam(cell, "DIVCLK_DIVIDE", 1.0); for (auto output : outputs) { // CLKOUT[0-5]_DUTY_CYCLE - clkout_duty_cycle[output] = FetchParam(cell, output + "_DUTY_CYCLE", 0.5); + clkout_duty_cycle[output] = + FetchParam(cell, output + "_DUTY_CYCLE", 0.5); // CLKOUT[0-5]_DIVIDE clkout_divisor[output] = FetchParam(cell, output + "_DIVIDE", 1.0); // CLKOUT[0-5]_PHASE @@ -65,22 +68,30 @@ void Pll::CalculateOutputClockPeriods() { for (auto output : outputs) { - // CLKOUT[0-5]_PERIOD = CLKIN1_PERIOD * CLKOUT[0-5]_DIVIDE * DIVCLK_DIVIDE / - // CLKFBOUT_MULT - clkout_period[output] = ClkinPeriod() * clkout_divisor.at(output) / clk_mult * - divclk_divisor; + // CLKOUT[0-5]_PERIOD = CLKIN1_PERIOD * CLKOUT[0-5]_DIVIDE * + // DIVCLK_DIVIDE / CLKFBOUT_MULT + clkout_period[output] = ClkinPeriod() * clkout_divisor.at(output) / + clk_mult * divclk_divisor; } } void Pll::CalculateOutputClockWaveforms(float input_clock_rising_edge) { for (auto output : outputs) { float output_clock_period = clkout_period.at(output); - clkout_rising_edge[output] = fmod(input_clock_rising_edge - (clk_fbout_phase / 360.0) * ClkinPeriod() + output_clock_period * (clkout_phase[output] / 360.0), output_clock_period); - clkout_falling_edge[output] = fmod(clkout_rising_edge[output] + clkout_duty_cycle[output] * output_clock_period, output_clock_period); + clkout_rising_edge[output] = + fmod(input_clock_rising_edge - + (clk_fbout_phase / 360.0) * ClkinPeriod() + + output_clock_period * (clkout_phase[output] / 360.0), + output_clock_period); + clkout_falling_edge[output] = + fmod(clkout_rising_edge[output] + + clkout_duty_cycle[output] * output_clock_period, + output_clock_period); } } -float Pll::FetchParam(RTLIL::Cell* cell, std::string&& param_name, float default_value) { +float Pll::FetchParam(RTLIL::Cell* cell, std::string&& param_name, + float default_value) { RTLIL::IdString param(RTLIL::escape_id(param_name)); if (cell->hasParam(param)) { auto param_obj = cell->parameters.at(param);
diff --git a/sdc-plugin/buffers.h b/sdc-plugin/buffers.h index b0ab049..ba3faa4 100644 --- a/sdc-plugin/buffers.h +++ b/sdc-plugin/buffers.h
@@ -45,9 +45,10 @@ std::string type; }; -struct Pll: public ClockDivider { - Pll():ClockDivider({"PLLE2_ADV"}){} - Pll(RTLIL::Cell* cell, float input_clock_period, float input_clock_rising_edge); +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 static float FetchParam(RTLIL::Cell* cell, std::string&& param_name,
diff --git a/sdc-plugin/clocks.cc b/sdc-plugin/clocks.cc index 2c12ccd..9f259d5 100644 --- a/sdc-plugin/clocks.cc +++ b/sdc-plugin/clocks.cc
@@ -19,32 +19,65 @@ #include <cassert> #include <cmath> #include <regex> -#include "kernel/log.h" #include "kernel/register.h" #include "propagation.h" +void Clock::Add(const std::string& name, RTLIL::Wire* wire, float period, + float rising_edge, float falling_edge) { + wire->set_string_attribute(RTLIL::escape_id("CLOCK_SIGNAL"), "yes"); + 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"), + Clock::ClockWireName(wire)); + wire->set_string_attribute(RTLIL::escape_id("PERIOD"), + std::to_string(period)); + std::string waveform(std::to_string(rising_edge) + " " + + std::to_string(falling_edge)); + wire->set_string_attribute(RTLIL::escape_id("WAVEFORM"), waveform); +} + +void Clock::Add(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) { + Add(name, wire, period, rising_edge, falling_edge); + }); +} + +void Clock::Add(RTLIL::Wire* wire, float period, float rising_edge, + float falling_edge) { + Add(Clock::ClockWireName(wire), 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"); + 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"))); + 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); + 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); + 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::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); } @@ -65,115 +98,18 @@ 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) { - AddClock(name, wire, period, rising_edge, falling_edge); - }); -} - -void Clocks::AddClock(const std::string& name, RTLIL::Wire* wire, float period, - float rising_edge, float falling_edge) { - wire->set_string_attribute(RTLIL::escape_id("CLOCK_SIGNAL"), "yes"); - 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"), Clock::ClockWireName(wire)); - wire->set_string_attribute(RTLIL::escape_id("PERIOD"), std::to_string(period)); - std::string waveform(std::to_string(rising_edge) + " " + std::to_string(falling_edge)); - wire->set_string_attribute(RTLIL::escape_id("WAVEFORM"), waveform); -} - -void Clocks::AddClock(RTLIL::Wire* wire, float period, - float rising_edge, float falling_edge) { - AddClock(Clock::ClockWireName(wire), wire, period, rising_edge, falling_edge); -} - const std::vector<RTLIL::Wire*> Clocks::GetClocks(RTLIL::Design* design) { std::vector<RTLIL::Wire*> clock_wires; RTLIL::Module* top_module = design->top_module(); for (auto& wire_obj : top_module->wires_) { auto& wire = wire_obj.second; if (wire->has_attribute(RTLIL::escape_id("CLOCK_SIGNAL"))) { - if (wire->get_string_attribute(RTLIL::escape_id("CLOCK_SIGNAL")) == "yes") { - clock_wires.push_back(wire); - } + if (wire->get_string_attribute(RTLIL::escape_id("CLOCK_SIGNAL")) == + "yes") { + clock_wires.push_back(wire); + } } } return clock_wires; } -void Clocks::Propagate(RTLIL::Design* design, NaturalPropagation* pass) { -#ifdef SDC_DEBUG - log("Start natural 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 - auto aliases = pass->FindAliasWires(clock_wire); - AddClock(Clock::ClockWireName(clock_wire), aliases, - Clock::Period(clock_wire), Clock::RisingEdge(clock_wire), - Clock::FallingEdge(clock_wire)); - } -#ifdef SDC_DEBUG - log("Finish natural clock propagation\n\n"); -#endif -} - -void Clocks::Propagate(RTLIL::Design* design, BufferPropagation* pass) { -#ifdef SDC_DEBUG - log("Start buffer clock propagation\n"); - log("IBUF pass\n"); -#endif - PropagateThroughBuffers(pass, design, IBuf()); -#ifdef SDC_DEBUG - log("BUFG pass\n"); -#endif - PropagateThroughBuffers(pass, design, Bufg()); -#ifdef SDC_DEBUG - log("Finish buffer clock propagation\n\n"); -#endif -} - -void Clocks::Propagate(RTLIL::Design* design, ClockDividerPropagation* pass) { -#ifdef SDC_DEBUG - log("Start clock divider clock propagation\n"); -#endif - PropagateThroughClockDividers(pass, design, Pll()); - PropagateThroughBuffers(pass, design, Bufg()); -#ifdef SDC_DEBUG - log("Finish clock divider clock propagation\n\n"); -#endif -} - -void Clocks::PropagateThroughBuffers(Propagation* pass, RTLIL::Design* design, - Buffer buffer) { - for (auto& clock_wire : Clocks::GetClocks(design)) { -#ifdef SDC_DEBUG - log("Clock wire %s\n", Clock::ClockWireName(clock_wire).c_str()); -#endif - 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.type.c_str(), - RTLIL::id2cstr(wire->name)); -#endif - path_delay += buffer.delay; - AddClock(wire, Clock::Period(clock_wire), - Clock::RisingEdge(clock_wire) + path_delay, - Clock::FallingEdge(clock_wire) + path_delay); - } - } -} - -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); - } -}
diff --git a/sdc-plugin/clocks.h b/sdc-plugin/clocks.h index 4b8a9e4..6fab3ea 100644 --- a/sdc-plugin/clocks.h +++ b/sdc-plugin/clocks.h
@@ -31,6 +31,12 @@ class Clock { public: + static void Add(const std::string& name, RTLIL::Wire* wire, float period, + float rising_edge, float falling_edge); + static void Add(const std::string& name, std::vector<RTLIL::Wire*> wires, + float period, float rising_edge, float falling_edge); + static void Add(RTLIL::Wire* wire, float period, + float rising_edge, float falling_edge); static float Period(RTLIL::Wire* clock_wire); static float RisingEdge(RTLIL::Wire* clock_wire); static float FallingEdge(RTLIL::Wire* clock_wire); @@ -42,22 +48,7 @@ class Clocks { public: - static void AddClock(const std::string& name, std::vector<RTLIL::Wire*> wires, - float period, float rising_edge, float falling_edge); - static void AddClock(const std::string& name, RTLIL::Wire* wire, float period, - float rising_edge, float falling_edge); - static void AddClock(RTLIL::Wire* wire, float period, - float rising_edge, float falling_edge); static const std::vector<RTLIL::Wire*> GetClocks(RTLIL::Design* design); - void Propagate(RTLIL::Design* design, NaturalPropagation* pass); - void Propagate(RTLIL::Design* design, BufferPropagation* pass); - void Propagate(RTLIL::Design* design, ClockDividerPropagation* pass); - - private: - void PropagateThroughBuffers(Propagation* pass, RTLIL::Design* design, - Buffer buffer); - void PropagateThroughClockDividers(ClockDividerPropagation* pass, RTLIL::Design* design, - ClockDivider divider); }; #endif // _CLOCKS_H_
diff --git a/sdc-plugin/propagation.cc b/sdc-plugin/propagation.cc index 71ce467..dc24d00 100644 --- a/sdc-plugin/propagation.cc +++ b/sdc-plugin/propagation.cc
@@ -20,47 +20,44 @@ USING_YOSYS_NAMESPACE -std::vector<RTLIL::Wire*> NaturalPropagation::FindAliasWires( - RTLIL::Wire* wire) { - RTLIL::Module* top_module = design_->top_module(); - assert(top_module); - std::vector<RTLIL::Wire*> alias_wires; - pass_->extra_args( - std::vector<std::string>{ - top_module->name.str() + "/w:" + wire->name.str(), "%a"}, - 0, design_); - for (auto module : design_->selected_modules()) { - for (auto wire : module->selected_wires()) { - alias_wires.push_back(wire); +void Propagation::PropagateThroughBuffers(Buffer buffer) { + for (auto& clock_wire : Clocks::GetClocks(design_)) { +#ifdef SDC_DEBUG + log("Clock wire %s\n", Clock::ClockWireName(clock_wire).c_str()); +#endif + auto buf_wires = + 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.type.c_str(), + RTLIL::id2cstr(wire->name)); +#endif + path_delay += buffer.delay; + Clock::Add(wire, Clock::Period(clock_wire), + Clock::RisingEdge(clock_wire) + path_delay, + Clock::FallingEdge(clock_wire) + path_delay); } } - return alias_wires; } -void ClockDividerPropagation::PropagateClocksForCellType( - RTLIL::Wire* driver_wire, const std::string& cell_type) { - if (cell_type == "PLLE2_ADV") { - RTLIL::Cell* cell = NULL; - for (auto input : Pll::inputs) { - cell = FindSinkCellOnPort(driver_wire, input); - if (cell and RTLIL::unescape_id(cell->type) == cell_type) { - break; - } - } - if (!cell) { - return; - } - Pll pll(cell, Clock::Period(driver_wire), Clock::RisingEdge(driver_wire)); - for (auto output : Pll::outputs) { - RTLIL::Wire* wire = FindSinkWireOnPort(cell, output); - if (wire) { - float clkout_period(pll.clkout_period.at(output)); - float clkout_rising_edge(pll.clkout_rising_edge.at(output)); - float clkout_falling_edge(pll.clkout_falling_edge.at(output)); - Clocks::AddClock(wire, clkout_period, clkout_rising_edge, clkout_falling_edge); - } - } +std::vector<RTLIL::Wire*> Propagation::FindSinkWiresForCellType( + RTLIL::Wire* driver_wire, const std::string& cell_type, + const std::string& cell_port) { + std::vector<RTLIL::Wire*> wires; + if (!driver_wire) { + return wires; } + auto cell = FindSinkCellOfType(driver_wire, cell_type); + RTLIL::Wire* wire = FindSinkWireOnPort(cell, cell_port); + if (wire) { + wires.push_back(wire); + auto further_wires = + FindSinkWiresForCellType(wire, cell_type, cell_port); + std::copy(further_wires.begin(), further_wires.end(), + std::back_inserter(wires)); + } + return wires; } RTLIL::Cell* Propagation::FindSinkCellOfType(RTLIL::Wire* wire, @@ -89,25 +86,6 @@ return sink_cell; } -std::vector<RTLIL::Wire*> Propagation::FindSinkWiresForCellType( - RTLIL::Wire* driver_wire, const std::string& cell_type, - const std::string& cell_port) { - std::vector<RTLIL::Wire*> wires; - if (!driver_wire) { - return wires; - } - auto cell = FindSinkCellOfType(driver_wire, cell_type); - RTLIL::Wire* wire = FindSinkWireOnPort(cell, cell_port); - if (wire) { - wires.push_back(wire); - auto further_wires = - FindSinkWiresForCellType(wire, cell_type, cell_port); - std::copy(further_wires.begin(), further_wires.end(), - std::back_inserter(wires)); - } - return wires; -} - RTLIL::Cell* Propagation::FindSinkCellOnPort(RTLIL::Wire* wire, const std::string& port) { RTLIL::Cell* sink_cell = NULL; @@ -161,3 +139,102 @@ } return sink_wire; } +void NaturalPropagation::Run() { +#ifdef SDC_DEBUG + log("Start natural 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 + auto aliases = FindAliasWires(clock_wire); + Clock::Add(Clock::ClockWireName(clock_wire), aliases, + Clock::Period(clock_wire), Clock::RisingEdge(clock_wire), + Clock::FallingEdge(clock_wire)); + } +#ifdef SDC_DEBUG + log("Finish natural clock propagation\n\n"); +#endif +} + +std::vector<RTLIL::Wire*> NaturalPropagation::FindAliasWires( + RTLIL::Wire* wire) { + RTLIL::Module* top_module = design_->top_module(); + assert(top_module); + std::vector<RTLIL::Wire*> alias_wires; + pass_->extra_args( + std::vector<std::string>{ + top_module->name.str() + "/w:" + wire->name.str(), "%a"}, + 0, design_); + for (auto module : design_->selected_modules()) { + for (auto wire : module->selected_wires()) { + alias_wires.push_back(wire); + } + } + return alias_wires; +} + +void BufferPropagation::Run() { +#ifdef SDC_DEBUG + log("Start buffer clock propagation\n"); + log("IBUF pass\n"); +#endif + PropagateThroughBuffers(IBuf()); +#ifdef SDC_DEBUG + log("BUFG pass\n"); +#endif + PropagateThroughBuffers(Bufg()); +#ifdef SDC_DEBUG + log("Finish buffer clock propagation\n\n"); +#endif +} + +void ClockDividerPropagation::Run() { +#ifdef SDC_DEBUG + log("Start clock divider clock propagation\n"); +#endif + PropagateThroughClockDividers(Pll()); + PropagateThroughBuffers(Bufg()); +#ifdef SDC_DEBUG + log("Finish clock divider clock propagation\n\n"); +#endif +} + +void ClockDividerPropagation::PropagateThroughClockDividers( + ClockDivider divider) { + for (auto& clock_wire : Clocks::GetClocks(design_)) { +#ifdef SDC_DEBUG + log("Processing clock %s\n", Clock::ClockWireName(clock_wire).c_str()); +#endif + PropagateClocksForCellType(clock_wire, divider.type); + } +} + +void ClockDividerPropagation::PropagateClocksForCellType( + RTLIL::Wire* driver_wire, const std::string& cell_type) { + if (cell_type == "PLLE2_ADV") { + RTLIL::Cell* cell = NULL; + for (auto input : Pll::inputs) { + cell = FindSinkCellOnPort(driver_wire, input); + if (cell and RTLIL::unescape_id(cell->type) == cell_type) { + break; + } + } + if (!cell) { + return; + } + Pll pll(cell, Clock::Period(driver_wire), + Clock::RisingEdge(driver_wire)); + for (auto output : Pll::outputs) { + RTLIL::Wire* wire = FindSinkWireOnPort(cell, output); + if (wire) { + float clkout_period(pll.clkout_period.at(output)); + 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); + } + } + } +} +
diff --git a/sdc-plugin/propagation.h b/sdc-plugin/propagation.h index f9f06ac..788b138 100644 --- a/sdc-plugin/propagation.h +++ b/sdc-plugin/propagation.h
@@ -26,17 +26,18 @@ public: Propagation(RTLIL::Design* design, Pass* pass) : design_(design), pass_(pass) {} - virtual ~Propagation(){} + virtual ~Propagation() {} - virtual void Run(Clocks& clocks) = 0; - std::vector<RTLIL::Wire*> FindSinkWiresForCellType( - RTLIL::Wire* driver_wire, const std::string& cell_type, - const std::string& cell_port); + virtual void Run() = 0; protected: RTLIL::Design* design_; Pass* pass_; + void PropagateThroughBuffers(Buffer buffer); + std::vector<RTLIL::Wire*> FindSinkWiresForCellType( + RTLIL::Wire* driver_wire, const std::string& cell_type, + const std::string& cell_port); RTLIL::Cell* FindSinkCellOfType(RTLIL::Wire* wire, const std::string& type); RTLIL::Cell* FindSinkCellOnPort(RTLIL::Wire* wire, const std::string& port); RTLIL::Wire* FindSinkWireOnPort(RTLIL::Cell* cell, @@ -48,7 +49,7 @@ NaturalPropagation(RTLIL::Design* design, Pass* pass) : Propagation(design, pass) {} - void Run(Clocks& clocks) override { clocks.Propagate(design_, this); } + void Run() override; std::vector<RTLIL::Wire*> FindAliasWires(RTLIL::Wire* wire); }; @@ -57,7 +58,7 @@ BufferPropagation(RTLIL::Design* design, Pass* pass) : Propagation(design, pass) {} - void Run(Clocks& clocks) override { clocks.Propagate(design_, this); } + void Run() override; }; class ClockDividerPropagation : public Propagation { @@ -65,8 +66,9 @@ ClockDividerPropagation(RTLIL::Design* design, Pass* pass) : Propagation(design, pass) {} - void Run(Clocks& clocks) override { clocks.Propagate(design_, this); } + void Run() override; void PropagateClocksForCellType(RTLIL::Wire* driver_wire, - const std::string& cell_type); + const std::string& cell_type); + void PropagateThroughClockDividers(ClockDivider divider); }; #endif // PROPAGATION_H_
diff --git a/sdc-plugin/sdc.cc b/sdc-plugin/sdc.cc index 9d55906..b940301 100644 --- a/sdc-plugin/sdc.cc +++ b/sdc-plugin/sdc.cc
@@ -61,8 +61,8 @@ }; struct WriteSdcCmd : public Backend { - WriteSdcCmd(Clocks& clocks, SdcWriter& sdc_writer) - : Backend("sdc", "Write SDC file"), clocks_(clocks), sdc_writer_(sdc_writer) {} + WriteSdcCmd(SdcWriter& sdc_writer) + : Backend("sdc", "Write SDC file"), sdc_writer_(sdc_writer) {} void help() override { log("\n"); @@ -82,13 +82,12 @@ sdc_writer_.WriteSdc(design, *f); } - Clocks& clocks_; SdcWriter& sdc_writer_; }; struct CreateClockCmd : public Pass { - CreateClockCmd(Clocks& clocks) - : Pass("create_clock", "Create clock object"), clocks_(clocks) {} + CreateClockCmd() + : Pass("create_clock", "Create clock object") {} void help() override { log("\n"); @@ -170,7 +169,7 @@ rising_edge = 0; falling_edge = period / 2; } - clocks_.AddClock(name, selected_wires, period, rising_edge, + Clock::Add(name, selected_wires, period, rising_edge, falling_edge); } @@ -179,8 +178,6 @@ std::transform(selection_begin, args.end(), selection_begin, [](std::string& w) { return "w:" + w; }); } - - Clocks& clocks_; }; struct GetClocksCmd : public Pass { @@ -216,9 +213,8 @@ }; struct PropagateClocksCmd : public Pass { - PropagateClocksCmd(Clocks& clocks) - : Pass("propagate_clocks", "Propagate clock information"), - clocks_(clocks) {} + PropagateClocksCmd() + : Pass("propagate_clocks", "Propagate clock information") {} void help() override { log("\n"); @@ -228,8 +224,11 @@ log("\n"); } - void execute(__attribute__((unused)) std::vector<std::string> args, + void execute(std::vector<std::string> args, RTLIL::Design* design) override { + if (args.size() > 1) { + log_warning("Command accepts no arguments.\nAll will be ignored.\n"); + } if (!design->top_module()) { log_cmd_error("No top module selected\n"); } @@ -243,19 +242,15 @@ log("Perform clock propagation\n"); for (auto& pass : passes) { - pass->Run(clocks_); + pass->Run(); } } - - Clocks& clocks_; }; class SdcPlugin { public: SdcPlugin() - : write_sdc_cmd_(clocks_, sdc_writer_), - create_clock_cmd_(clocks_), - propagate_clocks_cmd_(clocks_), + : write_sdc_cmd_(sdc_writer_), set_false_path_cmd_(sdc_writer_), set_max_delay_cmd_(sdc_writer_), set_clock_groups_cmd_(sdc_writer_) { @@ -272,7 +267,6 @@ SetClockGroups set_clock_groups_cmd_; private: - Clocks clocks_; SdcWriter sdc_writer_; } SdcPlugin;
diff --git a/sdc-plugin/tests/counter/counter.tcl b/sdc-plugin/tests/counter/counter.tcl index 4fcf9be..b045b3c 100644 --- a/sdc-plugin/tests/counter/counter.tcl +++ b/sdc-plugin/tests/counter/counter.tcl
@@ -24,3 +24,4 @@ # Write out the SDC file after the clock propagation step write_sdc $::env(DESIGN_TOP).sdc +write_json $::env(DESIGN_TOP).json