SDC: Refactor Clock classes Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
diff --git a/sdc-plugin/clocks.cc b/sdc-plugin/clocks.cc index 06c1933..a9b4607 100644 --- a/sdc-plugin/clocks.cc +++ b/sdc-plugin/clocks.cc
@@ -21,8 +21,29 @@ #include "kernel/register.h" #include "propagation.h" +void Clocks::AddClock(const std::string& name, + std::vector<RTLIL::Wire*> wires, float period, + float rising_edge, float falling_edge) { + AddClockWires(name, wires, period, rising_edge, falling_edge); +} + +void Clocks::AddClock(const std::string& name, + RTLIL::Wire* wire, float period, + float rising_edge, float falling_edge) { + auto clock = std::find_if(clocks_.begin(), clocks_.end(), [&](Clock& clock) { return clock.Name() == name; }); + if (clock != clocks_.end()) { + log("Clock %s already exists and will be overwritten\n", name.c_str()); + clocks_.erase(clock); + } + clocks_.emplace_back(name, wire, period, rising_edge, falling_edge); +} + +void Clocks::AddClock(Clock& clock) { + AddClock(clock.Name(), clock.GetClockWires(), clock.Period(), clock.RisingEdge(), clock.FallingEdge()); +} + void Clocks::AddClockWires(const std::string& name, - const std::vector<RTLIL::Wire*>& wires, float period, + std::vector<RTLIL::Wire*> wires, float period, float rising_edge, float falling_edge) { std::for_each(wires.begin(), wires.end(), [&, this](RTLIL::Wire* wire) { AddClockWire(name, wire, period, rising_edge, falling_edge); @@ -31,32 +52,28 @@ void Clocks::AddClockWire(const std::string& name, RTLIL::Wire* wire, float period, float rising_edge, float falling_edge) { - auto clock = clocks_.find(name); + auto clock = std::find_if(clocks_.begin(), clocks_.end(), [&](Clock& clock) { return clock.Name() == name; }); if (clock == clocks_.end()) { - clocks_.emplace(std::make_pair(name, Clock(name, wire, period, rising_edge, falling_edge))); + AddClock(name, wire, period, rising_edge, falling_edge); } else { - clock->second.AddClockWire(wire, period, rising_edge, falling_edge); + clock->AddWire(wire); } } -void Clocks::AddClockWire(const std::string& name, ClockWire& clock_wire) { - AddClockWire(name, clock_wire.Wire(), clock_wire.Period(), clock_wire.RisingEdge(), clock_wire.FallingEdge()); -} - std::vector<std::string> Clocks::GetClockNames() { std::vector<std::string> res; for (auto clock : clocks_) { - res.push_back(clock.first); + res.push_back(clock.Name()); #ifdef SDC_DEBUG - log("Wires in clock %s:\n", clock.first.c_str()); - for (auto clock_wire : clock.second.GetClockWires()) { - log("create_clock -period %f -name %s -waveform {%f %f} %s\n", - clock_wire.Period(), clock.first.c_str(), - clock_wire.RisingEdge(), clock_wire.FallingEdge(), - clock_wire.WireName().c_str()); + std::stringstream ss; + for (auto clock_wire : clock.GetClockWires()) { + ss << RTLIL::unescape_id(clock_wire->name) << " "; } -#endif + log("create_clock -period %f -name %s -waveform {%f %f} %s\n", + clock.Period(), clock.Name().c_str(), + clock.RisingEdge(), clock.FallingEdge(), ss.str().c_str()); } +#endif return res; } @@ -66,13 +83,13 @@ #endif for (auto clock : clocks_) { #ifdef SDC_DEBUG - log("Processing clock %s\n", clock.first.c_str()); + log("Processing clock %s\n", clock.Name().c_str()); #endif - auto clock_wires = clock.second.GetClockWires(); + auto clock_wires = clock.GetClockWires(); for (auto clock_wire : clock_wires) { - auto aliases = pass->FindAliasWires(clock_wire.Wire()); - AddClockWires(clock.first, aliases, clock_wire.Period(), - clock_wire.RisingEdge(), clock_wire.FallingEdge()); + auto aliases = pass->FindAliasWires(clock_wire); + AddClockWires(clock.Name(), aliases, clock.Period(), + clock.RisingEdge(), clock.FallingEdge()); } } #ifdef SDC_DEBUG @@ -84,9 +101,9 @@ #ifdef SDC_DEBUG log("Start buffer clock propagation\n"); #endif - for (auto& clock : clocks_) { + for (auto clock : clocks_) { #ifdef SDC_DEBUG - log("Processing clock %s\n", clock.first.c_str()); + log("Processing clock %s\n", clock.Name().c_str()); #endif PropagateThroughBuffer(pass, clock, IBuf()); PropagateThroughBuffer(pass, clock, Bufg()); @@ -100,19 +117,19 @@ #ifdef SDC_DEBUG log("Start clock divider clock propagation\n"); #endif - for (auto& clock : clocks_) { + for (auto clock : clocks_) { #ifdef SDC_DEBUG - log("Processing clock %s\n", clock.first.c_str()); + log("Processing clock %s\n", clock.Name().c_str()); #endif - auto clock_wires = clock.second.GetClockWires(); + auto clock_wires = clock.GetClockWires(); for (auto clock_wire : clock_wires) { - auto pll_clock_wires = pass->FindSinkClockWiresForCellType( + auto pll_clocks = pass->FindSinkClocksForCellType( clock_wire, "PLLE2_ADV"); - for (auto pll_clock_wire : pll_clock_wires) { + for (auto pll_clock : pll_clocks) { #ifdef SDC_DEBUG - log("PLL wire: %s\n", pll_clock_wire.WireName().c_str()); + log("PLL clock: %s\n", pll_clock.Name().c_str()); #endif - AddClockWire(pll_clock_wire.WireName(), pll_clock_wire); + AddClock(pll_clock); } } } @@ -122,68 +139,76 @@ } void Clocks::PropagateThroughBuffer(BufferPropagation* pass, - decltype(clocks_)::value_type clock, + Clock& clock, Buffer buffer) { - auto clock_wires = clock.second.GetClockWires(); + auto clock_wires = clock.GetClockWires(); for (auto clock_wire : clock_wires) { + log("%s\n", clock_wire->name.c_str()); auto buf_wires = pass->FindSinkWiresForCellType( - clock_wire.Wire(), buffer.name, buffer.output); + clock_wire, buffer.name, buffer.output); int path_delay(0); for (auto wire : buf_wires) { #ifdef SDC_DEBUG - log("%s wire: %s\n", buffer.name.c_str(), wire->name.c_str()); + log("%s wire: %s\n", buffer.name.c_str(), RTLIL::unescape_id(wire->name).c_str()); #endif path_delay += buffer.delay; - AddClockWire(wire->name.str(), wire, clock_wire.Period(), - clock_wire.RisingEdge() + path_delay, - clock_wire.FallingEdge() + path_delay); + AddClock(RTLIL::unescape_id(wire->name), wire, clock.Period(), + clock.RisingEdge() + path_delay, + clock.FallingEdge() + path_delay); } } } void Clocks::WriteSdc(std::ostream& file) { for (auto& clock : clocks_) { - auto clock_wires = clock.second.GetClockWires(); - file << "create_clock"; - for (auto clock_wire : clock_wires) { - file << " -period " << clock_wire.Period(); - if (clock_wires.size() > 1) { - file << " -name " << clock.first; - } + auto clock_wires = clock.GetClockWires(); + file << "create_clock -period " << clock.Period(); + if (clock_wires.size() > 1) { + file << " -name " << clock.Name(); } - /* log("create_clock -period %f -name %s -waveform {%f %f} %s\n", */ - /* clock_wire.Period(), clock.first.c_str(), */ - /* clock_wire.RisingEdge(), clock_wire.FallingEdge(), */ - /* clock_wire.WireName().c_str()); */ + file << " -waveform {" << clock.RisingEdge() << " " << clock.FallingEdge() << "}"; + for (auto clock_wire : clock_wires) { + file << " " << RTLIL::unescape_id(clock_wire->name) << std::endl; + } } } Clock::Clock(const std::string& name, RTLIL::Wire* wire, float period, float rising_edge, float falling_edge) - : name_(name) { - AddClockWire(wire, period, rising_edge, falling_edge); + : name_(name), + period_(period), + rising_edge_(rising_edge), + falling_edge_(falling_edge) { + AddWire(wire); } -void Clock::AddClockWire(RTLIL::Wire* wire, float period, float rising_edge, - float falling_edge) { - auto clock_wire = std::find_if( +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) { + AddWire(wire); + }); +} + +void Clock::AddWire(RTLIL::Wire* wire) { + auto clock_wire = std::find( clock_wires_.begin(), clock_wires_.end(), - [wire](ClockWire& clock_wire) { return clock_wire.Wire() == wire; }); + wire); if (clock_wire == clock_wires_.end()) { - clock_wires_.emplace_back(wire, period, rising_edge, falling_edge); - } else { - clock_wire->UpdatePeriod(period); - clock_wire->UpdateWaveform(rising_edge, falling_edge); + clock_wires_.push_back(wire); } } -void ClockWire::UpdatePeriod(float period) { +void Clock::UpdatePeriod(float period) { period_ = period; rising_edge_ = 0; falling_edge_ = period / 2; } -void ClockWire::UpdateWaveform(float rising_edge, float falling_edge) { +void Clock::UpdateWaveform(float rising_edge, float falling_edge) { rising_edge_ = rising_edge; falling_edge_ = falling_edge; assert(falling_edge - rising_edge == period_ / 2);
diff --git a/sdc-plugin/clocks.h b/sdc-plugin/clocks.h index 1fdce01..97fe75c 100644 --- a/sdc-plugin/clocks.h +++ b/sdc-plugin/clocks.h
@@ -29,16 +29,15 @@ class BufferPropagation; class ClockDividerPropagation; -class ClockWire { +class Clock { public: - ClockWire(RTLIL::Wire* wire, float period, float rising_edge, - float falling_edge) - : wire_(wire), - period_(period), - rising_edge_(rising_edge), - falling_edge_(falling_edge) {} - RTLIL::Wire* Wire() { return wire_; } - std::string WireName() { return RTLIL::unescape_id(wire_->name); } + 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); + void AddWire(RTLIL::Wire* wire); + std::vector<RTLIL::Wire*> GetClockWires() { return clock_wires_; } + const std::string& Name() const { return name_; } float Period() { return period_; } float RisingEdge() { return rising_edge_; } float FallingEdge() { return falling_edge_; } @@ -46,34 +45,26 @@ void UpdateWaveform(float rising_edge, float falling_edge); private: - RTLIL::Wire* wire_; + std::string name_; + std::vector<RTLIL::Wire*> clock_wires_; float period_; float rising_edge_; float falling_edge_; }; -class Clock { - public: - Clock(const std::string& name, RTLIL::Wire* wire, float period, - float rising_edge, float falling_edge); - void AddClockWire(RTLIL::Wire* wire, float period, float rising_edge, - float falling_edge); - std::vector<ClockWire> GetClockWires() { return clock_wires_; } - - private: - std::string name_; - std::vector<ClockWire> clock_wires_; -}; - - class Clocks { public: + void AddClock(const std::string& name, + std::vector<RTLIL::Wire*> wires, float period, + float rising_edge, float falling_edge); + void AddClock(const std::string& name, RTLIL::Wire* wire, float period, + float rising_edge, float falling_edge); + void AddClock(Clock& clock); void AddClockWires(const std::string& name, - const std::vector<RTLIL::Wire*>& wires, float period, + std::vector<RTLIL::Wire*> wires, float period, float rising_edge, float falling_edge); void AddClockWire(const std::string& name, RTLIL::Wire* wire, float period, float rising_edge, float falling_edge); - void AddClockWire(const std::string& name, ClockWire& clock_wire); std::vector<std::string> GetClockNames(); void Propagate(NaturalPropagation* pass); void Propagate(BufferPropagation* pass); @@ -81,8 +72,8 @@ void WriteSdc(std::ostream& file); private: - std::unordered_map<std::string, Clock> clocks_; - void PropagateThroughBuffer(BufferPropagation* pass, decltype(clocks_)::value_type clock, Buffer buffer); + std::vector<Clock> clocks_; + void PropagateThroughBuffer(BufferPropagation* pass, Clock& clock, Buffer buffer); }; #endif // _CLOCKS_H_
diff --git a/sdc-plugin/propagation.cc b/sdc-plugin/propagation.cc index c719dbb..e8a519e 100644 --- a/sdc-plugin/propagation.cc +++ b/sdc-plugin/propagation.cc
@@ -37,34 +37,34 @@ return alias_wires; } -std::vector<ClockWire> ClockDividerPropagation::FindSinkClockWiresForCellType(ClockWire& driver_wire, +std::vector<Clock> ClockDividerPropagation::FindSinkClocksForCellType(RTLIL::Wire* driver_wire, const std::string& cell_type) { - std::vector<ClockWire> wires; + std::vector<Clock> clocks; if (cell_type == "PLLE2_ADV") { RTLIL::Cell* cell = NULL; for (auto input : Pll::inputs) { - cell = FindSinkCellOnPort(driver_wire.Wire(), input); + cell = FindSinkCellOnPort(driver_wire, input); if (cell and RTLIL::unescape_id(cell->type) == cell_type) { break; } } if (!cell) { - return wires; + return clocks; } Pll pll(cell); for (auto output : Pll::outputs) { RTLIL::Wire* wire = FindSinkWireOnPort(cell, output); if (wire) { float period(pll.CalculatePeriod(output)); - ClockWire clock_wire(wire, period, 0, period / 2); - wires.push_back(clock_wire); - auto further_wires = FindSinkClockWiresForCellType(clock_wire, cell_type); - std::copy(further_wires.begin(), further_wires.end(), - std::back_inserter(wires)); + Clock clock(RTLIL::unescape_id(wire->name), wire, period, 0, period / 2); + clocks.push_back(clock); + auto further_clocks = FindSinkClocksForCellType(wire, cell_type); + std::copy(further_clocks.begin(), further_clocks.end(), + std::back_inserter(clocks)); } } } - return wires; + return clocks; } RTLIL::Cell* Propagation::FindSinkCellOfType(RTLIL::Wire* wire, @@ -86,7 +86,7 @@ if (selected_cells.size() > 0) { sink_cell = selected_cells.at(0); #ifdef SDC_DEBUG - log("Found sink cell: %s\n", sink_cell->name.c_str()); + log("Found sink cell: %s\n", RTLIL::unescape_id(sink_cell->name).c_str()); #endif } return sink_cell; @@ -128,7 +128,7 @@ if (selected_cells.size() > 0) { sink_cell = selected_cells.at(0); #ifdef SDC_DEBUG - log("Found sink cell: %s\n", sink_cell->name.c_str()); + log("Found sink cell: %s\n", RTLIL::unescape_id(sink_cell->name).c_str()); #endif } return sink_cell; @@ -154,7 +154,7 @@ if (selected_wires.size() > 0) { sink_wire = selected_wires.at(0); #ifdef SDC_DEBUG - log("Found sink wire: %s\n", sink_wire->name.c_str()); + log("Found sink wire: %s\n", RTLIL::unescape_id(sink_wire->name).c_str()); #endif } return sink_wire;
diff --git a/sdc-plugin/propagation.h b/sdc-plugin/propagation.h index 4680ff9..e09fc84 100644 --- a/sdc-plugin/propagation.h +++ b/sdc-plugin/propagation.h
@@ -65,7 +65,7 @@ : Propagation(design, pass) {} void Run(Clocks& clocks) override { clocks.Propagate(this); } - std::vector<ClockWire> FindSinkClockWiresForCellType( - ClockWire& driver_wire, const std::string& cell_type); + std::vector<Clock> FindSinkClocksForCellType( + RTLIL::Wire* driver_wire, const std::string& cell_type); }; #endif // PROPAGATION_H_
diff --git a/sdc-plugin/sdc.cc b/sdc-plugin/sdc.cc index e344acb..60a1f83 100644 --- a/sdc-plugin/sdc.cc +++ b/sdc-plugin/sdc.cc
@@ -73,7 +73,7 @@ if (args.size() < 2) { log_cmd_error("Missing output file.\n"); } - log("\nWriting out clock constraints file(SDC)\n\n"); + log("\nWriting out clock constraints file(SDC)\n"); extra_args(f, filename, args, 1); clocks_.WriteSdc(*f); } @@ -158,7 +158,7 @@ if (name.empty()) { name = RTLIL::unescape_id(selected_wires.at(0)->name); } - clocks_.AddClockWires(name, selected_wires, period, rising_edge, + clocks_.AddClock(name, selected_wires, period, rising_edge, falling_edge); log("Created clock %s with period %f, waveform {%f %f}\n", name.c_str(), period, rising_edge, falling_edge);