From ac10e7d96da4965751fd60a8dd42a8998c011c39 Mon Sep 17 00:00:00 2001
From: Udi Finkelstein <github@udifink.com>
Date: Fri, 3 May 2019 03:10:43 +0300
Subject: Initial implementation of elaboration system tasks (IEEE1800-2017
 section 20.11) This PR allows us to use $info/$warning/$error/$fatal **at
 elaboration time** within a generate block. This is very useful to stop a
 synthesis of a parametrized block when an illegal combination of parameters
 is chosen.

---
 frontends/ast/ast.cc               |  1 +
 frontends/ast/ast.h                |  4 +++-
 frontends/ast/genrtlil.cc          |  1 +
 frontends/ast/simplify.cc          | 47 +++++++++++++++++++++++++++++++++++---
 frontends/verilog/verilog_lexer.l  |  5 ++++
 frontends/verilog/verilog_parser.y | 11 ++++++++-
 kernel/log.cc                      | 11 +++++++++
 kernel/log.h                       |  1 +
 tests/various/elab_sys_tasks.sv    | 30 ++++++++++++++++++++++++
 tests/various/elab_sys_tasks.ys    |  1 +
 10 files changed, 107 insertions(+), 5 deletions(-)
 create mode 100644 tests/various/elab_sys_tasks.sv
 create mode 100644 tests/various/elab_sys_tasks.ys

diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 9f88b08c1..d28345503 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -154,6 +154,7 @@ std::string AST::type2str(AstNodeType type)
 	X(AST_GENIF)
 	X(AST_GENCASE)
 	X(AST_GENBLOCK)
+	X(AST_TECALL)
 	X(AST_POSEDGE)
 	X(AST_NEGEDGE)
 	X(AST_EDGE)
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 281cbe086..b3e6fbaa0 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -137,7 +137,8 @@ namespace AST
 		AST_GENIF,
 		AST_GENCASE,
 		AST_GENBLOCK,
-
+		AST_TECALL,
+		
 		AST_POSEDGE,
 		AST_NEGEDGE,
 		AST_EDGE,
@@ -233,6 +234,7 @@ namespace AST
 		bool mem2reg_check(pool<AstNode*> &mem2reg_set);
 		void mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes);
 		void meminfo(int &mem_width, int &mem_size, int &addr_bits);
+		bool check_elab_tasks(void);
 
 		// additional functionality for evaluating constant functions
 		struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; };
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index b3a2a84be..d5e7d94ab 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -856,6 +856,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 	case AST_GENVAR:
 	case AST_GENFOR:
 	case AST_GENBLOCK:
+	case AST_TECALL:
 	case AST_GENIF:
 	case AST_GENCASE:
 	case AST_PACKAGE:
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 4d4b9dfe1..e6132995d 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -1146,7 +1146,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 
 			if (type == AST_GENFOR) {
 				for (size_t i = 0; i < buf->children.size(); i++) {
-					buf->children[i]->simplify(false, false, false, stage, -1, false, false);
+					if (!buf->children[i]->check_elab_tasks())
+						buf->children[i]->simplify(false, false, false, stage, -1, false, false);
 					current_ast_mod->children.push_back(buf->children[i]);
 				}
 			} else {
@@ -1261,7 +1262,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 			}
 
 			for (size_t i = 0; i < buf->children.size(); i++) {
-				buf->children[i]->simplify(false, false, false, stage, -1, false, false);
+				if (!buf->children[i]->check_elab_tasks())
+					buf->children[i]->simplify(false, false, false, stage, -1, false, false);
 				current_ast_mod->children.push_back(buf->children[i]);
 			}
 
@@ -1340,7 +1342,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 			}
 
 			for (size_t i = 0; i < buf->children.size(); i++) {
-				buf->children[i]->simplify(false, false, false, stage, -1, false, false);
+				if (!buf->children[i]->check_elab_tasks())
+					buf->children[i]->simplify(false, false, false, stage, -1, false, false);
 				current_ast_mod->children.push_back(buf->children[i]);
 			}
 
@@ -2969,6 +2972,44 @@ static void mark_memories_assign_lhs_complex(dict<AstNode*, pool<std::string>> &
 	}
 }
 
+// handle $info(), $warning(), $error(), $fatal()
+// we don't do that in simplify() because we don't know 
+bool AstNode::check_elab_tasks(void)
+{
+	if (type == AST_TECALL) {
+		int sz = children.size();
+		if (str == "$info") {
+			if (sz > 0)
+				log_file_info(filename, linenum, "%s.\n", children[0]->str.c_str());
+			else
+				log_file_info(filename, linenum, "\n");
+		} else if (str == "$warning") {
+			if (sz > 0)
+				log_file_warning(filename, linenum, "%s.\n", children[0]->str.c_str());
+			else
+				log_file_warning(filename, linenum, "\n");
+		} else if (str == "$error") {
+			if (sz > 0)
+				log_file_error(filename, linenum, "%s.\n", children[0]->str.c_str());
+			else
+				log_file_error(filename, linenum, "\n");
+		} else if (str == "$fatal") {
+			// TODO: 1st parameter, if exists, is 0,1 or 2, and passed to $finish()
+			// if no parameter is given, default value is 1
+			// dollar_finish(sz ? children[0] : 1);
+			// perhaps create & use log_file_fatal()
+			if (sz > 0)
+				log_file_error(filename, linenum, "FATAL: %s.\n", children[0]->str.c_str());
+			else
+				log_file_error(filename, linenum, "FATAL.\n");
+		} else {
+			log_file_error(filename, linenum, "Unknown elabortoon system task '%s'.\n", str.c_str());
+		}
+		return true;
+	}
+	return false;
+
+}
 // find memories that should be replaced by registers
 void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg_places,
 		dict<AstNode*, uint32_t> &mem2reg_candidates, dict<AstNode*, uint32_t> &proc_flags, uint32_t &flags)
diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l
index 6ef38252a..1c6810b47 100644
--- a/frontends/verilog/verilog_lexer.l
+++ b/frontends/verilog/verilog_lexer.l
@@ -301,6 +301,11 @@ supply1 { return TOK_SUPPLY1; }
 	return TOK_ID;
 }
 
+"$"(info|warning|error|fatal) {
+	frontend_verilog_yylval.string = new std::string(yytext);
+	return TOK_ELAB_TASK;
+}
+
 "$signed"   { return TOK_TO_SIGNED; }
 "$unsigned" { return TOK_TO_UNSIGNED; }
 
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 40968d17a..1965f090e 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -105,7 +105,7 @@ static void free_attr(std::map<std::string, AstNode*> *al)
 	bool boolean;
 }
 
-%token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE TOK_SVA_LABEL
+%token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE TOK_SVA_LABEL TOK_ELAB_TASK
 %token TOK_ASSERT TOK_ASSUME TOK_RESTRICT TOK_COVER
 %token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END
 %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM
@@ -1869,6 +1869,15 @@ gen_stmt:
 		if ($6 != NULL)
 			delete $6;
 		ast_stack.pop_back();
+	} |
+	TOK_ELAB_TASK {
+		AstNode *node = new AstNode(AST_TECALL);
+		node->str = *$1;
+		delete $1;
+		ast_stack.back()->children.push_back(node);
+		ast_stack.push_back(node);
+	} opt_arg_list ';'{
+		ast_stack.pop_back();		
 	};
 
 gen_stmt_block:
diff --git a/kernel/log.cc b/kernel/log.cc
index 9a9104e26..d2a661bb0 100644
--- a/kernel/log.cc
+++ b/kernel/log.cc
@@ -278,6 +278,17 @@ void log_file_warning(const std::string &filename, int lineno,
 	va_end(ap);
 }
 
+void log_file_info(const std::string &filename, int lineno,
+                      const char *format, ...)
+{
+	va_list ap;
+	va_start(ap, format);
+	std::string prefix = stringf("%s:%d: Info: ",
+				     filename.c_str(), lineno);
+	logv_warning_with_prefix(prefix.c_str(), format, ap);
+	va_end(ap);
+}
+
 YS_ATTRIBUTE(noreturn)
 static void logv_error_with_prefix(const char *prefix,
                                    const char *format, va_list ap)
diff --git a/kernel/log.h b/kernel/log.h
index e6afae716..3e1facae8 100644
--- a/kernel/log.h
+++ b/kernel/log.h
@@ -80,6 +80,7 @@ void log_warning(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
 
 // Log with filename to report a problem in a source file.
 void log_file_warning(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4));
+void log_file_info(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4));
 
 void log_warning_noprefix(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
 YS_NORETURN void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2), noreturn);
diff --git a/tests/various/elab_sys_tasks.sv b/tests/various/elab_sys_tasks.sv
new file mode 100644
index 000000000..774d85b32
--- /dev/null
+++ b/tests/various/elab_sys_tasks.sv
@@ -0,0 +1,30 @@
+module test;
+localparam X=1;
+genvar i;
+generate
+if (X == 1)
+  $info("X is 1");
+if (X == 1)
+  $warning("X is 1");
+else
+  $error("X is not 1");
+case (X)
+  1: $info("X is 1 in a case statement");
+endcase
+//case (X-1)
+//  1: $warn("X is 2");
+//  default: $warn("X might be anything in a case statement");
+//endcase
+for (i = 0; i < 3; i = i + 1)
+begin
+  case(i)
+    0: $info;
+    1: $warning;
+    default: $info("default case statemnent");
+  endcase
+end
+
+$info("This is a standalone $info(). Next $info has no parameters");
+$info;
+endgenerate
+endmodule
diff --git a/tests/various/elab_sys_tasks.ys b/tests/various/elab_sys_tasks.ys
new file mode 100644
index 000000000..45bee3a60
--- /dev/null
+++ b/tests/various/elab_sys_tasks.ys
@@ -0,0 +1 @@
+read_verilog -sv elab_sys_tasks.sv
-- 
cgit v1.2.3


From 88f59770932720cfc1e987c98e53faedd7388ed8 Mon Sep 17 00:00:00 2001
From: tux3 <barrdetwix@gmail.com>
Date: Wed, 5 Jun 2019 00:47:54 +0200
Subject: SystemVerilog support for implicit named port connections

This is the `foo foo(.port1, .port2);` SystemVerilog syntax
introduced in IEEE1800-2005.
---
 frontends/verilog/verilog_parser.y | 26 +++++++++++++++++---------
 tests/simple/run-test.sh           |  3 ++-
 tests/tools/autotest.sh            | 15 +++++++++++++--
 tests/various/implicit_ports.sv    | 19 +++++++++++++++++++
 tests/various/implicit_ports.ys    |  8 ++++++++
 5 files changed, 59 insertions(+), 12 deletions(-)
 create mode 100644 tests/various/implicit_ports.sv
 create mode 100644 tests/various/implicit_ports.ys

diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 8244a8f44..983445011 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -154,7 +154,7 @@ struct specify_rise_fall {
 %token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_PRIORITY
 
 %type <ast> range range_or_multirange  non_opt_range non_opt_multirange range_or_signed_int
-%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
+%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list named_port
 %type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id
 %type <boolean> opt_signed opt_property unique_case_attr
 %type <al> attr case_attr
@@ -1541,18 +1541,26 @@ cell_port:
 		astbuf2->children.push_back(node);
 		node->children.push_back($1);
 	} |
-	'.' TOK_ID '(' expr ')' {
-		AstNode *node = new AstNode(AST_ARGUMENT);
-		node->str = *$2;
-		astbuf2->children.push_back(node);
-		node->children.push_back($4);
-		delete $2;
+	named_port '(' ')' | // not connected
+	named_port '(' expr ')' {
+		($1)->children.push_back($3);
 	} |
-	'.' TOK_ID '(' ')' {
+	named_port {
+		// SV implied port
+		if (!sv_mode)
+			frontend_verilog_yyerror("Implicit .name port connection in port list (%s). This is not supported unless read_verilog is called with -sv!", $1->str.c_str());
+		auto id_node = new AstNode(AST_IDENTIFIER);
+		id_node->str = ($1)->str;
+		($1)->children.push_back(id_node);
+	};
+
+named_port:
+	'.' TOK_ID {
 		AstNode *node = new AstNode(AST_ARGUMENT);
 		node->str = *$2;
-		astbuf2->children.push_back(node);
 		delete $2;
+		astbuf2->children.push_back(node);
+		$$ = node;
 	};
 
 always_stmt:
diff --git a/tests/simple/run-test.sh b/tests/simple/run-test.sh
index aaa1cf940..967ac49f2 100755
--- a/tests/simple/run-test.sh
+++ b/tests/simple/run-test.sh
@@ -17,4 +17,5 @@ if ! which iverilog > /dev/null ; then
   exit 1
 fi
 
-exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v
+shopt -s nullglob
+exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.{sv,v}
diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh
index 920474a84..0a511f29c 100755
--- a/tests/tools/autotest.sh
+++ b/tests/tools/autotest.sh
@@ -89,6 +89,13 @@ done
 
 compile_and_run() {
 	exe="$1"; output="$2"; shift 2
+	ext=${1##*.}
+	if [ "$ext" == "sv" ]; then
+		language_gen="-g2012"
+	else
+		language_gen="-g2005"
+	fi
+
 	if $use_modelsim; then
 		altver=$( ls -v /opt/altera/ | grep '^[0-9]' | tail -n1; )
 		/opt/altera/$altver/modelsim_ase/bin/vlib work
@@ -99,7 +106,7 @@ compile_and_run() {
 		/opt/Xilinx/Vivado/$xilver/bin/xvlog $xinclude_opts -d outfile=\"$output\" "$@"
 		/opt/Xilinx/Vivado/$xilver/bin/xelab -R work.testbench
 	else
-		iverilog $include_opts -Doutfile=\"$output\" -s testbench -o "$exe" "$@"
+		iverilog $language_gen $include_opts -Doutfile=\"$output\" -s testbench -o "$exe" "$@"
 		vvp -n "$exe"
 	fi
 }
@@ -110,7 +117,7 @@ for fn
 do
 	bn=${fn%.*}
 	ext=${fn##*.}
-	if [[ "$ext" != "v" ]] && [[ "$ext" != "aag" ]] && [[ "$ext" != "aig" ]]; then
+	if [[ "$ext" != "v" ]] && [[ "$ext" != "sv" ]] && [[ "$ext" != "aag" ]] && [[ "$ext" != "aig" ]]; then
 		echo "Invalid argument: $fn" >&2
 		exit 1
 	fi
@@ -123,6 +130,10 @@ do
 		echo -n "Test: $bn "
 	fi
 
+	if [ "$ext" == sv ]; then
+		frontend="$frontend -sv"
+	fi
+
 	rm -f ${bn}.{err,log,skip}
 	mkdir -p ${bn}.out
 	rm -rf ${bn}.out/*
diff --git a/tests/various/implicit_ports.sv b/tests/various/implicit_ports.sv
new file mode 100644
index 000000000..6a766bd51
--- /dev/null
+++ b/tests/various/implicit_ports.sv
@@ -0,0 +1,19 @@
+// Test implicit port connections
+module alu (input [2:0] a, input [2:0] b, input cin, output cout, output [2:0] result);
+	assign cout = cin;
+	assign result = a + b;
+endmodule
+
+module named_ports(output [2:0] alu_result, output cout);
+	wire [2:0] a = 3'b010, b = 3'b100;
+	wire cin = 1;
+
+	alu alu (
+		.a(a),
+		.b, // Implicit connection is equivalent to .b(b)
+		.cin(), // Explicitely unconnected
+		.cout(cout),
+		.result(alu_result)
+	);
+endmodule
+
diff --git a/tests/various/implicit_ports.ys b/tests/various/implicit_ports.ys
new file mode 100644
index 000000000..7b4764921
--- /dev/null
+++ b/tests/various/implicit_ports.ys
@@ -0,0 +1,8 @@
+read_verilog -sv implicit_ports.sv
+proc; opt
+
+flatten
+select -module named_ports
+
+sat -verify -prove alu_result 6
+sat -verify -set-all-undef cout
-- 
cgit v1.2.3


From d018e026142b9903a6f51b0a76ab109e86c4c59b Mon Sep 17 00:00:00 2001
From: Stefan Biereigel <stefan.biereigel@cern.ch>
Date: Fri, 7 Jun 2019 09:47:33 +0200
Subject: remove boost/log/exceptions.hpp from wrapper generator

---
 misc/py_wrap_generator.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/misc/py_wrap_generator.py b/misc/py_wrap_generator.py
index 9f2c72915..9e5727499 100644
--- a/misc/py_wrap_generator.py
+++ b/misc/py_wrap_generator.py
@@ -2026,7 +2026,6 @@ def gen_wrappers(filename, debug_level_ = 0):
 #include <boost/python/wrapper.hpp>
 #include <boost/python/call.hpp>
 #include <boost/python.hpp>
-#include <boost/log/exceptions.hpp>
 
 USING_YOSYS_NAMESPACE
 
-- 
cgit v1.2.3


From a0b57f2a6ffae3b5770e38bf5a9af0df50db8522 Mon Sep 17 00:00:00 2001
From: Clifford Wolf <clifford@clifford.at>
Date: Fri, 7 Jun 2019 11:46:16 +0200
Subject: Cleanup tux3-implicit_named_connection

Signed-off-by: Clifford Wolf <clifford@clifford.at>
---
 frontends/verilog/verilog_parser.y |  2 +-
 tests/simple/implicit_ports.sv     | 16 ++++++++++++++++
 tests/various/implicit_ports.sv    | 19 -------------------
 tests/various/implicit_ports.ys    |  8 --------
 4 files changed, 17 insertions(+), 28 deletions(-)
 create mode 100644 tests/simple/implicit_ports.sv
 delete mode 100644 tests/various/implicit_ports.sv
 delete mode 100644 tests/various/implicit_ports.ys

diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 2fffc7536..6d3afed0e 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -154,7 +154,7 @@ struct specify_rise_fall {
 %token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_PRIORITY
 
 %type <ast> range range_or_multirange  non_opt_range non_opt_multirange range_or_signed_int
-%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list named_port
+%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
 %type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id
 %type <boolean> opt_signed opt_property unique_case_attr
 %type <al> attr case_attr
diff --git a/tests/simple/implicit_ports.sv b/tests/simple/implicit_ports.sv
new file mode 100644
index 000000000..8b0a6f386
--- /dev/null
+++ b/tests/simple/implicit_ports.sv
@@ -0,0 +1,16 @@
+// Test implicit port connections
+module alu (input [2:0] a, input [2:0] b, input cin, output cout, output [2:0] result);
+	assign cout = cin;
+	assign result = a + b;
+endmodule
+
+module named_ports(input [2:0] a, b, output [2:0] alu_result, output cout);
+	wire cin = 1;
+	alu alu (
+		.a(a),
+		.b, // Implicit connection is equivalent to .b(b)
+		.cin(), // Explicitely unconnected
+		.cout(cout),
+		.result(alu_result)
+	);
+endmodule
diff --git a/tests/various/implicit_ports.sv b/tests/various/implicit_ports.sv
deleted file mode 100644
index 6a766bd51..000000000
--- a/tests/various/implicit_ports.sv
+++ /dev/null
@@ -1,19 +0,0 @@
-// Test implicit port connections
-module alu (input [2:0] a, input [2:0] b, input cin, output cout, output [2:0] result);
-	assign cout = cin;
-	assign result = a + b;
-endmodule
-
-module named_ports(output [2:0] alu_result, output cout);
-	wire [2:0] a = 3'b010, b = 3'b100;
-	wire cin = 1;
-
-	alu alu (
-		.a(a),
-		.b, // Implicit connection is equivalent to .b(b)
-		.cin(), // Explicitely unconnected
-		.cout(cout),
-		.result(alu_result)
-	);
-endmodule
-
diff --git a/tests/various/implicit_ports.ys b/tests/various/implicit_ports.ys
deleted file mode 100644
index 7b4764921..000000000
--- a/tests/various/implicit_ports.ys
+++ /dev/null
@@ -1,8 +0,0 @@
-read_verilog -sv implicit_ports.sv
-proc; opt
-
-flatten
-select -module named_ports
-
-sat -verify -prove alu_result 6
-sat -verify -set-all-undef cout
-- 
cgit v1.2.3


From 211d85cfcc1ae701bb9392347bcbb9750e3045b0 Mon Sep 17 00:00:00 2001
From: Clifford Wolf <clifford@clifford.at>
Date: Fri, 7 Jun 2019 12:41:09 +0200
Subject: Fixes and cleanups in AST_TECALL handling

Signed-off-by: Clifford Wolf <clifford@clifford.at>
---
 frontends/ast/ast.h       |  1 -
 frontends/ast/genrtlil.cc | 32 +++++++++++++++++++++++++++++++-
 frontends/ast/simplify.cc | 47 +++--------------------------------------------
 kernel/log.cc             |  8 ++++----
 4 files changed, 38 insertions(+), 50 deletions(-)

diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 93997ab86..b8cde060e 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -234,7 +234,6 @@ namespace AST
 		bool mem2reg_check(pool<AstNode*> &mem2reg_set);
 		void mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes);
 		void meminfo(int &mem_width, int &mem_size, int &addr_bits);
-		bool check_elab_tasks(void);
 
 		// additional functionality for evaluating constant functions
 		struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; };
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index 60a087282..32ed401eb 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -858,7 +858,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 	case AST_GENVAR:
 	case AST_GENFOR:
 	case AST_GENBLOCK:
-	case AST_TECALL:
 	case AST_GENIF:
 	case AST_GENCASE:
 	case AST_PACKAGE:
@@ -1576,6 +1575,37 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 			delete always;
 		} break;
 
+	case AST_TECALL: {
+			int sz = children.size();
+			if (str == "$info") {
+				if (sz > 0)
+					log_file_info(filename, linenum, "%s.\n", children[0]->str.c_str());
+				else
+					log_file_info(filename, linenum, "\n");
+			} else if (str == "$warning") {
+				if (sz > 0)
+					log_file_warning(filename, linenum, "%s.\n", children[0]->str.c_str());
+				else
+					log_file_warning(filename, linenum, "\n");
+			} else if (str == "$error") {
+				if (sz > 0)
+					log_file_error(filename, linenum, "%s.\n", children[0]->str.c_str());
+				else
+					log_file_error(filename, linenum, "\n");
+			} else if (str == "$fatal") {
+				// TODO: 1st parameter, if exists, is 0,1 or 2, and passed to $finish()
+				// if no parameter is given, default value is 1
+				// dollar_finish(sz ? children[0] : 1);
+				// perhaps create & use log_file_fatal()
+				if (sz > 0)
+					log_file_error(filename, linenum, "FATAL: %s.\n", children[0]->str.c_str());
+				else
+					log_file_error(filename, linenum, "FATAL.\n");
+			} else {
+				log_file_error(filename, linenum, "Unknown elabortoon system task '%s'.\n", str.c_str());
+			}
+		} break;
+
 	case AST_FCALL: {
 			if (str == "\\$anyconst" || str == "\\$anyseq" || str == "\\$allconst" || str == "\\$allseq")
 			{
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 66fd243d3..e947125bf 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -1146,8 +1146,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 
 			if (type == AST_GENFOR) {
 				for (size_t i = 0; i < buf->children.size(); i++) {
-					if (!buf->children[i]->check_elab_tasks())
-						buf->children[i]->simplify(false, false, false, stage, -1, false, false);
+					buf->children[i]->simplify(false, false, false, stage, -1, false, false);
 					current_ast_mod->children.push_back(buf->children[i]);
 				}
 			} else {
@@ -1260,8 +1259,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 			}
 
 			for (size_t i = 0; i < buf->children.size(); i++) {
-				if (!buf->children[i]->check_elab_tasks())
-					buf->children[i]->simplify(false, false, false, stage, -1, false, false);
+				buf->children[i]->simplify(false, false, false, stage, -1, false, false);
 				current_ast_mod->children.push_back(buf->children[i]);
 			}
 
@@ -1340,8 +1338,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 			}
 
 			for (size_t i = 0; i < buf->children.size(); i++) {
-				if (!buf->children[i]->check_elab_tasks())
-					buf->children[i]->simplify(false, false, false, stage, -1, false, false);
+				buf->children[i]->simplify(false, false, false, stage, -1, false, false);
 				current_ast_mod->children.push_back(buf->children[i]);
 			}
 
@@ -2971,44 +2968,6 @@ static void mark_memories_assign_lhs_complex(dict<AstNode*, pool<std::string>> &
 	}
 }
 
-// handle $info(), $warning(), $error(), $fatal()
-// we don't do that in simplify() because we don't know 
-bool AstNode::check_elab_tasks(void)
-{
-	if (type == AST_TECALL) {
-		int sz = children.size();
-		if (str == "$info") {
-			if (sz > 0)
-				log_file_info(filename, linenum, "%s.\n", children[0]->str.c_str());
-			else
-				log_file_info(filename, linenum, "\n");
-		} else if (str == "$warning") {
-			if (sz > 0)
-				log_file_warning(filename, linenum, "%s.\n", children[0]->str.c_str());
-			else
-				log_file_warning(filename, linenum, "\n");
-		} else if (str == "$error") {
-			if (sz > 0)
-				log_file_error(filename, linenum, "%s.\n", children[0]->str.c_str());
-			else
-				log_file_error(filename, linenum, "\n");
-		} else if (str == "$fatal") {
-			// TODO: 1st parameter, if exists, is 0,1 or 2, and passed to $finish()
-			// if no parameter is given, default value is 1
-			// dollar_finish(sz ? children[0] : 1);
-			// perhaps create & use log_file_fatal()
-			if (sz > 0)
-				log_file_error(filename, linenum, "FATAL: %s.\n", children[0]->str.c_str());
-			else
-				log_file_error(filename, linenum, "FATAL.\n");
-		} else {
-			log_file_error(filename, linenum, "Unknown elabortoon system task '%s'.\n", str.c_str());
-		}
-		return true;
-	}
-	return false;
-
-}
 // find memories that should be replaced by registers
 void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg_places,
 		dict<AstNode*, uint32_t> &mem2reg_candidates, dict<AstNode*, uint32_t> &proc_flags, uint32_t &flags)
diff --git a/kernel/log.cc b/kernel/log.cc
index 9ce952cae..a7820950c 100644
--- a/kernel/log.cc
+++ b/kernel/log.cc
@@ -277,7 +277,7 @@ void log_file_warning(const std::string &filename, int lineno,
 	va_list ap;
 	va_start(ap, format);
 	std::string prefix = stringf("%s:%d: Warning: ",
-				     filename.c_str(), lineno);
+			filename.c_str(), lineno);
 	logv_warning_with_prefix(prefix.c_str(), format, ap);
 	va_end(ap);
 }
@@ -287,9 +287,9 @@ void log_file_info(const std::string &filename, int lineno,
 {
 	va_list ap;
 	va_start(ap, format);
-	std::string prefix = stringf("%s:%d: Info: ",
-				     filename.c_str(), lineno);
-	logv_warning_with_prefix(prefix.c_str(), format, ap);
+	std::string fmt = stringf("%s:%d: Info: %s",
+			filename.c_str(), lineno, format);
+	logv(fmt.c_str(), ap);
 	va_end(ap);
 }
 
-- 
cgit v1.2.3


From f01a61f093528e5111e5dac8aedbf8c7c468be1c Mon Sep 17 00:00:00 2001
From: Clifford Wolf <clifford@clifford.at>
Date: Fri, 7 Jun 2019 13:12:25 +0200
Subject: Rename implicit_ports.sv test to implicit_ports.v

Signed-off-by: Clifford Wolf <clifford@clifford.at>
---
 tests/simple/implicit_ports.sv | 16 ----------------
 tests/simple/implicit_ports.v  | 16 ++++++++++++++++
 2 files changed, 16 insertions(+), 16 deletions(-)
 delete mode 100644 tests/simple/implicit_ports.sv
 create mode 100644 tests/simple/implicit_ports.v

diff --git a/tests/simple/implicit_ports.sv b/tests/simple/implicit_ports.sv
deleted file mode 100644
index 8b0a6f386..000000000
--- a/tests/simple/implicit_ports.sv
+++ /dev/null
@@ -1,16 +0,0 @@
-// Test implicit port connections
-module alu (input [2:0] a, input [2:0] b, input cin, output cout, output [2:0] result);
-	assign cout = cin;
-	assign result = a + b;
-endmodule
-
-module named_ports(input [2:0] a, b, output [2:0] alu_result, output cout);
-	wire cin = 1;
-	alu alu (
-		.a(a),
-		.b, // Implicit connection is equivalent to .b(b)
-		.cin(), // Explicitely unconnected
-		.cout(cout),
-		.result(alu_result)
-	);
-endmodule
diff --git a/tests/simple/implicit_ports.v b/tests/simple/implicit_ports.v
new file mode 100644
index 000000000..8b0a6f386
--- /dev/null
+++ b/tests/simple/implicit_ports.v
@@ -0,0 +1,16 @@
+// Test implicit port connections
+module alu (input [2:0] a, input [2:0] b, input cin, output cout, output [2:0] result);
+	assign cout = cin;
+	assign result = a + b;
+endmodule
+
+module named_ports(input [2:0] a, b, output [2:0] alu_result, output cout);
+	wire cin = 1;
+	alu alu (
+		.a(a),
+		.b, // Implicit connection is equivalent to .b(b)
+		.cin(), // Explicitely unconnected
+		.cout(cout),
+		.result(alu_result)
+	);
+endmodule
-- 
cgit v1.2.3


From 1b113a05742377f5b18d52bc5bf50b1991e88c19 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 7 Jun 2019 11:05:25 -0700
Subject: Add symbols to AIGER test inputs for ABC

---
 tests/aiger/and.aag      | 5 -----
 tests/aiger/and.aig      | 3 ---
 tests/aiger/and_.aag     | 8 ++++++++
 tests/aiger/and_.aig     | 5 +++++
 tests/aiger/buffer.aag   | 2 ++
 tests/aiger/buffer.aig   | 2 ++
 tests/aiger/cnt1.aag     | 1 +
 tests/aiger/cnt1.aig     | 1 +
 tests/aiger/cnt1e.aag    | 1 +
 tests/aiger/cnt1e.aig    | 3 ++-
 tests/aiger/false.aag    | 1 +
 tests/aiger/false.aig    | 1 +
 tests/aiger/inverter.aag | 2 ++
 tests/aiger/inverter.aig | 2 ++
 tests/aiger/notcnt1e.aag | 1 +
 tests/aiger/notcnt1e.aig | 3 ++-
 tests/aiger/or.aag       | 5 -----
 tests/aiger/or.aig       | 3 ---
 tests/aiger/or_.aag      | 8 ++++++++
 tests/aiger/or_.aig      | 5 +++++
 tests/aiger/toggle.aag   | 2 ++
 tests/aiger/toggle.aig   | 2 ++
 tests/aiger/true.aag     | 1 +
 tests/aiger/true.aig     | 1 +
 24 files changed, 50 insertions(+), 18 deletions(-)
 delete mode 100644 tests/aiger/and.aag
 delete mode 100644 tests/aiger/and.aig
 create mode 100644 tests/aiger/and_.aag
 create mode 100644 tests/aiger/and_.aig
 delete mode 100644 tests/aiger/or.aag
 delete mode 100644 tests/aiger/or.aig
 create mode 100644 tests/aiger/or_.aag
 create mode 100644 tests/aiger/or_.aig

diff --git a/tests/aiger/and.aag b/tests/aiger/and.aag
deleted file mode 100644
index d1ef2c5a5..000000000
--- a/tests/aiger/and.aag
+++ /dev/null
@@ -1,5 +0,0 @@
-aag 3 2 0 1 1
-2
-4
-6
-6 2 4
diff --git a/tests/aiger/and.aig b/tests/aiger/and.aig
deleted file mode 100644
index da0fa0719..000000000
--- a/tests/aiger/and.aig
+++ /dev/null
@@ -1,3 +0,0 @@
-aig 3 2 0 1 1
-6
-
\ No newline at end of file
diff --git a/tests/aiger/and_.aag b/tests/aiger/and_.aag
new file mode 100644
index 000000000..cadd505f0
--- /dev/null
+++ b/tests/aiger/and_.aag
@@ -0,0 +1,8 @@
+aag 3 2 0 1 1
+2
+4
+6
+6 2 4
+i0 pi0
+i1 pi1
+o0 po0
diff --git a/tests/aiger/and_.aig b/tests/aiger/and_.aig
new file mode 100644
index 000000000..13c7a0c17
--- /dev/null
+++ b/tests/aiger/and_.aig
@@ -0,0 +1,5 @@
+aig 3 2 0 1 1
+6
+i0 pi0
+i1 pi1
+o0 po0
diff --git a/tests/aiger/buffer.aag b/tests/aiger/buffer.aag
index 94a6fb1ed..211106ed6 100644
--- a/tests/aiger/buffer.aag
+++ b/tests/aiger/buffer.aag
@@ -1,3 +1,5 @@
 aag 1 1 0 1 0
 2
 2
+i0 pi0
+o0 po0
diff --git a/tests/aiger/buffer.aig b/tests/aiger/buffer.aig
index 0c715fdeb..01df6f1cf 100644
--- a/tests/aiger/buffer.aig
+++ b/tests/aiger/buffer.aig
@@ -1,2 +1,4 @@
 aig 1 1 0 1 0
 2
+i0 pi0
+o0 po0
diff --git a/tests/aiger/cnt1.aag b/tests/aiger/cnt1.aag
index ce4f28fcb..75598862c 100644
--- a/tests/aiger/cnt1.aag
+++ b/tests/aiger/cnt1.aag
@@ -1,3 +1,4 @@
 aag 1 0 1 0 0 1
 2 3
 2
+b0 po0
diff --git a/tests/aiger/cnt1.aig b/tests/aiger/cnt1.aig
index 8d0ba13b1..6fcf62522 100644
--- a/tests/aiger/cnt1.aig
+++ b/tests/aiger/cnt1.aig
@@ -1,3 +1,4 @@
 aig 1 0 1 0 0 1
 3
 2
+b0 po0
diff --git a/tests/aiger/cnt1e.aag b/tests/aiger/cnt1e.aag
index 6db3f0ffd..35cd5a482 100644
--- a/tests/aiger/cnt1e.aag
+++ b/tests/aiger/cnt1e.aag
@@ -6,3 +6,4 @@ aag 5 1 1 0 3 1
 8 4 2
 10 9 7
 b0 AIGER_NEVER
+i0 po0
diff --git a/tests/aiger/cnt1e.aig b/tests/aiger/cnt1e.aig
index d8d159f11..7284dd42a 100644
--- a/tests/aiger/cnt1e.aig
+++ b/tests/aiger/cnt1e.aig
@@ -1,4 +1,5 @@
 aig 5 1 1 0 3 1
 10
 4
-b0 AIGER_NEVER
+i0 po0
+b0 AIGER_NEVER
diff --git a/tests/aiger/false.aag b/tests/aiger/false.aag
index 421e64a91..bab4a06a6 100644
--- a/tests/aiger/false.aag
+++ b/tests/aiger/false.aag
@@ -1,2 +1,3 @@
 aag 0 0 0 1 0
 0
+o0 po0
diff --git a/tests/aiger/false.aig b/tests/aiger/false.aig
index ad7d039fa..4dc442d7b 100644
--- a/tests/aiger/false.aig
+++ b/tests/aiger/false.aig
@@ -1,2 +1,3 @@
 aig 0 0 0 1 0
 0
+o0 po0
diff --git a/tests/aiger/inverter.aag b/tests/aiger/inverter.aag
index ff7c28542..428bad9e4 100644
--- a/tests/aiger/inverter.aag
+++ b/tests/aiger/inverter.aag
@@ -1,3 +1,5 @@
 aag 1 1 0 1 0
 2
 3
+i0 pi0
+o0 po0
diff --git a/tests/aiger/inverter.aig b/tests/aiger/inverter.aig
index 525d82392..5bec90ae3 100644
--- a/tests/aiger/inverter.aig
+++ b/tests/aiger/inverter.aig
@@ -1,2 +1,4 @@
 aig 1 1 0 1 0
 3
+i0 pi0
+o0 po0
diff --git a/tests/aiger/notcnt1e.aag b/tests/aiger/notcnt1e.aag
index 141c864f7..2ed645d84 100644
--- a/tests/aiger/notcnt1e.aag
+++ b/tests/aiger/notcnt1e.aag
@@ -6,3 +6,4 @@ aag 5 1 1 0 3 1
 8 4 2
 10 9 7
 b0 AIGER_NEVER
+i0 pi0
diff --git a/tests/aiger/notcnt1e.aig b/tests/aiger/notcnt1e.aig
index 7c85a7290..fd7e94508 100644
--- a/tests/aiger/notcnt1e.aig
+++ b/tests/aiger/notcnt1e.aig
@@ -1,4 +1,5 @@
 aig 5 1 1 0 3 1
 10
 5
-b0 AIGER_NEVER
+i0 pi0
+b0 AIGER_NEVER
diff --git a/tests/aiger/or.aag b/tests/aiger/or.aag
deleted file mode 100644
index f780e339f..000000000
--- a/tests/aiger/or.aag
+++ /dev/null
@@ -1,5 +0,0 @@
-aag 3 2 0 1 1
-2
-4
-7
-6 3 5
diff --git a/tests/aiger/or.aig b/tests/aiger/or.aig
deleted file mode 100644
index 75c9e4480..000000000
--- a/tests/aiger/or.aig
+++ /dev/null
@@ -1,3 +0,0 @@
-aig 3 2 0 1 1
-7
-
\ No newline at end of file
diff --git a/tests/aiger/or_.aag b/tests/aiger/or_.aag
new file mode 100644
index 000000000..0f619dba3
--- /dev/null
+++ b/tests/aiger/or_.aag
@@ -0,0 +1,8 @@
+aag 3 2 0 1 1
+2
+4
+7
+6 3 5
+i0 pi0
+i1 pi1
+o0 po0
diff --git a/tests/aiger/or_.aig b/tests/aiger/or_.aig
new file mode 100644
index 000000000..051687512
--- /dev/null
+++ b/tests/aiger/or_.aig
@@ -0,0 +1,5 @@
+aig 3 2 0 1 1
+7
+i0 pi0
+i1 pi1
+o0 po0
diff --git a/tests/aiger/toggle.aag b/tests/aiger/toggle.aag
index 09651012d..b1a1582d7 100644
--- a/tests/aiger/toggle.aag
+++ b/tests/aiger/toggle.aag
@@ -2,3 +2,5 @@ aag 1 0 1 2 0
 2 3
 2
 3
+o0 po0
+o1 po1
diff --git a/tests/aiger/toggle.aig b/tests/aiger/toggle.aig
index b69e21aaf..68b41763f 100644
--- a/tests/aiger/toggle.aig
+++ b/tests/aiger/toggle.aig
@@ -2,3 +2,5 @@ aig 1 0 1 2 0
 3
 2
 3
+o0 po0
+o1 po1
diff --git a/tests/aiger/true.aag b/tests/aiger/true.aag
index 366893648..66a9eab46 100644
--- a/tests/aiger/true.aag
+++ b/tests/aiger/true.aag
@@ -1,2 +1,3 @@
 aag 0 0 0 1 0
 1
+o0 po0
diff --git a/tests/aiger/true.aig b/tests/aiger/true.aig
index 10086f389..f9bad6000 100644
--- a/tests/aiger/true.aig
+++ b/tests/aiger/true.aig
@@ -1,2 +1,3 @@
 aig 0 0 0 1 0
 1
+o0 po0
-- 
cgit v1.2.3


From ebe29b66593414d0317879359d1f1d1f61a9ecc4 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 7 Jun 2019 11:05:36 -0700
Subject: Use ABC to convert AIGER to Verilog, then sat against Yosys

---
 tests/aiger/run-test.sh | 36 +++++++++++++++---------------------
 1 file changed, 15 insertions(+), 21 deletions(-)

diff --git a/tests/aiger/run-test.sh b/tests/aiger/run-test.sh
index e0a34f023..70300d305 100755
--- a/tests/aiger/run-test.sh
+++ b/tests/aiger/run-test.sh
@@ -1,24 +1,18 @@
 #!/bin/bash
 
-OPTIND=1
-seed=""    # default to no seed specified
-while getopts "S:" opt
-do
-    case "$opt" in
-	S) arg="${OPTARG#"${OPTARG%%[![:space:]]*}"}" # remove leading space
-	   seed="SEED=$arg" ;;
-    esac
+set -e
+for aig in *.aig; do
+    ../../yosys-abc -c "read -c $aig; write ${aig%.*}_ref.v"
+    ../../yosys -p "
+read_verilog ${aig%.*}_ref.v
+prep
+design -stash gold
+read_aiger -clk_name clock $aig
+prep
+design -stash gate
+design -import gold -as gold
+design -import gate -as gate
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports -seq 16 miter
+"
 done
-shift "$((OPTIND-1))"
-
-# check for Icarus Verilog
-if ! which iverilog > /dev/null ; then
-  echo "$0: Error: Icarus Verilog 'iverilog' not found."
-  exit 1
-fi
-
-echo "===== AAG ======"
-${MAKE:-make} -f ../tools/autotest.mk $seed *.aag EXTRA_FLAGS="-f aiger"
-
-echo "===== AIG ======"
-exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.aig EXTRA_FLAGS="-f aiger"
-- 
cgit v1.2.3


From abc40924ed5dc4aba91c7f1e83ca90f54e9eb455 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 7 Jun 2019 11:06:57 -0700
Subject: Use ABC to convert from AIGER to Verilog

---
 tests/tools/autotest.sh | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh
index 0a511f29c..23964a751 100755
--- a/tests/tools/autotest.sh
+++ b/tests/tools/autotest.sh
@@ -146,9 +146,10 @@ do
 		rm -f ${bn}_ref.fir
 		if [[ "$ext" == "v" ]]; then
 			egrep -v '^\s*`timescale' ../$fn > ${bn}_ref.${ext}
+		elif [[ "$ext" == "aig" ]] || [[ "$ext" == "aag" ]]; then
+			"$toolsdir"/../../yosys-abc -c "read_aiger ../${fn}; write ${bn}_ref.v"
 		else
-			"$toolsdir"/../../yosys -f "$frontend $include_opts" -b "verilog" -o ${bn}_ref.v ../${fn}
-			frontend="verilog -noblackbox"
+			cp ../${fn} ${bn}_ref.${ext}
 		fi
 
 		if [ ! -f ../${bn}_tb.v ]; then
-- 
cgit v1.2.3


From a04521c6b70396a590f0ddb3081c4c5d6b01671e Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 7 Jun 2019 11:07:15 -0700
Subject: Fix read_aiger -- create zero driver, fix init width, parse 'b'

---
 frontends/aiger/aigerparse.cc | 64 ++++++++++++++++++++++++++++++++++---------
 frontends/aiger/aigerparse.h  |  1 +
 2 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc
index 38348cd65..26b101e4c 100644
--- a/frontends/aiger/aigerparse.cc
+++ b/frontends/aiger/aigerparse.cc
@@ -81,11 +81,26 @@ end_of_header:
     else
         log_abort();
 
+	RTLIL::Wire* n0 = module->wire("\\n0");
+	if (n0)
+		module->connect(n0, RTLIL::S0);
+
+    for (unsigned i = 0; i < outputs.size(); ++i) {
+        RTLIL::Wire *wire = outputs[i];
+        if (wire->port_input) {
+            RTLIL::Wire *o_wire = module->addWire(wire->name.str() + "_o");
+            o_wire->port_output = true;
+            wire->port_output = false;
+            module->connect(o_wire, wire);
+            outputs[i] = o_wire;
+        }
+    }
+
     // Parse footer (symbol table, comments, etc.)
     unsigned l1;
     std::string s;
     for (int c = f.peek(); c != EOF; c = f.peek(), ++line_count) {
-        if (c == 'i' || c == 'l' || c == 'o') {
+        if (c == 'i' || c == 'l' || c == 'o' || c == 'b') {
             f.ignore(1);
             if (!(f >> l1 >> s))
                 log_error("Line %u cannot be interpreted as a symbol entry!\n", line_count);
@@ -97,11 +112,12 @@ end_of_header:
             if (c == 'i') wire = inputs[l1];
             else if (c == 'l') wire = latches[l1];
             else if (c == 'o') wire = outputs[l1];
+            else if (c == 'b') wire = bad_properties[l1];
             else log_abort();
 
             module->rename(wire, stringf("\\%s", s.c_str()));
         }
-        else if (c == 'b' || c == 'j' || c == 'f') {
+        else if (c == 'j' || c == 'f') {
             // TODO
         }
         else if (c == 'c') {
@@ -153,7 +169,7 @@ void AigerReader::parse_aiger_ascii()
     unsigned l1, l2, l3;
 
     // Parse inputs
-    for (unsigned i = 0; i < I; ++i, ++line_count) {
+    for (unsigned i = 1; i <= I; ++i, ++line_count) {
         if (!(f >> l1))
             log_error("Line %u cannot be interpreted as an input!\n", line_count);
         log_debug("%d is an input\n", l1);
@@ -187,8 +203,10 @@ void AigerReader::parse_aiger_ascii()
             if (!(f >> l3))
                 log_error("Line %u cannot be interpreted as a latch!\n", line_count);
 
-            if (l3 == 0 || l3 == 1)
-                q_wire->attributes["\\init"] = RTLIL::Const(l3);
+            if (l3 == 0)
+                q_wire->attributes["\\init"] = RTLIL::S0;
+            else if (l3 == 1)
+                q_wire->attributes["\\init"] = RTLIL::S1;
             else if (l3 == l1) {
                 //q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
             }
@@ -197,7 +215,7 @@ void AigerReader::parse_aiger_ascii()
         }
         else {
             // AIGER latches are assumed to be initialized to zero
-            q_wire->attributes["\\init"] = RTLIL::Const(0);
+            q_wire->attributes["\\init"] = RTLIL::S0;
         }
         latches.push_back(q_wire);
     }
@@ -214,8 +232,17 @@ void AigerReader::parse_aiger_ascii()
     }
     std::getline(f, line); // Ignore up to start of next line
 
-    // TODO: Parse bad state properties
-    for (unsigned i = 0; i < B; ++i, ++line_count)
+    // Parse bad properties
+    for (unsigned i = 0; i < B; ++i, ++line_count) {
+        if (!(f >> l1))
+            log_error("Line %u cannot be interpreted as a bad state property!\n", line_count);
+
+        log_debug("%d is a bad state property\n", l1);
+        RTLIL::Wire *wire = createWireIfNotExists(module, l1);
+        wire->port_output = true;
+        bad_properties.push_back(wire);
+    }
+    if (B > 0)
         std::getline(f, line); // Ignore up to start of next line
 
     // TODO: Parse invariant constraints
@@ -290,8 +317,10 @@ void AigerReader::parse_aiger_binary()
             if (!(f >> l3))
                 log_error("Line %u cannot be interpreted as a latch!\n", line_count);
 
-            if (l3 == 0 || l3 == 1)
-                q_wire->attributes["\\init"] = RTLIL::Const(l3);
+            if (l3 == 0)
+                q_wire->attributes["\\init"] = RTLIL::S0;
+            else if (l3 == 1)
+                q_wire->attributes["\\init"] = RTLIL::S1;
             else if (l3 == l1) {
                 //q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
             }
@@ -300,7 +329,7 @@ void AigerReader::parse_aiger_binary()
         }
         else {
             // AIGER latches are assumed to be initialized to zero
-            q_wire->attributes["\\init"] = RTLIL::Const(0);
+            q_wire->attributes["\\init"] = RTLIL::S0;
         }
         latches.push_back(q_wire);
     }
@@ -317,8 +346,17 @@ void AigerReader::parse_aiger_binary()
     }
     std::getline(f, line); // Ignore up to start of next line
 
-    // TODO: Parse bad state properties
-    for (unsigned i = 0; i < B; ++i, ++line_count)
+    // Parse bad properties
+    for (unsigned i = 0; i < B; ++i, ++line_count) {
+        if (!(f >> l1))
+            log_error("Line %u cannot be interpreted as a bad state property!\n", line_count);
+
+        log_debug("%d is a bad state property\n", l1);
+        RTLIL::Wire *wire = createWireIfNotExists(module, l1);
+        wire->port_output = true;
+        bad_properties.push_back(wire);
+    }
+    if (B > 0)
         std::getline(f, line); // Ignore up to start of next line
 
     // TODO: Parse invariant constraints
diff --git a/frontends/aiger/aigerparse.h b/frontends/aiger/aigerparse.h
index c49cd152d..0e3719cc4 100644
--- a/frontends/aiger/aigerparse.h
+++ b/frontends/aiger/aigerparse.h
@@ -39,6 +39,7 @@ struct AigerReader
     std::vector<RTLIL::Wire*> inputs;
     std::vector<RTLIL::Wire*> latches;
     std::vector<RTLIL::Wire*> outputs;
+    std::vector<RTLIL::Wire*> bad_properties;
 
     AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name);
     void parse_aiger();
-- 
cgit v1.2.3


From 65924fd12f48b4ec5a4d51efeea977992d033ecf Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 7 Jun 2019 11:28:05 -0700
Subject: Test *.aag too, by using *.aig as reference

---
 tests/aiger/run-test.sh | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/tests/aiger/run-test.sh b/tests/aiger/run-test.sh
index 70300d305..e56d0fa80 100755
--- a/tests/aiger/run-test.sh
+++ b/tests/aiger/run-test.sh
@@ -1,6 +1,25 @@
 #!/bin/bash
 
 set -e
+
+for aag in *.aag; do
+    # Since ABC cannot read *.aag, read the *.aig instead
+    # (which would have been created by the reference aig2aig utility)
+    ../../yosys-abc -c "read -c ${aag%.*}.aig; write ${aag%.*}_ref.v"
+    ../../yosys -p "
+read_verilog ${aag%.*}_ref.v
+prep
+design -stash gold
+read_aiger -clk_name clock $aag
+prep
+design -stash gate
+design -import gold -as gold
+design -import gate -as gate
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports -seq 16 miter
+"
+done
+
 for aig in *.aig; do
     ../../yosys-abc -c "read -c $aig; write ${aig%.*}_ref.v"
     ../../yosys -p "
-- 
cgit v1.2.3


From d00ae1d6a8c0a1e147599ee27f6a4ea68f43267e Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 7 Jun 2019 11:28:25 -0700
Subject: Remove unnecessary std::getline() for ASCII

---
 frontends/aiger/aigerparse.cc | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc
index 26b101e4c..d0338e45d 100644
--- a/frontends/aiger/aigerparse.cc
+++ b/frontends/aiger/aigerparse.cc
@@ -230,7 +230,6 @@ void AigerReader::parse_aiger_ascii()
         wire->port_output = true;
         outputs.push_back(wire);
     }
-    std::getline(f, line); // Ignore up to start of next line
 
     // Parse bad properties
     for (unsigned i = 0; i < B; ++i, ++line_count) {
@@ -242,8 +241,6 @@ void AigerReader::parse_aiger_ascii()
         wire->port_output = true;
         bad_properties.push_back(wire);
     }
-    if (B > 0)
-        std::getline(f, line); // Ignore up to start of next line
 
     // TODO: Parse invariant constraints
     for (unsigned i = 0; i < C; ++i, ++line_count)
-- 
cgit v1.2.3


From 6934f4bdd53cb226d0c8631eff691d9a96aebbce Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 7 Jun 2019 11:30:36 -0700
Subject: Fix spacing (entire file is wrong anyway, will fix later)

---
 frontends/aiger/aigerparse.cc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc
index d0338e45d..32be4cf6c 100644
--- a/frontends/aiger/aigerparse.cc
+++ b/frontends/aiger/aigerparse.cc
@@ -81,9 +81,9 @@ end_of_header:
     else
         log_abort();
 
-	RTLIL::Wire* n0 = module->wire("\\n0");
-	if (n0)
-		module->connect(n0, RTLIL::S0);
+    RTLIL::Wire* n0 = module->wire("\\n0");
+    if (n0)
+        module->connect(n0, RTLIL::S0);
 
     for (unsigned i = 0; i < outputs.size(); ++i) {
         RTLIL::Wire *wire = outputs[i];
-- 
cgit v1.2.3


From f48c6920b7aa777c0c569f444e3db88211835cec Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 7 Jun 2019 13:12:48 -0700
Subject: Add read_aiger to CHANGELOG

---
 CHANGELOG | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG b/CHANGELOG
index 36b64e111..839fefcf1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,7 @@ Yosys 0.8 .. Yosys 0.8-dev
     - Added "gate2lut.v" techmap rule
     - Added "rename -src"
     - Added "equiv_opt" pass
+    - Added "read_aiger" frontend
     - "synth_xilinx" to now infer hard shift registers, using new "shregmap -tech xilinx"
 
 
-- 
cgit v1.2.3


From 2b350401c4577d54c0d460240e2d2847d2eeadc4 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 7 Jun 2019 15:44:57 -0700
Subject: Fix spacing from spaces to tabs

---
 frontends/aiger/aigerparse.cc | 724 +++++++++++++++++++++---------------------
 1 file changed, 362 insertions(+), 362 deletions(-)

diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc
index 32be4cf6c..68552fd06 100644
--- a/frontends/aiger/aigerparse.cc
+++ b/frontends/aiger/aigerparse.cc
@@ -34,389 +34,389 @@
 YOSYS_NAMESPACE_BEGIN
 
 AigerReader::AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name)
-    : design(design), f(f), clk_name(clk_name)
+	: design(design), f(f), clk_name(clk_name)
 {
-    module = new RTLIL::Module;
-    module->name = module_name;
-    if (design->module(module->name))
-        log_error("Duplicate definition of module %s!\n", log_id(module->name));
+	module = new RTLIL::Module;
+	module->name = module_name;
+	if (design->module(module->name))
+		log_error("Duplicate definition of module %s!\n", log_id(module->name));
 }
 
 void AigerReader::parse_aiger()
 {
-    std::string header;
-    f >> header;
-    if (header != "aag" && header != "aig")
-        log_error("Unsupported AIGER file!\n");
-
-    // Parse rest of header
-    if (!(f >> M >> I >> L >> O >> A))
-        log_error("Invalid AIGER header\n");
-
-    // Optional values
-    B = C = J = F = 0;
-    if (f.peek() != ' ') goto end_of_header;
-    if (!(f >> B)) log_error("Invalid AIGER header\n");
-    if (f.peek() != ' ') goto end_of_header;
-    if (!(f >> C)) log_error("Invalid AIGER header\n");
-    if (f.peek() != ' ') goto end_of_header;
-    if (!(f >> J)) log_error("Invalid AIGER header\n");
-    if (f.peek() != ' ') goto end_of_header;
-    if (!(f >> F)) log_error("Invalid AIGER header\n");
+	std::string header;
+	f >> header;
+	if (header != "aag" && header != "aig")
+		log_error("Unsupported AIGER file!\n");
+
+	// Parse rest of header
+	if (!(f >> M >> I >> L >> O >> A))
+		log_error("Invalid AIGER header\n");
+
+	// Optional values
+	B = C = J = F = 0;
+	if (f.peek() != ' ') goto end_of_header;
+	if (!(f >> B)) log_error("Invalid AIGER header\n");
+	if (f.peek() != ' ') goto end_of_header;
+	if (!(f >> C)) log_error("Invalid AIGER header\n");
+	if (f.peek() != ' ') goto end_of_header;
+	if (!(f >> J)) log_error("Invalid AIGER header\n");
+	if (f.peek() != ' ') goto end_of_header;
+	if (!(f >> F)) log_error("Invalid AIGER header\n");
 end_of_header:
 
-    std::string line;
-    std::getline(f, line); // Ignore up to start of next line, as standard
-                           // says anything that follows could be used for
-                           // optional sections
-
-    log_debug("M=%u I=%u L=%u O=%u A=%u B=%u C=%u J=%u F=%u\n", M, I, L, O, A, B, C, J, F);
-
-    line_count = 1;
-
-    if (header == "aag")
-        parse_aiger_ascii();
-    else if (header == "aig")
-        parse_aiger_binary();
-    else
-        log_abort();
-
-    RTLIL::Wire* n0 = module->wire("\\n0");
-    if (n0)
-        module->connect(n0, RTLIL::S0);
-
-    for (unsigned i = 0; i < outputs.size(); ++i) {
-        RTLIL::Wire *wire = outputs[i];
-        if (wire->port_input) {
-            RTLIL::Wire *o_wire = module->addWire(wire->name.str() + "_o");
-            o_wire->port_output = true;
-            wire->port_output = false;
-            module->connect(o_wire, wire);
-            outputs[i] = o_wire;
-        }
-    }
-
-    // Parse footer (symbol table, comments, etc.)
-    unsigned l1;
-    std::string s;
-    for (int c = f.peek(); c != EOF; c = f.peek(), ++line_count) {
-        if (c == 'i' || c == 'l' || c == 'o' || c == 'b') {
-            f.ignore(1);
-            if (!(f >> l1 >> s))
-                log_error("Line %u cannot be interpreted as a symbol entry!\n", line_count);
-
-            if ((c == 'i' && l1 > inputs.size()) || (c == 'l' && l1 > latches.size()) || (c == 'o' && l1 > outputs.size()))
-                log_error("Line %u has invalid symbol position!\n", line_count);
-
-            RTLIL::Wire* wire;
-            if (c == 'i') wire = inputs[l1];
-            else if (c == 'l') wire = latches[l1];
-            else if (c == 'o') wire = outputs[l1];
-            else if (c == 'b') wire = bad_properties[l1];
-            else log_abort();
-
-            module->rename(wire, stringf("\\%s", s.c_str()));
-        }
-        else if (c == 'j' || c == 'f') {
-            // TODO
-        }
-        else if (c == 'c') {
-            f.ignore(1);
-            if (f.peek() == '\n')
-                break;
-            // Else constraint (TODO)
-        }
-        else
-            log_error("Line %u: cannot interpret first character '%c'!\n", line_count, c);
-        std::getline(f, line); // Ignore up to start of next line
-    }
-
-    module->fixup_ports();
-    design->add(module);
+	std::string line;
+	std::getline(f, line); // Ignore up to start of next line, as standard
+	// says anything that follows could be used for
+	// optional sections
+
+	log_debug("M=%u I=%u L=%u O=%u A=%u B=%u C=%u J=%u F=%u\n", M, I, L, O, A, B, C, J, F);
+
+	line_count = 1;
+
+	if (header == "aag")
+		parse_aiger_ascii();
+	else if (header == "aig")
+		parse_aiger_binary();
+	else
+		log_abort();
+
+	RTLIL::Wire* n0 = module->wire("\\n0");
+	if (n0)
+		module->connect(n0, RTLIL::S0);
+
+	for (unsigned i = 0; i < outputs.size(); ++i) {
+		RTLIL::Wire *wire = outputs[i];
+		if (wire->port_input) {
+			RTLIL::Wire *o_wire = module->addWire(wire->name.str() + "_o");
+			o_wire->port_output = true;
+			wire->port_output = false;
+			module->connect(o_wire, wire);
+			outputs[i] = o_wire;
+		}
+	}
+
+	// Parse footer (symbol table, comments, etc.)
+	unsigned l1;
+	std::string s;
+	for (int c = f.peek(); c != EOF; c = f.peek(), ++line_count) {
+		if (c == 'i' || c == 'l' || c == 'o' || c == 'b') {
+			f.ignore(1);
+			if (!(f >> l1 >> s))
+				log_error("Line %u cannot be interpreted as a symbol entry!\n", line_count);
+
+			if ((c == 'i' && l1 > inputs.size()) || (c == 'l' && l1 > latches.size()) || (c == 'o' && l1 > outputs.size()))
+				log_error("Line %u has invalid symbol position!\n", line_count);
+
+			RTLIL::Wire* wire;
+			if (c == 'i') wire = inputs[l1];
+			else if (c == 'l') wire = latches[l1];
+			else if (c == 'o') wire = outputs[l1];
+			else if (c == 'b') wire = bad_properties[l1];
+			else log_abort();
+
+			module->rename(wire, stringf("\\%s", s.c_str()));
+		}
+		else if (c == 'j' || c == 'f') {
+			// TODO
+		}
+		else if (c == 'c') {
+			f.ignore(1);
+			if (f.peek() == '\n')
+				break;
+			// Else constraint (TODO)
+		}
+		else
+			log_error("Line %u: cannot interpret first character '%c'!\n", line_count, c);
+		std::getline(f, line); // Ignore up to start of next line
+	}
+
+	module->fixup_ports();
+	design->add(module);
 }
 
 static RTLIL::Wire* createWireIfNotExists(RTLIL::Module *module, unsigned literal)
 {
-    const unsigned variable = literal >> 1;
-    const bool invert = literal & 1;
-    RTLIL::IdString wire_name(stringf("\\n%d%s", variable, invert ? "_inv" : "")); // FIXME: is "_inv" the right suffix?
-    RTLIL::Wire *wire = module->wire(wire_name);
-    if (wire) return wire;
-    log_debug("Creating %s\n", wire_name.c_str());
-    wire = module->addWire(wire_name);
-    if (!invert) return wire;
-    RTLIL::IdString wire_inv_name(stringf("\\n%d", variable));
-    RTLIL::Wire *wire_inv = module->wire(wire_inv_name);
-    if (wire_inv) {
-        if (module->cell(wire_inv_name)) return wire;
-    }
-    else {
-        log_debug("Creating %s\n", wire_inv_name.c_str());
-        wire_inv = module->addWire(wire_inv_name);
-    }
-
-    log_debug("Creating %s = ~%s\n", wire_name.c_str(), wire_inv_name.c_str());
-    module->addNotGate(stringf("\\n%d_not", variable), wire_inv, wire); // FIXME: is "_not" the right suffix?
-
-    return wire;
+	const unsigned variable = literal >> 1;
+	const bool invert = literal & 1;
+	RTLIL::IdString wire_name(stringf("\\n%d%s", variable, invert ? "_inv" : "")); // FIXME: is "_inv" the right suffix?
+	RTLIL::Wire *wire = module->wire(wire_name);
+	if (wire) return wire;
+	log_debug("Creating %s\n", wire_name.c_str());
+	wire = module->addWire(wire_name);
+	if (!invert) return wire;
+	RTLIL::IdString wire_inv_name(stringf("\\n%d", variable));
+	RTLIL::Wire *wire_inv = module->wire(wire_inv_name);
+	if (wire_inv) {
+		if (module->cell(wire_inv_name)) return wire;
+	}
+	else {
+		log_debug("Creating %s\n", wire_inv_name.c_str());
+		wire_inv = module->addWire(wire_inv_name);
+	}
+
+	log_debug("Creating %s = ~%s\n", wire_name.c_str(), wire_inv_name.c_str());
+	module->addNotGate(stringf("\\n%d_not", variable), wire_inv, wire); // FIXME: is "_not" the right suffix?
+
+	return wire;
 }
 
 void AigerReader::parse_aiger_ascii()
 {
-    std::string line;
-    std::stringstream ss;
-
-    unsigned l1, l2, l3;
-
-    // Parse inputs
-    for (unsigned i = 1; i <= I; ++i, ++line_count) {
-        if (!(f >> l1))
-            log_error("Line %u cannot be interpreted as an input!\n", line_count);
-        log_debug("%d is an input\n", l1);
-        log_assert(!(l1 & 1)); // TODO: Inputs can't be inverted?
-        RTLIL::Wire *wire = createWireIfNotExists(module, l1);
-        wire->port_input = true;
-        inputs.push_back(wire);
-    }
-
-    // Parse latches
-    RTLIL::Wire *clk_wire = nullptr;
-    if (L > 0) {
-        clk_wire = module->wire(clk_name);
-        log_assert(!clk_wire);
-        log_debug("Creating %s\n", clk_name.c_str());
-        clk_wire = module->addWire(clk_name);
-        clk_wire->port_input = true;
-    }
-    for (unsigned i = 0; i < L; ++i, ++line_count) {
-        if (!(f >> l1 >> l2))
-            log_error("Line %u cannot be interpreted as a latch!\n", line_count);
-        log_debug("%d %d is a latch\n", l1, l2);
-        log_assert(!(l1 & 1)); // TODO: Latch outputs can't be inverted?
-        RTLIL::Wire *q_wire = createWireIfNotExists(module, l1);
-        RTLIL::Wire *d_wire = createWireIfNotExists(module, l2);
-
-        module->addDffGate(NEW_ID, clk_wire, d_wire, q_wire);
-
-        // Reset logic is optional in AIGER 1.9
-        if (f.peek() == ' ') {
-            if (!(f >> l3))
-                log_error("Line %u cannot be interpreted as a latch!\n", line_count);
-
-            if (l3 == 0)
-                q_wire->attributes["\\init"] = RTLIL::S0;
-            else if (l3 == 1)
-                q_wire->attributes["\\init"] = RTLIL::S1;
-            else if (l3 == l1) {
-                //q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
-            }
-            else
-                log_error("Line %u has invalid reset literal for latch!\n", line_count);
-        }
-        else {
-            // AIGER latches are assumed to be initialized to zero
-            q_wire->attributes["\\init"] = RTLIL::S0;
-        }
-        latches.push_back(q_wire);
-    }
-
-    // Parse outputs
-    for (unsigned i = 0; i < O; ++i, ++line_count) {
-        if (!(f >> l1))
-            log_error("Line %u cannot be interpreted as an output!\n", line_count);
-
-        log_debug("%d is an output\n", l1);
-        RTLIL::Wire *wire = createWireIfNotExists(module, l1);
-        wire->port_output = true;
-        outputs.push_back(wire);
-    }
-
-    // Parse bad properties
-    for (unsigned i = 0; i < B; ++i, ++line_count) {
-        if (!(f >> l1))
-            log_error("Line %u cannot be interpreted as a bad state property!\n", line_count);
-
-        log_debug("%d is a bad state property\n", l1);
-        RTLIL::Wire *wire = createWireIfNotExists(module, l1);
-        wire->port_output = true;
-        bad_properties.push_back(wire);
-    }
-
-    // TODO: Parse invariant constraints
-    for (unsigned i = 0; i < C; ++i, ++line_count)
-        std::getline(f, line); // Ignore up to start of next line
-
-    // TODO: Parse justice properties
-    for (unsigned i = 0; i < J; ++i, ++line_count)
-        std::getline(f, line); // Ignore up to start of next line
-
-    // TODO: Parse fairness constraints
-    for (unsigned i = 0; i < F; ++i, ++line_count)
-        std::getline(f, line); // Ignore up to start of next line
-
-    // Parse AND
-    for (unsigned i = 0; i < A; ++i) {
-        if (!(f >> l1 >> l2 >> l3))
-            log_error("Line %u cannot be interpreted as an AND!\n", line_count);
-
-        log_debug("%d %d %d is an AND\n", l1, l2, l3);
-        log_assert(!(l1 & 1)); // TODO: Output of ANDs can't be inverted?
-        RTLIL::Wire *o_wire = createWireIfNotExists(module, l1);
-        RTLIL::Wire *i1_wire = createWireIfNotExists(module, l2);
-        RTLIL::Wire *i2_wire = createWireIfNotExists(module, l3);
-        module->addAndGate(NEW_ID, i1_wire, i2_wire, o_wire);
-    }
-    std::getline(f, line); // Ignore up to start of next line
+	std::string line;
+	std::stringstream ss;
+
+	unsigned l1, l2, l3;
+
+	// Parse inputs
+	for (unsigned i = 1; i <= I; ++i, ++line_count) {
+		if (!(f >> l1))
+			log_error("Line %u cannot be interpreted as an input!\n", line_count);
+		log_debug("%d is an input\n", l1);
+		log_assert(!(l1 & 1)); // TODO: Inputs can't be inverted?
+		RTLIL::Wire *wire = createWireIfNotExists(module, l1);
+		wire->port_input = true;
+		inputs.push_back(wire);
+	}
+
+	// Parse latches
+	RTLIL::Wire *clk_wire = nullptr;
+	if (L > 0) {
+		clk_wire = module->wire(clk_name);
+		log_assert(!clk_wire);
+		log_debug("Creating %s\n", clk_name.c_str());
+		clk_wire = module->addWire(clk_name);
+		clk_wire->port_input = true;
+	}
+	for (unsigned i = 0; i < L; ++i, ++line_count) {
+		if (!(f >> l1 >> l2))
+			log_error("Line %u cannot be interpreted as a latch!\n", line_count);
+		log_debug("%d %d is a latch\n", l1, l2);
+		log_assert(!(l1 & 1)); // TODO: Latch outputs can't be inverted?
+		RTLIL::Wire *q_wire = createWireIfNotExists(module, l1);
+		RTLIL::Wire *d_wire = createWireIfNotExists(module, l2);
+
+		module->addDffGate(NEW_ID, clk_wire, d_wire, q_wire);
+
+		// Reset logic is optional in AIGER 1.9
+		if (f.peek() == ' ') {
+			if (!(f >> l3))
+				log_error("Line %u cannot be interpreted as a latch!\n", line_count);
+
+			if (l3 == 0)
+				q_wire->attributes["\\init"] = RTLIL::S0;
+			else if (l3 == 1)
+				q_wire->attributes["\\init"] = RTLIL::S1;
+			else if (l3 == l1) {
+				//q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
+			}
+			else
+				log_error("Line %u has invalid reset literal for latch!\n", line_count);
+		}
+		else {
+			// AIGER latches are assumed to be initialized to zero
+			q_wire->attributes["\\init"] = RTLIL::S0;
+		}
+		latches.push_back(q_wire);
+	}
+
+	// Parse outputs
+	for (unsigned i = 0; i < O; ++i, ++line_count) {
+		if (!(f >> l1))
+			log_error("Line %u cannot be interpreted as an output!\n", line_count);
+
+		log_debug("%d is an output\n", l1);
+		RTLIL::Wire *wire = createWireIfNotExists(module, l1);
+		wire->port_output = true;
+		outputs.push_back(wire);
+	}
+
+	// Parse bad properties
+	for (unsigned i = 0; i < B; ++i, ++line_count) {
+		if (!(f >> l1))
+			log_error("Line %u cannot be interpreted as a bad state property!\n", line_count);
+
+		log_debug("%d is a bad state property\n", l1);
+		RTLIL::Wire *wire = createWireIfNotExists(module, l1);
+		wire->port_output = true;
+		bad_properties.push_back(wire);
+	}
+
+	// TODO: Parse invariant constraints
+	for (unsigned i = 0; i < C; ++i, ++line_count)
+		std::getline(f, line); // Ignore up to start of next line
+
+	// TODO: Parse justice properties
+	for (unsigned i = 0; i < J; ++i, ++line_count)
+		std::getline(f, line); // Ignore up to start of next line
+
+	// TODO: Parse fairness constraints
+	for (unsigned i = 0; i < F; ++i, ++line_count)
+		std::getline(f, line); // Ignore up to start of next line
+
+	// Parse AND
+	for (unsigned i = 0; i < A; ++i) {
+		if (!(f >> l1 >> l2 >> l3))
+			log_error("Line %u cannot be interpreted as an AND!\n", line_count);
+
+		log_debug("%d %d %d is an AND\n", l1, l2, l3);
+		log_assert(!(l1 & 1)); // TODO: Output of ANDs can't be inverted?
+		RTLIL::Wire *o_wire = createWireIfNotExists(module, l1);
+		RTLIL::Wire *i1_wire = createWireIfNotExists(module, l2);
+		RTLIL::Wire *i2_wire = createWireIfNotExists(module, l3);
+		module->addAndGate(NEW_ID, i1_wire, i2_wire, o_wire);
+	}
+	std::getline(f, line); // Ignore up to start of next line
 }
 
 static unsigned parse_next_delta_literal(std::istream &f, unsigned ref)
 {
-    unsigned x = 0, i = 0;
-    unsigned char ch;
-    while ((ch = f.get()) & 0x80)
-        x |= (ch & 0x7f) << (7 * i++);
-    return ref - (x | (ch << (7 * i)));
+	unsigned x = 0, i = 0;
+	unsigned char ch;
+	while ((ch = f.get()) & 0x80)
+		x |= (ch & 0x7f) << (7 * i++);
+	return ref - (x | (ch << (7 * i)));
 }
 
 void AigerReader::parse_aiger_binary()
 {
-    unsigned l1, l2, l3;
-    std::string line;
-
-    // Parse inputs
-    for (unsigned i = 1; i <= I; ++i) {
-        RTLIL::Wire *wire = createWireIfNotExists(module, i << 1);
-        wire->port_input = true;
-        inputs.push_back(wire);
-    }
-
-    // Parse latches
-    RTLIL::Wire *clk_wire = nullptr;
-    if (L > 0) {
-        clk_wire = module->wire(clk_name);
-        log_assert(!clk_wire);
-        log_debug("Creating %s\n", clk_name.c_str());
-        clk_wire = module->addWire(clk_name);
-        clk_wire->port_input = true;
-    }
-    l1 = (I+1) * 2;
-    for (unsigned i = 0; i < L; ++i, ++line_count, l1 += 2) {
-        if (!(f >> l2))
-            log_error("Line %u cannot be interpreted as a latch!\n", line_count);
-        log_debug("%d %d is a latch\n", l1, l2);
-        RTLIL::Wire *q_wire = createWireIfNotExists(module, l1);
-        RTLIL::Wire *d_wire = createWireIfNotExists(module, l2);
-
-        module->addDff(NEW_ID, clk_wire, d_wire, q_wire);
-
-        // Reset logic is optional in AIGER 1.9
-        if (f.peek() == ' ') {
-            if (!(f >> l3))
-                log_error("Line %u cannot be interpreted as a latch!\n", line_count);
-
-            if (l3 == 0)
-                q_wire->attributes["\\init"] = RTLIL::S0;
-            else if (l3 == 1)
-                q_wire->attributes["\\init"] = RTLIL::S1;
-            else if (l3 == l1) {
-                //q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
-            }
-            else
-                log_error("Line %u has invalid reset literal for latch!\n", line_count);
-        }
-        else {
-            // AIGER latches are assumed to be initialized to zero
-            q_wire->attributes["\\init"] = RTLIL::S0;
-        }
-        latches.push_back(q_wire);
-    }
-
-    // Parse outputs
-    for (unsigned i = 0; i < O; ++i, ++line_count) {
-        if (!(f >> l1))
-            log_error("Line %u cannot be interpreted as an output!\n", line_count);
-
-        log_debug("%d is an output\n", l1);
-        RTLIL::Wire *wire = createWireIfNotExists(module, l1);
-        wire->port_output = true;
-        outputs.push_back(wire);
-    }
-    std::getline(f, line); // Ignore up to start of next line
-
-    // Parse bad properties
-    for (unsigned i = 0; i < B; ++i, ++line_count) {
-        if (!(f >> l1))
-            log_error("Line %u cannot be interpreted as a bad state property!\n", line_count);
-
-        log_debug("%d is a bad state property\n", l1);
-        RTLIL::Wire *wire = createWireIfNotExists(module, l1);
-        wire->port_output = true;
-        bad_properties.push_back(wire);
-    }
-    if (B > 0)
-        std::getline(f, line); // Ignore up to start of next line
-
-    // TODO: Parse invariant constraints
-    for (unsigned i = 0; i < C; ++i, ++line_count)
-        std::getline(f, line); // Ignore up to start of next line
-
-    // TODO: Parse justice properties
-    for (unsigned i = 0; i < J; ++i, ++line_count)
-        std::getline(f, line); // Ignore up to start of next line
-
-    // TODO: Parse fairness constraints
-    for (unsigned i = 0; i < F; ++i, ++line_count)
-        std::getline(f, line); // Ignore up to start of next line
-
-    // Parse AND
-    l1 = (I+L+1) << 1;
-    for (unsigned i = 0; i < A; ++i, ++line_count, l1 += 2) {
-        l2 = parse_next_delta_literal(f, l1);
-        l3 = parse_next_delta_literal(f, l2);
-
-        log_debug("%d %d %d is an AND\n", l1, l2, l3);
-        log_assert(!(l1 & 1)); // TODO: Output of ANDs can't be inverted?
-        RTLIL::Wire *o_wire = createWireIfNotExists(module, l1);
-        RTLIL::Wire *i1_wire = createWireIfNotExists(module, l2);
-        RTLIL::Wire *i2_wire = createWireIfNotExists(module, l3);
-
-        RTLIL::Cell *and_cell = module->addCell(NEW_ID, "$_AND_");
-        and_cell->setPort("\\A", i1_wire);
-        and_cell->setPort("\\B", i2_wire);
-        and_cell->setPort("\\Y", o_wire);
-    }
+	unsigned l1, l2, l3;
+	std::string line;
+
+	// Parse inputs
+	for (unsigned i = 1; i <= I; ++i) {
+		RTLIL::Wire *wire = createWireIfNotExists(module, i << 1);
+		wire->port_input = true;
+		inputs.push_back(wire);
+	}
+
+	// Parse latches
+	RTLIL::Wire *clk_wire = nullptr;
+	if (L > 0) {
+		clk_wire = module->wire(clk_name);
+		log_assert(!clk_wire);
+		log_debug("Creating %s\n", clk_name.c_str());
+		clk_wire = module->addWire(clk_name);
+		clk_wire->port_input = true;
+	}
+	l1 = (I+1) * 2;
+	for (unsigned i = 0; i < L; ++i, ++line_count, l1 += 2) {
+		if (!(f >> l2))
+			log_error("Line %u cannot be interpreted as a latch!\n", line_count);
+		log_debug("%d %d is a latch\n", l1, l2);
+		RTLIL::Wire *q_wire = createWireIfNotExists(module, l1);
+		RTLIL::Wire *d_wire = createWireIfNotExists(module, l2);
+
+		module->addDff(NEW_ID, clk_wire, d_wire, q_wire);
+
+		// Reset logic is optional in AIGER 1.9
+		if (f.peek() == ' ') {
+			if (!(f >> l3))
+				log_error("Line %u cannot be interpreted as a latch!\n", line_count);
+
+			if (l3 == 0)
+				q_wire->attributes["\\init"] = RTLIL::S0;
+			else if (l3 == 1)
+				q_wire->attributes["\\init"] = RTLIL::S1;
+			else if (l3 == l1) {
+				//q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
+			}
+			else
+				log_error("Line %u has invalid reset literal for latch!\n", line_count);
+		}
+		else {
+			// AIGER latches are assumed to be initialized to zero
+			q_wire->attributes["\\init"] = RTLIL::S0;
+		}
+		latches.push_back(q_wire);
+	}
+
+	// Parse outputs
+	for (unsigned i = 0; i < O; ++i, ++line_count) {
+		if (!(f >> l1))
+			log_error("Line %u cannot be interpreted as an output!\n", line_count);
+
+		log_debug("%d is an output\n", l1);
+		RTLIL::Wire *wire = createWireIfNotExists(module, l1);
+		wire->port_output = true;
+		outputs.push_back(wire);
+	}
+	std::getline(f, line); // Ignore up to start of next line
+
+	// Parse bad properties
+	for (unsigned i = 0; i < B; ++i, ++line_count) {
+		if (!(f >> l1))
+			log_error("Line %u cannot be interpreted as a bad state property!\n", line_count);
+
+		log_debug("%d is a bad state property\n", l1);
+		RTLIL::Wire *wire = createWireIfNotExists(module, l1);
+		wire->port_output = true;
+		bad_properties.push_back(wire);
+	}
+	if (B > 0)
+		std::getline(f, line); // Ignore up to start of next line
+
+	// TODO: Parse invariant constraints
+	for (unsigned i = 0; i < C; ++i, ++line_count)
+		std::getline(f, line); // Ignore up to start of next line
+
+	// TODO: Parse justice properties
+	for (unsigned i = 0; i < J; ++i, ++line_count)
+		std::getline(f, line); // Ignore up to start of next line
+
+	// TODO: Parse fairness constraints
+	for (unsigned i = 0; i < F; ++i, ++line_count)
+		std::getline(f, line); // Ignore up to start of next line
+
+	// Parse AND
+	l1 = (I+L+1) << 1;
+	for (unsigned i = 0; i < A; ++i, ++line_count, l1 += 2) {
+		l2 = parse_next_delta_literal(f, l1);
+		l3 = parse_next_delta_literal(f, l2);
+
+		log_debug("%d %d %d is an AND\n", l1, l2, l3);
+		log_assert(!(l1 & 1)); // TODO: Output of ANDs can't be inverted?
+		RTLIL::Wire *o_wire = createWireIfNotExists(module, l1);
+		RTLIL::Wire *i1_wire = createWireIfNotExists(module, l2);
+		RTLIL::Wire *i2_wire = createWireIfNotExists(module, l3);
+
+		RTLIL::Cell *and_cell = module->addCell(NEW_ID, "$_AND_");
+		and_cell->setPort("\\A", i1_wire);
+		and_cell->setPort("\\B", i2_wire);
+		and_cell->setPort("\\Y", o_wire);
+	}
 }
 
 struct AigerFrontend : public Frontend {
-    AigerFrontend() : Frontend("aiger", "read AIGER file") { }
-    void help() YS_OVERRIDE
-    {
-        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
-        log("\n");
-        log("    read_aiger [options] [filename]\n");
-        log("\n");
-        log("Load module from an AIGER file into the current design.\n");
-        log("\n");
-        log("    -module_name <module_name>\n");
-        log("        Name of module to be created (default: <filename>)"
+	AigerFrontend() : Frontend("aiger", "read AIGER file") { }
+	void help() YS_OVERRIDE
+	{
+		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+		log("\n");
+		log("    read_aiger [options] [filename]\n");
+		log("\n");
+		log("Load module from an AIGER file into the current design.\n");
+		log("\n");
+		log("    -module_name <module_name>\n");
+		log("        Name of module to be created (default: "
 #ifdef _WIN32
-		                                                   "top" // FIXME
+				"top" // FIXME
 #else
-		                                                   "<filename>"
+				"<filename>"
 #endif
-                                                           ")\n");
-        log("\n");
-        log("    -clk_name <wire_name>\n");
-        log("        AIGER latches to be transformed into posedge DFFs clocked by wire of");
-        log("        this name (default: clk)\n");
-        log("\n");
-    }
-    void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
-    {
-        log_header(design, "Executing AIGER frontend.\n");
-
-        RTLIL::IdString clk_name = "\\clk";
-        RTLIL::IdString module_name;
+				")\n");
+		log("\n");
+		log("    -clk_name <wire_name>\n");
+		log("        AIGER latches to be transformed into posedge DFFs clocked by wire of");
+		log("        this name (default: clk)\n");
+		log("\n");
+	}
+	void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+	{
+		log_header(design, "Executing AIGER frontend.\n");
+
+		RTLIL::IdString clk_name = "\\clk";
+		RTLIL::IdString module_name;
 
 		size_t argidx;
 		for (argidx = 1; argidx < args.size(); argidx++) {
@@ -433,19 +433,19 @@ struct AigerFrontend : public Frontend {
 		}
 		extra_args(f, filename, args, argidx);
 
-        if (module_name.empty()) {
+		if (module_name.empty()) {
 #ifdef _WIN32
-            module_name = "top"; // FIXME: basename equivalent on Win32?
+			module_name = "top"; // FIXME: basename equivalent on Win32?
 #else
-            char* bn = strdup(filename.c_str());
-            module_name = RTLIL::escape_id(bn);
-            free(bn);
+			char* bn = strdup(filename.c_str());
+			module_name = RTLIL::escape_id(bn);
+			free(bn);
 #endif
-        }
+		}
 
-        AigerReader reader(design, *f, module_name, clk_name);
+		AigerReader reader(design, *f, module_name, clk_name);
 		reader.parse_aiger();
-    }
+	}
 } AigerFrontend;
 
 YOSYS_NAMESPACE_END
-- 
cgit v1.2.3