Merge pull request #420 from antmicro/mglb/RenameNamespaces

systemverilog-plugin: use dedicated namespace and move code from const2ast.cc to third_party directory.
diff --git a/Makefile b/Makefile
index fc39ff4..70433f7 100644
--- a/Makefile
+++ b/Makefile
@@ -71,9 +71,9 @@
 CLANG_FORMAT ?= clang-format-8
 .PHONY: format
 format:
-	find . \( -name "*.h" -o -name "*.cc" \) -and -not -path './third_party/*' -print0 | xargs -0 -P $$(nproc) ${CLANG_FORMAT} -style=file -i
+	find . \( -name "*.h" -o -name "*.cc" \) -and -not -path '*/third_party/*' -print0 | xargs -0 -P $$(nproc) ${CLANG_FORMAT} -style=file -i
 
 VERIBLE_FORMAT ?= verible-verilog-format
 .PHONY: format-verilog
 format-verilog:
-	find */tests \( -name "*.v" -o -name "*.sv" \) -and -not -path './third_party/*' -print0 | xargs -0 $(VERIBLE_FORMAT) --inplace
+	find */tests \( -name "*.v" -o -name "*.sv" \) -and -not -path '*/third_party/*' -print0 | xargs -0 $(VERIBLE_FORMAT) --inplace
diff --git a/systemverilog-plugin/Makefile b/systemverilog-plugin/Makefile
index a1d69e1..af5320d 100644
--- a/systemverilog-plugin/Makefile
+++ b/systemverilog-plugin/Makefile
@@ -18,11 +18,11 @@
 
 NAME = systemverilog
 SOURCES = UhdmAst.cc \
-          UhdmAstUpstream.cc \
           uhdmastfrontend.cc \
           uhdmcommonfrontend.cc \
           uhdmsurelogastfrontend.cc \
-          uhdmastreport.cc
+          uhdmastreport.cc \
+          third_party/yosys/const2ast.cc
 
 # Directory to search for Surelog and UHDM libraries
 UHDM_INSTALL_DIR ?= /usr/local
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index 6b3624a..00816d6 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -14,9 +14,33 @@
 #include <uhdm/uhdm.h>
 #include <uhdm/vpi_user.h>
 
-#include "UhdmAstUpstream.h"
+#include "third_party/yosys/const2ast.h"
 
 YOSYS_NAMESPACE_BEGIN
+namespace VERILOG_FRONTEND
+{
+extern bool sv_mode;
+}
+YOSYS_NAMESPACE_END
+
+namespace systemverilog_plugin
+{
+
+using namespace ::Yosys;
+
+namespace AST
+{
+using namespace ::Yosys::AST;
+
+namespace Extended
+{
+enum AstNodeTypeExtended {
+    AST_DOT = ::Yosys::AST::AST_BIND + 1, // here we always want to point to the last element of yosys' AstNodeType
+    AST_BREAK,
+    AST_CONTINUE
+};
+}
+} // namespace AST
 
 /*static*/ const IdString &UhdmAst::partial()
 {
@@ -96,6 +120,13 @@
     return objectName;
 }
 
+static AST::AstNode *mkconst_real(double d)
+{
+    AST::AstNode *node = new AST::AstNode(AST::AST_REALVALUE);
+    node->realvalue = d;
+    return node;
+}
+
 static AST::AstNode *make_range(int left, int right, bool is_signed = false)
 {
     // generate a pre-validated range node for a fixed signal range.
@@ -486,7 +517,7 @@
     AST::AstNode *struct_range = nullptr;
 
     for (auto c : search_node->children) {
-        if (c->type == static_cast<int>(AST::AST_DOT)) {
+        if (c->type == static_cast<int>(AST::Extended::AST_DOT)) {
             // There should be only 1 AST_DOT node children
             log_assert(!sub_dot);
             sub_dot = expand_dot(current_struct_elem, c);
@@ -851,8 +882,8 @@
 
 static void simplify(AST::AstNode *current_node, AST::AstNode *parent_node)
 {
-    auto dot_it =
-      std::find_if(current_node->children.begin(), current_node->children.end(), [](auto c) { return c->type == static_cast<int>(AST::AST_DOT); });
+    auto dot_it = std::find_if(current_node->children.begin(), current_node->children.end(),
+                               [](auto c) { return c->type == static_cast<int>(AST::Extended::AST_DOT); });
     AST::AstNode *dot = (dot_it != current_node->children.end()) ? *dot_it : nullptr;
 
     AST::AstNode *expanded = nullptr;
@@ -875,8 +906,8 @@
                     break;
                 } else {
                     current_node->str += "." + dot->str.substr(1);
-                    dot_it =
-                      std::find_if(dot->children.begin(), dot->children.end(), [](auto c) { return c->type == static_cast<int>(AST::AST_DOT); });
+                    dot_it = std::find_if(dot->children.begin(), dot->children.end(),
+                                          [](auto c) { return c->type == static_cast<int>(AST::Extended::AST_DOT); });
                     parent_node = dot;
                     dot = (dot_it != dot->children.end()) ? *dot_it : nullptr;
                 }
@@ -1155,7 +1186,7 @@
         }
         // handle vpiBinStrVal, vpiDecStrVal and vpiHexStrVal
         if (std::strchr(val.value.str, '\'')) {
-            return VERILOG_FRONTEND::const2ast(val.value.str, 0, false);
+            return ::systemverilog_plugin::const2ast(val.value.str, 0, false);
         } else {
             auto size = vpi_get(vpiSize, obj_h);
             if (size == 0) {
@@ -1163,7 +1194,7 @@
                 c->is_unsized = true;
                 return c;
             } else {
-                return VERILOG_FRONTEND::const2ast(std::to_string(size) + strValType + val.value.str, 0, false);
+                return ::systemverilog_plugin::const2ast(std::to_string(size) + strValType + val.value.str, 0, false);
             }
         }
     }
@@ -1233,15 +1264,15 @@
                 }
                 break;
             }
-            case AST::AST_BREAK:
-            case AST::AST_CONTINUE: {
+            case AST::Extended::AST_BREAK:
+            case AST::Extended::AST_CONTINUE: {
                 std::for_each(it, block->children.end(), [](auto *node) { delete node; });
                 block->children.erase(it, block->children.end());
                 if (!continue_wire)
                     continue_wire = make_cond_var("$continue");
                 auto *continue_id = make_identifier(continue_wire->str);
                 block->children.push_back(make_ast_node(AST::AST_ASSIGN_EQ, {continue_id, AST::AstNode::mkconst_int(1, false)}));
-                if (type == AST::AST_BREAK) {
+                if (type == AST::Extended::AST_BREAK) {
                     if (!break_wire)
                         break_wire = make_cond_var("$break");
                     auto *break_id = make_identifier(break_wire->str);
@@ -3486,7 +3517,7 @@
                     log_assert(!node->children.empty());
                     top_node->children.push_back(node->children[0]);
                 } else {
-                    node->type = static_cast<AST::AstNodeType>(AST::AST_DOT);
+                    node->type = static_cast<AST::AstNodeType>(AST::Extended::AST_DOT);
                     top_node->children.push_back(node);
                     top_node = node;
                 }
@@ -3549,7 +3580,7 @@
     if (vpi_get(vpiType, typespec_h) == vpiStringTypespec) {
         std::string field_name = vpi_get_str(vpiName, typespec_h);
         if (field_name != "default") { // TODO: better support of the default keyword
-            auto field = new AST::AstNode(static_cast<AST::AstNodeType>(AST::AST_DOT));
+            auto field = new AST::AstNode(static_cast<AST::AstNodeType>(AST::Extended::AST_DOT));
             field->str = field_name;
             current_node->children[0]->children.push_back(field);
         }
@@ -4339,11 +4370,11 @@
         break;
     case vpiBreak:
         // Will be resolved later by loop processor
-        current_node = make_ast_node(static_cast<AST::AstNodeType>(AST::AST_BREAK));
+        current_node = make_ast_node(static_cast<AST::AstNodeType>(AST::Extended::AST_BREAK));
         break;
     case vpiContinue:
         // Will be resolved later by loop processor
-        current_node = make_ast_node(static_cast<AST::AstNodeType>(AST::AST_CONTINUE));
+        current_node = make_ast_node(static_cast<AST::AstNodeType>(AST::Extended::AST_CONTINUE));
         break;
     case vpiGenScopeArray:
         process_gen_scope_array();
@@ -4496,4 +4527,4 @@
     }
 }
 
-YOSYS_NAMESPACE_END
+} // namespace systemverilog_plugin
diff --git a/systemverilog-plugin/UhdmAst.h b/systemverilog-plugin/UhdmAst.h
index 1e77c17..f3b1017 100644
--- a/systemverilog-plugin/UhdmAst.h
+++ b/systemverilog-plugin/UhdmAst.h
@@ -8,7 +8,8 @@
 #include "uhdmastshared.h"
 #include <uhdm/uhdm.h>
 
-YOSYS_NAMESPACE_BEGIN
+namespace systemverilog_plugin
+{
 
 class UhdmAst
 {
@@ -16,43 +17,44 @@
     // Walks through one-to-many relationships from given parent
     // node through the VPI interface, visiting child nodes belonging to
     // ChildrenNodeTypes that are present in the given object.
-    void visit_one_to_many(const std::vector<int> child_node_types, vpiHandle parent_handle, const std::function<void(AST::AstNode *)> &f);
+    void visit_one_to_many(const std::vector<int> child_node_types, vpiHandle parent_handle, const std::function<void(::Yosys::AST::AstNode *)> &f);
 
     // Walks through one-to-one relationships from given parent
     // node through the VPI interface, visiting child nodes belonging to
     // ChildrenNodeTypes that are present in the given object.
-    void visit_one_to_one(const std::vector<int> child_node_types, vpiHandle parent_handle, const std::function<void(AST::AstNode *)> &f);
+    void visit_one_to_one(const std::vector<int> child_node_types, vpiHandle parent_handle, const std::function<void(::Yosys::AST::AstNode *)> &f);
 
     // Visit children of type vpiRange that belong to the given parent node.
-    void visit_range(vpiHandle obj_h, const std::function<void(AST::AstNode *)> &f);
+    void visit_range(vpiHandle obj_h, const std::function<void(::Yosys::AST::AstNode *)> &f);
 
     // Visit the default expression assigned to a variable.
     void visit_default_expr(vpiHandle obj_h);
 
     // Create an AstNode of the specified type with metadata extracted from
     // the given vpiHandle.
-    AST::AstNode *make_ast_node(AST::AstNodeType type, std::vector<AST::AstNode *> children = {}, bool prefer_full_name = false);
+    ::Yosys::AST::AstNode *make_ast_node(::Yosys::AST::AstNodeType type, std::vector<::Yosys::AST::AstNode *> children = {},
+                                         bool prefer_full_name = false);
 
     // Create an identifier AstNode
-    AST::AstNode *make_identifier(const std::string &name);
+    ::Yosys::AST::AstNode *make_identifier(const std::string &name);
 
     // Makes the passed node a cell node of the specified type
-    void make_cell(vpiHandle obj_h, AST::AstNode *node, AST::AstNode *type);
+    void make_cell(vpiHandle obj_h, ::Yosys::AST::AstNode *node, ::Yosys::AST::AstNode *type);
 
     // Moves a type node to the specified node
-    void move_type_to_new_typedef(AST::AstNode *current_node, AST::AstNode *type_node);
+    void move_type_to_new_typedef(::Yosys::AST::AstNode *current_node, ::Yosys::AST::AstNode *type_node);
 
     // Go up the UhdmAst to find a parent node of the specified type
-    AST::AstNode *find_ancestor(const std::unordered_set<AST::AstNodeType> &types);
+    ::Yosys::AST::AstNode *find_ancestor(const std::unordered_set<::Yosys::AST::AstNodeType> &types);
 
     // Reports that something went wrong with reading the UHDM file
     void report_error(const char *format, ...) const;
 
     // Processes the value connected to the specified node
-    AST::AstNode *process_value(vpiHandle obj_h);
+    ::Yosys::AST::AstNode *process_value(vpiHandle obj_h);
 
     // Transforms break and continue nodes into structures accepted by the AST frontend
-    void transform_breaks_continues(AST::AstNode *loop, AST::AstNode *decl_block);
+    void transform_breaks_continues(::Yosys::AST::AstNode *loop, ::Yosys::AST::AstNode *decl_block);
 
     // The parent UhdmAst
     UhdmAst *parent;
@@ -64,7 +66,7 @@
     vpiHandle obj_h = 0;
 
     // The current Yosys AST node
-    AST::AstNode *current_node = nullptr;
+    ::Yosys::AST::AstNode *current_node = nullptr;
 
     // Indentation used for debug printing
     std::string indent;
@@ -128,7 +130,7 @@
     void process_logic_var();
     void process_sys_func_call();
     // use for task calls and function calls
-    void process_tf_call(AST::AstNodeType type);
+    void process_tf_call(::Yosys::AST::AstNodeType type);
     void process_immediate_assert();
     void process_hier_path();
     void process_logic_typespec();
@@ -148,7 +150,7 @@
     void process_while();
     void process_gate();
     void process_primterm();
-    void simplify_parameter(AST::AstNode *parameter, AST::AstNode *module_node = nullptr);
+    void simplify_parameter(::Yosys::AST::AstNode *parameter, ::Yosys::AST::AstNode *module_node = nullptr);
     void process_unsupported_stmt(const UHDM::BaseClass *object);
 
     UhdmAst(UhdmAst *p, UhdmAstShared &s, const std::string &i) : parent(p), shared(s), indent(i)
@@ -161,23 +163,19 @@
     UhdmAst(UhdmAstShared &s, const std::string &i = "") : UhdmAst(nullptr, s, i) {}
 
     // Visits single VPI object and creates proper AST node
-    AST::AstNode *process_object(vpiHandle obj_h);
+    ::Yosys::AST::AstNode *process_object(vpiHandle obj_h);
 
     // Visits all VPI design objects and returns created ASTs
-    AST::AstNode *visit_designs(const std::vector<vpiHandle> &designs);
+    ::Yosys::AST::AstNode *visit_designs(const std::vector<vpiHandle> &designs);
 
-    static const IdString &partial();
-    static const IdString &packed_ranges();
-    static const IdString &unpacked_ranges();
+    static const ::Yosys::IdString &partial();
+    static const ::Yosys::IdString &packed_ranges();
+    static const ::Yosys::IdString &unpacked_ranges();
     // set this attribute to force conversion of multirange wire to single range. It is useful to force-convert some memories.
-    static const IdString &force_convert();
-    static const IdString &is_imported();
+    static const ::Yosys::IdString &force_convert();
+    static const ::Yosys::IdString &is_imported();
 };
 
-namespace VERILOG_FRONTEND
-{
-extern bool sv_mode;
-}
-YOSYS_NAMESPACE_END
+} // namespace systemverilog_plugin
 
 #endif
diff --git a/systemverilog-plugin/third_party/yosys/README b/systemverilog-plugin/third_party/yosys/README
new file mode 100644
index 0000000..ceb62a9
--- /dev/null
+++ b/systemverilog-plugin/third_party/yosys/README
@@ -0,0 +1,17 @@
+Files in this directory were copied from Yosys sources and slightly adapted.
+Original sources and their license available at https://github.com/YosysHQ/yosys.
+
+Copied files, their sources, changes & notes:
+
+- const2ast.cc: yosys/frontends/verilog/const2ast.cc (rev. 72787f5)
+  - The file is a part of Yosys Verilog frontend, which is not publicly exposed
+    by Yosys. Copy has been made to avoid relying on internal details.
+  - Changes:
+    - C++ includes adapted to not rely on `verilog_frontend.h` file.
+    - Removed Yosys namespace; `const2ast()` has been placed inside
+      `systemverilog_plugin` namespace to avoid conflicts with the symbol from
+      Yosys when statically linking.
+
+Non-copied files placed here for interfacing purposes:
+
+- const2ast.h
diff --git a/systemverilog-plugin/third_party/yosys/const2ast.cc b/systemverilog-plugin/third_party/yosys/const2ast.cc
new file mode 100644
index 0000000..96ea6cc
--- /dev/null
+++ b/systemverilog-plugin/third_party/yosys/const2ast.cc
@@ -0,0 +1,252 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2012  Claire Xenia Wolf <claire@yosyshq.com>
+ *
+ *  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.
+ *
+ *  ---
+ *
+ *  The Verilog frontend.
+ *
+ *  This frontend is using the AST frontend library (see frontends/ast/).
+ *  Thus this frontend does not generate RTLIL code directly but creates an
+ *  AST directly from the Verilog parse tree and then passes this AST to
+ *  the AST frontend library.
+ *
+ *  ---
+ *
+ *  This file contains an ad-hoc parser for Verilog constants. The Verilog
+ *  lexer does only recognize a constant but does not actually split it to its
+ *  components. I.e. it just passes the Verilog code for the constant to the
+ *  bison parser. The parser then uses the function const2ast() from this file
+ *  to create an AST node for the constant.
+ *
+ *  ---
+ *
+ *  The file has been adapted for use in Yosys SystemVerilog Plugin.
+ *
+ */
+
+#include "const2ast.h"
+#include "frontends/ast/ast.h"
+#include "kernel/log.h"
+
+#include <string>
+#include <cmath>
+#include <vector>
+
+using namespace Yosys;
+using namespace Yosys::AST;
+
+// divide an arbitrary length decimal number by two and return the rest
+static int my_decimal_div_by_two(std::vector<uint8_t> &digits)
+{
+	int carry = 0;
+	for (size_t i = 0; i < digits.size(); i++) {
+		if (digits[i] >= 10)
+			log_file_error(current_filename, get_line_num(), "Invalid use of [a-fxz?] in decimal constant.\n");
+		digits[i] += carry * 10;
+		carry = digits[i] % 2;
+		digits[i] /= 2;
+	}
+	while (!digits.empty() && !digits.front())
+		digits.erase(digits.begin());
+	return carry;
+}
+
+// find the number of significant bits in a binary number (not including the sign bit)
+static int my_ilog2(int x)
+{
+	int ret = 0;
+	while (x != 0 && x != -1) {
+		x = x >> 1;
+		ret++;
+	}
+	return ret;
+}
+
+// parse a binary, decimal, hexadecimal or octal number with support for special bits ('x', 'z' and '?')
+static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int len_in_bits, int base, char case_type, bool is_unsized)
+{
+	// all digits in string (MSB at index 0)
+	std::vector<uint8_t> digits;
+
+	while (*str) {
+		if ('0' <= *str && *str <= '9')
+			digits.push_back(*str - '0');
+		else if ('a' <= *str && *str <= 'f')
+			digits.push_back(10 + *str - 'a');
+		else if ('A' <= *str && *str <= 'F')
+			digits.push_back(10 + *str - 'A');
+		else if (*str == 'x' || *str == 'X')
+			digits.push_back(0xf0);
+		else if (*str == 'z' || *str == 'Z' || *str == '?')
+			digits.push_back(0xf1);
+		str++;
+	}
+
+	if (base == 10 && GetSize(digits) == 1 && digits.front() >= 0xf0)
+		base = 2;
+
+	data.clear();
+
+	if (base == 10) {
+		while (!digits.empty())
+			data.push_back(my_decimal_div_by_two(digits) ? State::S1 : State::S0);
+	} else {
+		int bits_per_digit = my_ilog2(base-1);
+		for (auto it = digits.rbegin(), e = digits.rend(); it != e; it++) {
+			if (*it > (base-1) && *it < 0xf0)
+				log_file_error(current_filename, get_line_num(), "Digit larger than %d used in in base-%d constant.\n",
+					       base-1, base);
+			for (int i = 0; i < bits_per_digit; i++) {
+				int bitmask = 1 << i;
+				if (*it == 0xf0)
+					data.push_back(case_type == 'x' ? RTLIL::Sa : RTLIL::Sx);
+				else if (*it == 0xf1)
+					data.push_back(case_type == 'x' || case_type == 'z' ? RTLIL::Sa : RTLIL::Sz);
+				else
+					data.push_back((*it & bitmask) ? State::S1 : State::S0);
+			}
+		}
+	}
+
+	int len = GetSize(data);
+	RTLIL::State msb = data.empty() ? State::S0 : data.back();
+
+	if (len_in_bits < 0) {
+		if (len < 32)
+			data.resize(32, msb == State::S0 || msb == State::S1 ? RTLIL::S0 : msb);
+		return;
+	}
+
+	if (is_unsized && (len > len_in_bits))
+		log_file_error(current_filename, get_line_num(), "Unsized constant must have width of 1 bit, but have %d bits!\n", len);
+
+	for (len = len - 1; len >= 0; len--)
+		if (data[len] == State::S1)
+			break;
+	if (msb == State::S0 || msb == State::S1) {
+		len += 1;
+		data.resize(len_in_bits, State::S0);
+	} else {
+		len += 2;
+		data.resize(len_in_bits, msb);
+	}
+
+	if (len_in_bits == 0)
+		log_file_error(current_filename, get_line_num(), "Illegal integer constant size of zero (IEEE 1800-2012, 5.7).\n");
+
+	if (len > len_in_bits)
+		log_warning("Literal has a width of %d bit, but value requires %d bit. (%s:%d)\n",
+			len_in_bits, len, current_filename.c_str(), get_line_num());
+}
+
+// convert the Verilog code for a constant to an AST node
+AstNode *systemverilog_plugin::const2ast(std::string code, char case_type, bool warn_z)
+{
+	if (warn_z) {
+		AstNode *ret = const2ast(code, case_type);
+		if (ret != nullptr && std::find(ret->bits.begin(), ret->bits.end(), RTLIL::State::Sz) != ret->bits.end())
+			log_warning("Yosys has only limited support for tri-state logic at the moment. (%s:%d)\n",
+				current_filename.c_str(), get_line_num());
+		return ret;
+	}
+
+	const char *str = code.c_str();
+
+	// Strings
+	if (*str == '"') {
+		int len = strlen(str) - 2;
+		std::vector<RTLIL::State> data;
+		data.reserve(len * 8);
+		for (int i = 0; i < len; i++) {
+			unsigned char ch = str[len - i];
+			for (int j = 0; j < 8; j++) {
+				data.push_back((ch & 1) ? State::S1 : State::S0);
+				ch = ch >> 1;
+			}
+		}
+		AstNode *ast = AstNode::mkconst_bits(data, false);
+		ast->str = code;
+		return ast;
+	}
+
+	for (size_t i = 0; i < code.size(); i++)
+		if (code[i] == '_' || code[i] == ' ' || code[i] == '\t' || code[i] == '\r' || code[i] == '\n')
+			code.erase(code.begin()+(i--));
+	str = code.c_str();
+
+	char *endptr;
+	long len_in_bits = strtol(str, &endptr, 10);
+
+	// Simple base-10 integer
+	if (*endptr == 0) {
+		std::vector<RTLIL::State> data;
+		my_strtobin(data, str, -1, 10, case_type, false);
+		if (data.back() == State::S1)
+			data.push_back(State::S0);
+		return AstNode::mkconst_bits(data, true);
+	}
+
+	// unsized constant
+	if (str == endptr)
+		len_in_bits = -1;
+
+	// The "<bits>'[sS]?[bodhBODH]<digits>" syntax
+	if (*endptr == '\'')
+	{
+		std::vector<RTLIL::State> data;
+		bool is_signed = false;
+		bool is_unsized = len_in_bits < 0;
+		if (*(endptr+1) == 's' || *(endptr+1) == 'S') {
+			is_signed = true;
+			endptr++;
+		}
+		switch (*(endptr+1))
+		{
+		case 'b':
+		case 'B':
+			my_strtobin(data, endptr+2, len_in_bits, 2, case_type, is_unsized);
+			break;
+		case 'o':
+		case 'O':
+			my_strtobin(data, endptr+2, len_in_bits, 8, case_type, is_unsized);
+			break;
+		case 'd':
+		case 'D':
+			my_strtobin(data, endptr+2, len_in_bits, 10, case_type, is_unsized);
+			break;
+		case 'h':
+		case 'H':
+			my_strtobin(data, endptr+2, len_in_bits, 16, case_type, is_unsized);
+			break;
+		default:
+			char next_char = char(tolower(*(endptr+1)));
+			if (next_char == '0' || next_char == '1' || next_char == 'x' || next_char == 'z') {
+				is_unsized = true;
+				my_strtobin(data, endptr+1, 1, 2, case_type, is_unsized);
+			} else {
+				return NULL;
+			}
+		}
+		if (len_in_bits < 0) {
+			if (is_signed && data.back() == State::S1)
+				data.push_back(State::S0);
+		}
+		return AstNode::mkconst_bits(data, is_signed, is_unsized);
+	}
+
+	return NULL;
+}
diff --git a/systemverilog-plugin/third_party/yosys/const2ast.h b/systemverilog-plugin/third_party/yosys/const2ast.h
new file mode 100644
index 0000000..f7130a2
--- /dev/null
+++ b/systemverilog-plugin/third_party/yosys/const2ast.h
@@ -0,0 +1,13 @@
+#ifndef SYSTEMVERILOG_PLUGIN_CONST2AST_H
+#define SYSTEMVERILOG_PLUGIN_CONST2AST_H
+
+#include "frontends/ast/ast.h"
+#include <string>
+
+namespace systemverilog_plugin
+{
+	// this function converts a Verilog constant to an AST_CONSTANT node
+	Yosys::AST::AstNode *const2ast(std::string code, char case_type = 0, bool warn_z = false);
+}
+
+#endif // SYSTEMVERILOG_PLUGIN_CONST2AST_H
diff --git a/systemverilog-plugin/uhdmastfrontend.cc b/systemverilog-plugin/uhdmastfrontend.cc
index 5925d06..427fb37 100644
--- a/systemverilog-plugin/uhdmastfrontend.cc
+++ b/systemverilog-plugin/uhdmastfrontend.cc
@@ -25,7 +25,10 @@
                          bool shallowVisit = false);
 }
 
-YOSYS_NAMESPACE_BEGIN
+namespace systemverilog_plugin
+{
+
+using namespace ::Yosys;
 
 struct UhdmAstFrontend : public UhdmCommonFrontend {
     UhdmAstFrontend() : UhdmCommonFrontend("uhdm", "read UHDM file") {}
@@ -68,4 +71,4 @@
     void call_log_header(RTLIL::Design *design) override { log_header(design, "Executing UHDM frontend.\n"); }
 } UhdmAstFrontend;
 
-YOSYS_NAMESPACE_END
+} // namespace systemverilog_plugin
diff --git a/systemverilog-plugin/uhdmastreport.cc b/systemverilog-plugin/uhdmastreport.cc
index 9a2832f..1df94b3 100644
--- a/systemverilog-plugin/uhdmastreport.cc
+++ b/systemverilog-plugin/uhdmastreport.cc
@@ -5,7 +5,10 @@
 #include <uhdm/BaseClass.h>
 #include <unordered_set>
 
-YOSYS_NAMESPACE_BEGIN
+namespace systemverilog_plugin
+{
+
+using namespace ::Yosys;
 
 void UhdmAstReport::mark_handled(const UHDM::BaseClass *object)
 {
@@ -84,4 +87,4 @@
     index_file << "</body>\n</html>" << std::endl;
 }
 
-YOSYS_NAMESPACE_END
+} // namespace systemverilog_plugin
diff --git a/systemverilog-plugin/uhdmastreport.h b/systemverilog-plugin/uhdmastreport.h
index ae16b95..e2403fc 100644
--- a/systemverilog-plugin/uhdmastreport.h
+++ b/systemverilog-plugin/uhdmastreport.h
@@ -8,7 +8,8 @@
 #undef cover
 #include <uhdm/uhdm.h>
 
-YOSYS_NAMESPACE_BEGIN
+namespace systemverilog_plugin
+{
 
 class UhdmAstReport
 {
@@ -30,6 +31,6 @@
     void write(const std::string &directory);
 };
 
-YOSYS_NAMESPACE_END
+} // namespace systemverilog_plugin
 
 #endif
diff --git a/systemverilog-plugin/uhdmastshared.h b/systemverilog-plugin/uhdmastshared.h
index a1ad1c6..b185975 100644
--- a/systemverilog-plugin/uhdmastshared.h
+++ b/systemverilog-plugin/uhdmastshared.h
@@ -5,7 +5,8 @@
 #include <string>
 #include <unordered_map>
 
-YOSYS_NAMESPACE_BEGIN
+namespace systemverilog_plugin
+{
 
 class UhdmAstShared
 {
@@ -51,19 +52,19 @@
     bool link = false;
 
     // Top nodes of the design (modules, interfaces)
-    std::unordered_map<std::string, AST::AstNode *> top_nodes;
+    std::unordered_map<std::string, ::Yosys::AST::AstNode *> top_nodes;
 
     // UHDM node coverage report
     UhdmAstReport report;
 
     // Map from AST param nodes to their types (used for params with struct types)
-    std::unordered_map<std::string, AST::AstNode *> param_types;
+    std::unordered_map<std::string, ::Yosys::AST::AstNode *> param_types;
 
-    AST::AstNode *current_top_node = nullptr;
+    ::Yosys::AST::AstNode *current_top_node = nullptr;
     // Set of non-synthesizable objects to skip in current design;
     std::set<const UHDM::BaseClass *> nonSynthesizableObjects;
 };
 
-YOSYS_NAMESPACE_END
+} // namespace systemverilog_plugin
 
 #endif
diff --git a/systemverilog-plugin/uhdmcommonfrontend.cc b/systemverilog-plugin/uhdmcommonfrontend.cc
index 651552a..167259c 100644
--- a/systemverilog-plugin/uhdmcommonfrontend.cc
+++ b/systemverilog-plugin/uhdmcommonfrontend.cc
@@ -19,7 +19,10 @@
 
 #include "uhdmcommonfrontend.h"
 
-YOSYS_NAMESPACE_BEGIN
+namespace systemverilog_plugin
+{
+
+using namespace ::Yosys;
 
 /* Stub for AST::process */
 static void set_line_num(int) {}
@@ -147,4 +150,4 @@
     }
 }
 
-YOSYS_NAMESPACE_END
+} // namespace systemverilog_plugin
diff --git a/systemverilog-plugin/uhdmcommonfrontend.h b/systemverilog-plugin/uhdmcommonfrontend.h
index e8b59f9..4c10d10 100644
--- a/systemverilog-plugin/uhdmcommonfrontend.h
+++ b/systemverilog-plugin/uhdmcommonfrontend.h
@@ -26,7 +26,8 @@
 #include <type_traits>
 #include <vector>
 
-YOSYS_NAMESPACE_BEGIN
+namespace systemverilog_plugin
+{
 
 // FIXME (mglb): temporary fix to support UHDM both before and after the following change:
 // https://github.com/chipsalliance/UHDM/commit/d78d094448bd94926644e48adea4df293b82f101
@@ -45,16 +46,16 @@
     return new ObjT(std::forward<ArgN>(arg_n)..., true);
 }
 
-struct UhdmCommonFrontend : public Frontend {
+struct UhdmCommonFrontend : public ::Yosys::Frontend {
     UhdmAstShared shared;
     std::string report_directory;
     std::vector<std::string> args;
     UhdmCommonFrontend(std::string name, std::string short_help) : Frontend(name, short_help) {}
     virtual void print_read_options();
     virtual void help() = 0;
-    virtual AST::AstNode *parse(std::string filename) = 0;
-    virtual void call_log_header(RTLIL::Design *design) = 0;
-    void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design);
+    virtual ::Yosys::AST::AstNode *parse(std::string filename) = 0;
+    virtual void call_log_header(::Yosys::RTLIL::Design *design) = 0;
+    void execute(std::istream *&f, std::string filename, std::vector<std::string> args, ::Yosys::RTLIL::Design *design);
 };
 
-YOSYS_NAMESPACE_END
+} // namespace systemverilog_plugin
diff --git a/systemverilog-plugin/uhdmsurelogastfrontend.cc b/systemverilog-plugin/uhdmsurelogastfrontend.cc
index 3c1c2f6..a72b405 100644
--- a/systemverilog-plugin/uhdmsurelogastfrontend.cc
+++ b/systemverilog-plugin/uhdmsurelogastfrontend.cc
@@ -42,7 +42,10 @@
                          bool shallowVisit = false);
 }
 
-YOSYS_NAMESPACE_BEGIN
+namespace systemverilog_plugin
+{
+
+using namespace ::Yosys;
 
 // Store systemverilog defaults to be passed for every invocation of read_systemverilog
 static std::vector<std::string> systemverilog_defaults;
@@ -390,4 +393,4 @@
     }
 } SystemVerilogDefines;
 
-YOSYS_NAMESPACE_END
+} // namespace systemverilog_plugin