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