SDC: Implement WriteSdc command

Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
diff --git a/sdc-plugin/clocks.cc b/sdc-plugin/clocks.cc
index 6bf4eb1..06c1933 100644
--- a/sdc-plugin/clocks.cc
+++ b/sdc-plugin/clocks.cc
@@ -141,6 +141,23 @@
     }
 }
 
+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;
+	   }
+	}
+	    /* 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()); */
+    }
+}
+
 Clock::Clock(const std::string& name, RTLIL::Wire* wire, float period,
              float rising_edge, float falling_edge)
     : name_(name) {
diff --git a/sdc-plugin/clocks.h b/sdc-plugin/clocks.h
index e17543e..1fdce01 100644
--- a/sdc-plugin/clocks.h
+++ b/sdc-plugin/clocks.h
@@ -78,6 +78,7 @@
     void Propagate(NaturalPropagation* pass);
     void Propagate(BufferPropagation* pass);
     void Propagate(ClockDividerPropagation* pass);
+    void WriteSdc(std::ostream& file);
 
    private:
     std::unordered_map<std::string, Clock> clocks_;
diff --git a/sdc-plugin/sdc.cc b/sdc-plugin/sdc.cc
index f44020d..e344acb 100644
--- a/sdc-plugin/sdc.cc
+++ b/sdc-plugin/sdc.cc
@@ -30,7 +30,6 @@
     ReadSdcCmd() : Frontend("sdc", "Read SDC file") {}
 
     void help() override {
-	//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 	log("\n");
 	log("    read_sdc <filename>\n");
 	log("\n");
@@ -57,6 +56,31 @@
     }
 };
 
+struct WriteSdcCmd : public Backend {
+    WriteSdcCmd(Clocks& clocks)
+        : Backend("sdc", "Write SDC file"), clocks_(clocks) {}
+
+    void help() override {
+	log("\n");
+	log("    write_sdc <filename>\n");
+	log("\n");
+	log("Write SDC file.\n");
+	log("\n");
+    }
+
+    void execute(std::ostream*& f, std::string filename,
+                 std::vector<std::string> args, RTLIL::Design*) override {
+	if (args.size() < 2) {
+	    log_cmd_error("Missing output file.\n");
+	}
+	log("\nWriting out clock constraints file(SDC)\n\n");
+	extra_args(f, filename, args, 1);
+	clocks_.WriteSdc(*f);
+    }
+
+    Clocks& clocks_;
+};
+
 struct CreateClockCmd : public Pass {
     CreateClockCmd(Clocks& clocks)
         : Pass("create_clock", "Create clock object"), clocks_(clocks) {}
@@ -215,13 +239,15 @@
 class SdcPlugin {
    public:
     SdcPlugin()
-        : create_clock_cmd_(clocks_),
+        : write_sdc_cmd_(clocks_),
+	  create_clock_cmd_(clocks_),
           get_clocks_cmd_(clocks_),
           propagate_clocks_cmd_(clocks_) {
 	log("Loaded SDC plugin\n");
     }
 
     ReadSdcCmd read_sdc_cmd_;
+    WriteSdcCmd write_sdc_cmd_;
     CreateClockCmd create_clock_cmd_;
     GetClocksCmd get_clocks_cmd_;
     PropagateClocksCmd propagate_clocks_cmd_;