From 5f9cd2e2f6cdea9f00cb5a042c7fe472fb54ef4c Mon Sep 17 00:00:00 2001
From: Vamsi K Vytla <vamsi.vytla@gmail.com>
Date: Mon, 27 Apr 2020 09:44:24 -0700
Subject: Preserve 'signed'-ness of a verilog wire through RTLIL

As per suggestion made in https://github.com/YosysHQ/yosys/pull/1987, now:

RTLIL::wire holds an is_signed field.
This is exported in JSON backend
This is exported via dump_rtlil command
This is read in via ilang_parser
---
 backends/ilang/ilang_backend.cc | 2 ++
 backends/json/json.cc           | 4 ++++
 frontends/ast/genrtlil.cc       | 1 +
 frontends/ilang/ilang_parser.y  | 3 +++
 kernel/rtlil.cc                 | 2 ++
 kernel/rtlil.h                  | 2 +-
 6 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc
index 6e3882d2d..3a418de3c 100644
--- a/backends/ilang/ilang_backend.cc
+++ b/backends/ilang/ilang_backend.cc
@@ -131,6 +131,8 @@ void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::
 		f << stringf("output %d ", wire->port_id);
 	if (wire->port_input && wire->port_output)
 		f << stringf("inout %d ", wire->port_id);
+	if (wire->is_signed)
+		f << stringf("signed ");
 	f << stringf("%s\n", wire->name.c_str());
 }
 
diff --git a/backends/json/json.cc b/backends/json/json.cc
index 1a8b757ef..5edc50f60 100644
--- a/backends/json/json.cc
+++ b/backends/json/json.cc
@@ -160,6 +160,8 @@ struct JsonWriter
 				f << stringf("          \"offset\": %d,\n", w->start_offset);
 			if (w->upto)
 				f << stringf("          \"upto\": 1,\n");
+			if (w->is_signed)
+				f << stringf("          \"signed\": %d,\n", w->is_signed);
 			f << stringf("          \"bits\": %s\n", get_bits(w).c_str());
 			f << stringf("        }");
 			first = false;
@@ -227,6 +229,8 @@ struct JsonWriter
 				f << stringf("          \"offset\": %d,\n", w->start_offset);
 			if (w->upto)
 				f << stringf("          \"upto\": 1,\n");
+			if (w->is_signed)
+				f << stringf("          \"signed\": %d,\n", w->is_signed);
 			f << stringf("          \"attributes\": {");
 			write_parameters(w->attributes);
 			f << stringf("\n          }\n");
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index d35335747..93fcfb396 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -1058,6 +1058,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 			wire->port_input = is_input;
 			wire->port_output = is_output;
 			wire->upto = range_swapped;
+			wire->is_signed = is_signed;
 
 			for (auto &attr : attributes) {
 				if (attr.second->type != AST_CONSTANT)
diff --git a/frontends/ilang/ilang_parser.y b/frontends/ilang/ilang_parser.y
index 8e21fb176..43b628e09 100644
--- a/frontends/ilang/ilang_parser.y
+++ b/frontends/ilang/ilang_parser.y
@@ -192,6 +192,9 @@ wire_options:
 	wire_options TOK_UPTO {
 		current_wire->upto = true;
 	} |
+	wire_options TOK_SIGNED {
+		current_wire->is_signed = true;
+	} |
 	wire_options TOK_OFFSET TOK_INT {
 		current_wire->start_offset = $3;
 	} |
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 196e301b6..98d6ed41f 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -1862,6 +1862,7 @@ RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, const RTLIL::Wire *oth
 	wire->port_input = other->port_input;
 	wire->port_output = other->port_output;
 	wire->upto = other->upto;
+	wire->is_signed = other->is_signed;
 	wire->attributes = other->attributes;
 	return wire;
 }
@@ -2445,6 +2446,7 @@ RTLIL::Wire::Wire()
 	port_input = false;
 	port_output = false;
 	upto = false;
+	is_signed = false;
 
 #ifdef WITH_PYTHON
 	RTLIL::Wire::get_all_wires()->insert(std::pair<unsigned int, RTLIL::Wire*>(hashidx_, this));
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index 11c45bbec..04d4325d1 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -1353,7 +1353,7 @@ public:
 	RTLIL::Module *module;
 	RTLIL::IdString name;
 	int width, start_offset, port_id;
-	bool port_input, port_output, upto;
+	bool port_input, port_output, upto, is_signed;
 
 #ifdef WITH_PYTHON
 	static std::map<unsigned int, RTLIL::Wire*> *get_all_wires(void);
-- 
cgit v1.2.3


From adb483ddfd3163a4efa08e09a35dd926377aa71d Mon Sep 17 00:00:00 2001
From: Vamsi K Vytla <vamsi.vytla@gmail.com>
Date: Mon, 27 Apr 2020 10:36:18 -0700
Subject: frontends/json/jsonparse.cc: Like the upto field read_json can also
 read the signedness of a wire

---
 frontends/json/jsonparse.cc | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc
index 7aceffbfc..8ae7c6578 100644
--- a/frontends/json/jsonparse.cc
+++ b/frontends/json/jsonparse.cc
@@ -309,6 +309,12 @@ void json_import(Design *design, string &modname, JsonNode *node)
 					port_wire->upto = val->data_number != 0;
 			}
 
+			if (port_node->data_dict.count("signed") != 0) {
+				JsonNode *val = port_node->data_dict.at("signed");
+				if (val->type == 'N')
+					port_wire->is_signed = val->data_number != 0;
+			}
+
 			if (port_node->data_dict.count("offset") != 0) {
 				JsonNode *val = port_node->data_dict.at("offset");
 				if (val->type == 'N')
@@ -573,4 +579,3 @@ struct JsonFrontend : public Frontend {
 } JsonFrontend;
 
 YOSYS_NAMESPACE_END
-
-- 
cgit v1.2.3