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;
}
}