From b5a9e51b966abdfedc9309defa79b5141928e84a Mon Sep 17 00:00:00 2001
From: Clifford Wolf <clifford@clifford.at>
Date: Thu, 31 Jul 2014 15:02:16 +0200
Subject: Added "trace" command

---
 kernel/yosys.h           |  3 ++
 passes/cmds/Makefile.inc |  1 +
 passes/cmds/tee.cc       |  4 +-
 passes/cmds/trace.cc     | 97 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 103 insertions(+), 2 deletions(-)
 create mode 100644 passes/cmds/trace.cc

diff --git a/kernel/yosys.h b/kernel/yosys.h
index 9b36ebcc9..119e7e8a6 100644
--- a/kernel/yosys.h
+++ b/kernel/yosys.h
@@ -44,6 +44,9 @@
 #include <algorithm>
 #include <initializer_list>
 
+#define PRIVATE_NAMESPACE_BEGIN  namespace {
+#define PRIVATE_NAMESPACE_END    }
+
 #if 0
 #  define YOSYS_NAMESPACE_BEGIN  namespace Yosys {
 #  define YOSYS_NAMESPACE_END    }
diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc
index 26c0ef8a9..b55af9958 100644
--- a/passes/cmds/Makefile.inc
+++ b/passes/cmds/Makefile.inc
@@ -19,4 +19,5 @@ OBJS += passes/cmds/tee.o
 OBJS += passes/cmds/write_file.o
 OBJS += passes/cmds/connwrappers.o
 OBJS += passes/cmds/cover.o
+OBJS += passes/cmds/trace.o
 
diff --git a/passes/cmds/tee.cc b/passes/cmds/tee.cc
index e2f69e599..6f80ef72c 100644
--- a/passes/cmds/tee.cc
+++ b/passes/cmds/tee.cc
@@ -73,11 +73,11 @@ struct TeePass : public Pass {
 		try {
 			std::vector<std::string> new_args(args.begin() + argidx, args.end());
 			Pass::call(design, new_args);
-		} catch (int ex) {
+		} catch (log_cmd_error_expection) {
 			for (auto cf : files_to_close)
 				fclose(cf);
 			log_files = backup_log_files;
-			throw ex;
+			throw log_cmd_error_expection();
 		}
 
 		for (auto cf : files_to_close)
diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc
new file mode 100644
index 000000000..b4bc45c20
--- /dev/null
+++ b/passes/cmds/trace.cc
@@ -0,0 +1,97 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2014  Clifford Wolf <clifford@clifford.at>
+ *  Copyright (C) 2014  Johann Glaser <Johann.Glaser@gmx.at>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/yosys.h"
+
+PRIVATE_NAMESPACE_BEGIN
+
+struct TraceMonitor : public RTLIL::Monitor
+{
+	virtual void notify_module_add(RTLIL::Module *module) override
+	{
+		log("#TRACE# Module add: %s\n", log_id(module));
+	}
+
+	virtual void notify_module_del(RTLIL::Module *module) override
+	{
+		log("#TRACE# Module delete: %s\n", log_id(module));
+	}
+
+	virtual void notify_cell_connect(RTLIL::Cell *cell, const std::pair<RTLIL::IdString, RTLIL::SigSpec> &conn) override
+	{
+		log("#TRACE# Cell connect: %s.%s.%s = %s\n", log_id(cell->module), log_id(cell), log_id(conn.first), log_signal(conn.second));
+	}
+
+	virtual void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) override
+	{
+		log("#TRACE# Connection in module %s: %s = %s\n", log_id(module), log_signal(sigsig.first), log_signal(sigsig.second));
+	}
+
+	virtual void notify_new_connections(RTLIL::Module *module, const std::vector<RTLIL::SigSig> &sigsig_vec) override
+	{
+		log("#TRACE# New connections in module %s:\n", log_id(module));
+		for (auto &sigsig : sigsig_vec)
+			log("##    %s = %s\n", log_signal(sigsig.first), log_signal(sigsig.second));
+	}
+
+	virtual void notify_blackout(RTLIL::Module *module) override
+	{
+		log("#TRACE# Blackout in module %s:\n", log_id(module));
+	}
+};
+
+struct TracePass : public Pass {
+	TracePass() : Pass("trace", "redirect command output to file") { }
+	virtual void help()
+	{
+		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+		log("\n");
+		log("    trace cmd\n");
+		log("\n");
+		log("Execute the specified command, logging all changes the command performs on\n");
+		log("the design in real time.\n");
+		log("\n");
+	}
+	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+	{
+		size_t argidx;
+		for (argidx = 1; argidx < args.size(); argidx++)
+		{
+			// .. parse options ..
+			break;
+		}
+
+		TraceMonitor monitor;
+		design->monitors.insert(&monitor);
+
+		try {
+			std::vector<std::string> new_args(args.begin() + argidx, args.end());
+			Pass::call(design, new_args);
+		} catch (log_cmd_error_expection) {
+			design->monitors.erase(&monitor);
+			throw log_cmd_error_expection();
+		}
+
+		design->monitors.erase(&monitor);
+	}
+} TracePass;
+
+PRIVATE_NAMESPACE_END
+
-- 
cgit v1.2.3