SDC: Write waveform from RTLIL attributes Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
diff --git a/sdc-plugin/clocks.cc b/sdc-plugin/clocks.cc index d1804b7..3727ec6 100644 --- a/sdc-plugin/clocks.cc +++ b/sdc-plugin/clocks.cc
@@ -33,7 +33,12 @@ 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(Clock& clock) { @@ -169,7 +174,41 @@ Clock::Clock(RTLIL::Wire* wire, float period, float rising_edge, float falling_edge) - : Clock(RTLIL::id2cstr(wire->name), wire, period, rising_edge, 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; + } + 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) {
diff --git a/sdc-plugin/clocks.h b/sdc-plugin/clocks.h index c074649..478b9ea 100644 --- a/sdc-plugin/clocks.h +++ b/sdc-plugin/clocks.h
@@ -40,8 +40,11 @@ std::vector<RTLIL::Wire*> GetClockWires() { return clock_wires_; } const std::string& Name() const { return name_; } float Period() { return period_; } + 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); @@ -55,6 +58,7 @@ 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);
diff --git a/sdc-plugin/sdc_writer.cc b/sdc-plugin/sdc_writer.cc index 6826d01..41ebfa3 100644 --- a/sdc-plugin/sdc_writer.cc +++ b/sdc-plugin/sdc_writer.cc
@@ -50,10 +50,10 @@ if (clock_wire->port_input) { continue; } - file << "create_clock -period " << clock_wire->get_string_attribute(RTLIL::escape_id("PERIOD")); - /* file << " -waveform {" << clock.RisingEdge() << " " */ - /* << clock.FallingEdge() << "}"; */ - file << " " << RTLIL::unescape_id(clock_wire->name); + file << "create_clock -period " << Clock::Period(clock_wire); + file << " -waveform {" << Clock::RisingEdge(clock_wire) << " " + << Clock::FallingEdge(clock_wire) << "}"; + file << " " << Clock::ClockWireName(clock_wire); file << std::endl; } }