diff --git a/systemverilog-plugin/third_party/yosys/simplify.cc b/systemverilog-plugin/third_party/yosys/simplify.cc
index 78e5768..71d15a4 100644
--- a/systemverilog-plugin/third_party/yosys/simplify.cc
+++ b/systemverilog-plugin/third_party/yosys/simplify.cc
@@ -28,8 +28,8 @@
 
 #include "kernel/log.h"
 #include "libs/sha1/sha1.h"
-#include "frontends/verilog/verilog_frontend.h"
-#include "ast.h"
+
+#include "const2ast.h"
 
 #include <sstream>
 #include <stdarg.h>
@@ -37,149 +37,22 @@
 #include <math.h>
 
 YOSYS_NAMESPACE_BEGIN
-
-using namespace AST;
-using namespace AST_INTERNAL;
-
-// Process a format string and arguments for $display, $write, $sprintf, etc
-
-std::string AstNode::process_format_str(const std::string &sformat, int next_arg, int stage, int width_hint, bool sign_hint) {
-	// Other arguments are placeholders. Process the string as we go through it
-	std::string sout;
-	for (size_t i = 0; i < sformat.length(); i++)
-	{
-		// format specifier
-		if (sformat[i] == '%')
-		{
-			// If there's no next character, that's a problem
-			if (i+1 >= sformat.length())
-				log_file_error(filename, location.first_line, "System task `%s' called with `%%' at end of string.\n", str.c_str());
-
-			char cformat = sformat[++i];
-
-			// %% is special, does not need a matching argument
-			if (cformat == '%')
-			{
-				sout += '%';
-				continue;
-			}
-
-			bool got_len = false;
-			bool got_zlen = false;
-			int len_value = 0;
-
-			while ('0' <= cformat && cformat <= '9')
-			{
-				if (!got_len && cformat == '0')
-					got_zlen = true;
-
-				got_len = true;
-				len_value = 10*len_value + (cformat - '0');
-
-				cformat = sformat[++i];
-			}
-
-			// Simplify the argument
-			AstNode *node_arg = nullptr;
-
-			// Everything from here on depends on the format specifier
-			switch (cformat)
-			{
-				case 's':
-				case 'S':
-				case 'd':
-				case 'D':
-					if (got_len && len_value != 0)
-						goto unsupported_format;
-					YS_FALLTHROUGH
-				case 'x':
-				case 'X':
-					if (next_arg >= GetSize(children))
-						log_file_error(filename, location.first_line, "Missing argument for %%%c format specifier in system task `%s'.\n",
-								cformat, str.c_str());
-
-					node_arg = children[next_arg++];
-					while (node_arg->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
-					if (node_arg->type != AST_CONSTANT)
-						log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str());
-					break;
-
-				case 'm':
-				case 'M':
-					if (got_len)
-						goto unsupported_format;
-					break;
-
-				case 'l':
-				case 'L':
-					if (got_len)
-						goto unsupported_format;
-					break;
-
-				default:
-				unsupported_format:
-					log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str());
-					break;
-			}
-
-			switch (cformat)
-			{
-				case 's':
-				case 'S':
-					sout += node_arg->bitsAsConst().decode_string();
-					break;
-
-				case 'd':
-				case 'D':
-					sout += stringf("%d", node_arg->bitsAsConst().as_int());
-					break;
-
-				case 'x':
-				case 'X':
-					{
-						Const val = node_arg->bitsAsConst();
-
-						while (GetSize(val) % 4 != 0)
-							val.bits.push_back(State::S0);
-
-						int len = GetSize(val) / 4;
-						for (int i = len; i < len_value; i++)
-							sout += got_zlen ? '0' : ' ';
-
-						for (int i = len-1; i >= 0; i--) {
-							Const digit = val.extract(4*i, 4);
-							if (digit.is_fully_def())
-								sout += stringf(cformat == 'x' ? "%x" : "%X", digit.as_int());
-							else
-								sout += cformat == 'x' ? "x" : "X";
-						}
-					}
-					break;
-
-				case 'm':
-				case 'M':
-					sout += log_id(current_module->name);
-					break;
-
-				case 'l':
-				case 'L':
-					sout += log_id(current_module->name);
-					break;
-
-				default:
-					log_abort();
-			}
-		}
-
-		// not a format specifier
-		else
-			sout += sformat[i];
-	}
-	return sout;
+namespace VERILOG_FRONTEND
+{
+extern bool sv_mode;
 }
+YOSYS_NAMESPACE_END
 
+namespace systemverilog_plugin
+{
 
-void AstNode::annotateTypedEnums(AstNode *template_node)
+using namespace ::Yosys;
+using namespace ::Yosys::AST;
+using namespace ::Yosys::AST_INTERNAL;
+
+bool simplify(AstNode *ast_node, bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param);
+
+void annotateTypedEnums(AstNode *ast_node, AstNode *template_node)
 {
 	//check if enum
 	if (template_node->attributes.count(ID::enum_type)) {
@@ -192,7 +65,7 @@
 		log_assert(current_scope.count(enum_type) == 1);
 		AstNode *enum_node = current_scope.at(enum_type);
 		log_assert(enum_node->type == AST_ENUM);
-		while (enum_node->simplify(true, false, false, 1, -1, false, true)) { }
+		while (simplify(enum_node, true, false, false, 1, -1, false, true)) { }
 		//get width from 1st enum item:
 		log_assert(enum_node->children.size() >= 1);
 		AstNode *enum_item0 = enum_node->children[0];
@@ -233,7 +106,7 @@
 			RTLIL::Const val = enum_item->children[0]->bitsAsConst(width, is_signed);
 			enum_item_str.append(val.as_string());
 			//set attribute for available val to enum item name mappings
-			attributes[enum_item_str.c_str()] = mkconst_str(enum_item->str);
+			ast_node->attributes[enum_item_str.c_str()] = AstNode::mkconst_str(enum_item->str);
 		}
 	}
 }
@@ -407,120 +280,7 @@
 	return (is_union ? packed_width : offset);
 }
 
-[[noreturn]] static void struct_op_error(AstNode *node)
-{
-	log_file_error(node->filename, node->location.first_line, "Unsupported operation for struct/union member %s\n", node->str.c_str()+1);
-}
-
-static AstNode *node_int(int ival)
-{
-	return AstNode::mkconst_int(ival, true);
-}
-
-static AstNode *multiply_by_const(AstNode *expr_node, int stride)
-{
-	return new AstNode(AST_MUL, expr_node, node_int(stride));
-}
-
-static AstNode *normalize_struct_index(AstNode *expr, AstNode *member_node, int dimension)
-{
-	expr = expr->clone();
-
-	int offset = get_struct_range_offset(member_node, dimension);
-	if (offset) {
-		expr = new AstNode(AST_SUB, expr, node_int(offset));
-	}
-
-	if (member_node->multirange_swapped[dimension]) {
-		// The dimension has swapped range; swap index into the struct accordingly.
-		int msb = get_struct_range_width(member_node, dimension) - 1;
-		expr = new AstNode(AST_SUB, node_int(msb), expr);
-	}
-
-	return expr;
-}
-
-static AstNode *struct_index_lsb_offset(AstNode *lsb_offset, AstNode *rnode, AstNode *member_node, int dimension, int &stride)
-{
-	stride /= get_struct_range_width(member_node, dimension);
-	auto right = normalize_struct_index(rnode->children.back(), member_node, dimension);
-	auto offset = stride > 1 ? multiply_by_const(right, stride) : right;
-	return lsb_offset ? new AstNode(AST_ADD, lsb_offset, offset) : offset;
-}
-
-static AstNode *struct_index_msb_offset(AstNode *lsb_offset, AstNode *rnode, AstNode *member_node, int dimension, int stride)
-{
-	log_assert(rnode->children.size() <= 2);
-
-	// Offset to add to LSB
-	AstNode *offset;
-	if (rnode->children.size() == 1) {
-		// Index, e.g. s.a[i]
-		offset = node_int(stride - 1);
-	}
-	else {
-		// rnode->children.size() == 2
-		// Slice, e.g. s.a[i:j]
-		auto left = normalize_struct_index(rnode->children[0], member_node, dimension);
-		auto right = normalize_struct_index(rnode->children[1], member_node, dimension);
-		offset = new AstNode(AST_SUB, left, right);
-		if (stride > 1) {
-			// offset = (msb - lsb + 1)*stride - 1
-			auto slice_width = new AstNode(AST_ADD, offset, node_int(1));
-			offset = new AstNode(AST_SUB, multiply_by_const(slice_width, stride), node_int(1));
-		}
-	}
-
-	return new AstNode(AST_ADD, lsb_offset, offset);
-}
-
-
-AstNode *AST::make_struct_member_range(AstNode *node, AstNode *member_node)
-{
-	// Work out the range in the packed array that corresponds to a struct member
-	// taking into account any range operations applicable to the current node
-	// such as array indexing or slicing
-	int range_left = member_node->range_left;
-	int range_right = member_node->range_right;
-	if (node->children.empty()) {
-		// no range operations apply, return the whole width
-		return make_range(range_left - range_right, 0);
-	}
-
-	if (node->children.size() != 1) {
-		struct_op_error(node);
-	}
-
-	// Range operations
-	auto rnode = node->children[0];
-	AstNode *lsb_offset = NULL;
-	int stride = range_left - range_right + 1;
-	size_t i = 0;
-
-	// Calculate LSB offset for the final index / slice
-	if (rnode->type == AST_RANGE) {
-		lsb_offset = struct_index_lsb_offset(lsb_offset, rnode, member_node, i, stride);
-	}
-	else if (rnode->type == AST_MULTIRANGE) {
-		// Add offset for each dimension
-		auto mrnode = rnode;
-		for (i = 0; i < mrnode->children.size(); i++) {
-			rnode = mrnode->children[i];
-			lsb_offset = struct_index_lsb_offset(lsb_offset, rnode, member_node, i, stride);
-		}
-		i--;  // Step back to the final index / slice
-	}
-	else {
-		struct_op_error(node);
-	}
-
-	// Calculate MSB offset for the final index / slice
-	auto msb_offset = struct_index_msb_offset(lsb_offset->clone(), rnode, member_node, i, stride);
-
-	return new AstNode(AST_RANGE, msb_offset, lsb_offset);
-}
-
-AstNode *AST::get_struct_member(const AstNode *node)
+AstNode get_struct_member(const AstNode *node)
 {
 	AST::AstNode *member_node;
 	if (node->attributes.count(ID::wiretype) && (member_node = node->attributes.at(ID::wiretype)) &&
@@ -606,84 +366,6 @@
 	return prefix + str;
 }
 
-// direct access to this global should be limited to the following two functions
-static const RTLIL::Design *simplify_design_context = nullptr;
-
-void AST::set_simplify_design_context(const RTLIL::Design *design)
-{
-	log_assert(!simplify_design_context || !design);
-	simplify_design_context = design;
-}
-
-// lookup the module with the given name in the current design context
-static const RTLIL::Module* lookup_module(const std::string &name)
-{
-	return simplify_design_context->module(name);
-}
-
-const RTLIL::Module* AstNode::lookup_cell_module()
-{
-	log_assert(type == AST_CELL);
-
-	auto reprocess_after = [this] (const std::string &modname) {
-		if (!attributes.count(ID::reprocess_after))
-			attributes[ID::reprocess_after] = AstNode::mkconst_str(modname);
-	};
-
-	const AstNode *celltype = nullptr;
-	for (const AstNode *child : children)
-		if (child->type == AST_CELLTYPE) {
-			celltype = child;
-			break;
-		}
-	log_assert(celltype != nullptr);
-
-	const RTLIL::Module *module = lookup_module(celltype->str);
-	if (!module)
-		module = lookup_module("$abstract" + celltype->str);
-	if (!module) {
-		if (celltype->str.at(0) != '$')
-			reprocess_after(celltype->str);
-		return nullptr;
-	}
-
-	// build a mapping from true param name to param value
-	size_t para_counter = 0;
-	dict<RTLIL::IdString, RTLIL::Const> cell_params_map;
-	for (AstNode *child : children) {
-		if (child->type != AST_PARASET)
-			continue;
-
-		if (child->str.empty() && para_counter >= module->avail_parameters.size())
-			return nullptr; // let hierarchy handle this error
-		IdString paraname = child->str.empty() ? module->avail_parameters[para_counter++] : child->str;
-
-		const AstNode *value = child->children[0];
-		if (value->type != AST_REALVALUE && value->type != AST_CONSTANT)
-			return nullptr; // let genrtlil handle this error
-		cell_params_map[paraname] = value->asParaConst();
-	}
-
-	// put the parameters in order and generate the derived module name
-	std::vector<std::pair<RTLIL::IdString, RTLIL::Const>> named_parameters;
-	for (RTLIL::IdString param : module->avail_parameters) {
-		auto it = cell_params_map.find(param);
-		if (it != cell_params_map.end())
-			named_parameters.emplace_back(it->first, it->second);
-	}
-	std::string modname = celltype->str;
-	if (cell_params_map.size()) // not named_parameters to cover hierarchical defparams
-		modname = derived_module_name(celltype->str, named_parameters);
-
-	// try to find the resolved module
-	module = lookup_module(modname);
-	if (!module) {
-		reprocess_after(modname);
-		return nullptr;
-	}
-	return module;
-}
-
 // returns whether an expression contains an unbased unsized literal; does not
 // check the literal exists in a self-determined context
 static bool contains_unbased_unsized(const AstNode *node)
@@ -837,6 +519,21 @@
 		check_auto_nosync(child);
 }
 
+static inline std::string encode_filename(const std::string &filename)
+{    
+    std::stringstream val; 
+    if (!std::any_of(filename.begin(), filename.end(), [](char c) { 
+        return static_cast<unsigned char>(c) < 33 || static_cast<unsigned char>(c) > 126; 
+    })) return filename;
+    for (unsigned char const c : filename) {
+        if (c < 33 || c > 126) 
+            val << stringf("$%02x", c);
+        else 
+            val << c;
+    }    
+    return val.str();
+}
+
 // convert the AST into a simpler AST that has all parameters substituted by their
 // values, unrolled for-loops, expanded generate blocks, etc. when this function
 // is done with an AST it can be converted into RTLIL using genRTLIL().
@@ -1280,7 +977,7 @@
 
 				// create the indirection wire
 				std::stringstream sstr;
-				sstr << "$indirect$" << ref->name.c_str() << "$" << RTLIL::encode_filename(filename) << ":" << location.first_line << "$" << (autoidx++);
+				sstr << "$indirect$" << ref->name.c_str() << "$" << encode_filename(filename) << ":" << location.first_line << "$" << (autoidx++);
 				std::string tmp_str = sstr.str();
 				add_wire_for_ref(ref, tmp_str);
 
@@ -1825,7 +1522,7 @@
 			attributes[ID::wiretype] = mkconst_str(resolved_type_node->str);
 
 			// if an enum then add attributes to support simulator tracing
-			annotateTypedEnums(template_node);
+			annotateTypedEnums(ast_node, template_node);
 
 			// Insert clones children from template at beginning
 			for (int i  = 0; i < GetSize(template_node->children); i++)
@@ -2181,7 +1878,7 @@
 			std::swap(data_range_left, data_range_right);
 
 		std::stringstream sstr;
-		sstr << "$mem2bits$" << str << "$" << RTLIL::encode_filename(filename) << ":" << location.first_line << "$" << (autoidx++);
+		sstr << "$mem2bits$" << str << "$" << encode_filename(filename) << ":" << location.first_line << "$" << (autoidx++);
 		std::string wire_id = sstr.str();
 
 		AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(data_range_left, true), mkconst_int(data_range_right, true)));
@@ -2777,14 +2474,14 @@
 			// mask and shift operations, disabled for now
 
 			AstNode *wire_mask = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(source_width-1, true), mkconst_int(0, true)));
-			wire_mask->str = stringf("$bitselwrite$mask$%s:%d$%d", RTLIL::encode_filename(filename).c_str(), location.first_line, autoidx++);
+			wire_mask->str = stringf("$bitselwrite$mask$%s:%d$%d", encode_filename(filename).c_str(), location.first_line, autoidx++);
 			wire_mask->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
 			wire_mask->is_logic = true;
 			while (wire_mask->simplify(true, false, false, 1, -1, false, false)) { }
 			current_ast_mod->children.push_back(wire_mask);
 
 			AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(source_width-1, true), mkconst_int(0, true)));
-			wire_data->str = stringf("$bitselwrite$data$%s:%d$%d", RTLIL::encode_filename(filename).c_str(), location.first_line, autoidx++);
+			wire_data->str = stringf("$bitselwrite$data$%s:%d$%d", encode_filename(filename).c_str(), location.first_line, autoidx++);
 			wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
 			wire_data->is_logic = true;
 			while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
@@ -2795,7 +2492,7 @@
 			shift_expr->detectSignWidth(shamt_width_hint, shamt_sign_hint);
 
 			AstNode *wire_sel = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(shamt_width_hint-1, true), mkconst_int(0, true)));
-			wire_sel->str = stringf("$bitselwrite$sel$%s:%d$%d", RTLIL::encode_filename(filename).c_str(), location.first_line, autoidx++);
+			wire_sel->str = stringf("$bitselwrite$sel$%s:%d$%d", encode_filename(filename).c_str(), location.first_line, autoidx++);
 			wire_sel->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
 			wire_sel->is_logic = true;
 			wire_sel->is_signed = shamt_sign_hint;
@@ -2874,7 +2571,7 @@
 	if (stage > 1 && (type == AST_ASSERT || type == AST_ASSUME || type == AST_LIVE || type == AST_FAIR || type == AST_COVER) && current_block != NULL)
 	{
 		std::stringstream sstr;
-		sstr << "$formal$" << RTLIL::encode_filename(filename) << ":" << location.first_line << "$" << (autoidx++);
+		sstr << "$formal$" << encode_filename(filename) << ":" << location.first_line << "$" << (autoidx++);
 		std::string id_check = sstr.str() + "_CHECK", id_en = sstr.str() + "_EN";
 
 		AstNode *wire_check = new AstNode(AST_WIRE);
@@ -2983,7 +2680,7 @@
 			newNode = new AstNode(AST_BLOCK);
 
 			AstNode *wire_tmp = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(width_hint-1, true), mkconst_int(0, true)));
-			wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", RTLIL::encode_filename(filename).c_str(), location.first_line, autoidx++);
+			wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", encode_filename(filename).c_str(), location.first_line, autoidx++);
 			current_ast_mod->children.push_back(wire_tmp);
 			current_scope[wire_tmp->str] = wire_tmp;
 			wire_tmp->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
@@ -3021,7 +2718,7 @@
 			(children[0]->children.size() == 1 || children[0]->children.size() == 2) && children[0]->children[0]->type == AST_RANGE)
 	{
 		std::stringstream sstr;
-		sstr << "$memwr$" << children[0]->str << "$" << RTLIL::encode_filename(filename) << ":" << location.first_line << "$" << (autoidx++);
+		sstr << "$memwr$" << children[0]->str << "$" << encode_filename(filename) << ":" << location.first_line << "$" << (autoidx++);
 		std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA", id_en = sstr.str() + "_EN";
 
 		int mem_width, mem_size, addr_bits;
@@ -3293,7 +2990,7 @@
 					AstNode *reg = new AstNode(AST_WIRE, new AstNode(AST_RANGE,
 							mkconst_int(width_hint-1, true), mkconst_int(0, true)));
 
-					reg->str = stringf("$past$%s:%d$%d$%d", RTLIL::encode_filename(filename).c_str(), location.first_line, myidx, i);
+					reg->str = stringf("$past$%s:%d$%d$%d", encode_filename(filename).c_str(), location.first_line, myidx, i);
 					reg->is_reg = true;
 					reg->is_signed = sign_hint;
 
@@ -3828,7 +3525,7 @@
 
 
 		std::stringstream sstr;
-		sstr << str << "$func$" << RTLIL::encode_filename(filename) << ":" << location.first_line << "$" << (autoidx++) << '.';
+		sstr << str << "$func$" << encode_filename(filename) << ":" << location.first_line << "$" << (autoidx++) << '.';
 		std::string prefix = sstr.str();
 
 		AstNode *decl = current_scope[str];
@@ -4375,1300 +4072,4 @@
 	return did_something;
 }
 
-void AstNode::replace_result_wire_name_in_function(const std::string &from, const std::string &to)
-{
-	for (AstNode *child : children)
-		child->replace_result_wire_name_in_function(from, to);
-	if (str == from && type != AST_FCALL && type != AST_TCALL)
-		str = to;
-}
-
-// replace a readmem[bh] TCALL ast node with a block of memory assignments
-AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init)
-{
-	int mem_width, mem_size, addr_bits;
-	memory->meminfo(mem_width, mem_size, addr_bits);
-
-	AstNode *block = new AstNode(AST_BLOCK);
-
-	AstNode *meminit = nullptr;
-	int next_meminit_cursor=0;
-	vector<State> meminit_bits;
-	vector<State> en_bits;
-	int meminit_size=0;
-
-	for (int i = 0; i < mem_width; i++)
-		en_bits.push_back(State::S1);
-
-	std::ifstream f;
-	f.open(mem_filename.c_str());
-	if (f.fail()) {
-#ifdef _WIN32
-		char slash = '\\';
-#else
-		char slash = '/';
-#endif
-		std::string path = filename.substr(0, filename.find_last_of(slash)+1);
-		f.open(path + mem_filename.c_str());
-		yosys_input_files.insert(path + mem_filename);
-	} else {
-		yosys_input_files.insert(mem_filename);
-	}
-	if (f.fail() || GetSize(mem_filename) == 0)
-		log_file_error(filename, location.first_line, "Can not open file `%s` for %s.\n", mem_filename.c_str(), str.c_str());
-
-	log_assert(GetSize(memory->children) == 2 && memory->children[1]->type == AST_RANGE && memory->children[1]->range_valid);
-	int range_left =  memory->children[1]->range_left, range_right =  memory->children[1]->range_right;
-	int range_min = min(range_left, range_right), range_max = max(range_left, range_right);
-
-	if (start_addr < 0)
-		start_addr = range_min;
-
-	if (finish_addr < 0)
-		finish_addr = range_max + 1;
-
-	bool in_comment = false;
-	int increment = start_addr <= finish_addr ? +1 : -1;
-	int cursor = start_addr;
-
-	while (!f.eof())
-	{
-		std::string line, token;
-		std::getline(f, line);
-
-		for (int i = 0; i < GetSize(line); i++) {
-			if (in_comment && line.compare(i, 2, "*/") == 0) {
-				line[i] = ' ';
-				line[i+1] = ' ';
-				in_comment = false;
-				continue;
-			}
-			if (!in_comment && line.compare(i, 2, "/*") == 0)
-				in_comment = true;
-			if (in_comment)
-				line[i] = ' ';
-		}
-
-		while (1)
-		{
-			token = next_token(line, " \t\r\n");
-			if (token.empty() || token.compare(0, 2, "//") == 0)
-				break;
-
-			if (token[0] == '@') {
-				token = token.substr(1);
-				const char *nptr = token.c_str();
-				char *endptr;
-				cursor = strtol(nptr, &endptr, 16);
-				if (!*nptr || *endptr)
-					log_file_error(filename, location.first_line, "Can not parse address `%s` for %s.\n", nptr, str.c_str());
-				continue;
-			}
-
-			AstNode *value = VERILOG_FRONTEND::const2ast(stringf("%d'%c", mem_width, is_readmemh ? 'h' : 'b') + token);
-
-			if (unconditional_init)
-			{
-				if (meminit == nullptr || cursor != next_meminit_cursor)
-				{
-					if (meminit != nullptr) {
-						meminit->children[1] = AstNode::mkconst_bits(meminit_bits, false);
-						meminit->children[3] = AstNode::mkconst_int(meminit_size, false);
-					}
-
-					meminit = new AstNode(AST_MEMINIT);
-					meminit->children.push_back(AstNode::mkconst_int(cursor, false));
-					meminit->children.push_back(nullptr);
-					meminit->children.push_back(AstNode::mkconst_bits(en_bits, false));
-					meminit->children.push_back(nullptr);
-					meminit->str = memory->str;
-					meminit->id2ast = memory;
-					meminit_bits.clear();
-					meminit_size = 0;
-
-					current_ast_mod->children.push_back(meminit);
-					next_meminit_cursor = cursor;
-				}
-
-				meminit_size++;
-				next_meminit_cursor++;
-				meminit_bits.insert(meminit_bits.end(), value->bits.begin(), value->bits.end());
-				delete value;
-			}
-			else
-			{
-				block->children.push_back(new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER, new AstNode(AST_RANGE, AstNode::mkconst_int(cursor, false))), value));
-				block->children.back()->children[0]->str = memory->str;
-				block->children.back()->children[0]->id2ast = memory;
-				block->children.back()->children[0]->was_checked = true;
-			}
-
-			cursor += increment;
-			if ((cursor == finish_addr+increment) || (increment > 0 && cursor > range_max) || (increment < 0 && cursor < range_min))
-				break;
-		}
-
-		if ((cursor == finish_addr+increment) || (increment > 0 && cursor > range_max) || (increment < 0 && cursor < range_min))
-			break;
-	}
-
-	if (meminit != nullptr) {
-		meminit->children[1] = AstNode::mkconst_bits(meminit_bits, false);
-		meminit->children[3] = AstNode::mkconst_int(meminit_size, false);
-	}
-
-	return block;
-}
-
-// annotate the names of all wires and other named objects in a named generate
-// or procedural block; nested blocks are themselves annotated such that the
-// prefix is carried forward, but resolution of their children is deferred
-void AstNode::expand_genblock(const std::string &prefix)
-{
-	if (type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL || type == AST_WIRETYPE || type == AST_PREFIX) {
-		log_assert(!str.empty());
-
-		// search starting in the innermost scope and then stepping outward
-		for (size_t ppos = prefix.size() - 1; ppos; --ppos) {
-			if (prefix.at(ppos) != '.') continue;
-
-			std::string new_prefix = prefix.substr(0, ppos + 1);
-			auto attempt_resolve = [&new_prefix](const std::string &ident) -> std::string {
-				std::string new_name = prefix_id(new_prefix, ident);
-				if (current_scope.count(new_name))
-					return new_name;
-				return {};
-			};
-
-			// attempt to resolve the full identifier
-			std::string resolved = attempt_resolve(str);
-			if (!resolved.empty()) {
-				str = resolved;
-				break;
-			}
-
-			// attempt to resolve hierarchical prefixes within the identifier,
-			// as the prefix could refer to a local scope which exists but
-			// hasn't yet been elaborated
-			for (size_t spos = str.size() - 1; spos; --spos) {
-				if (str.at(spos) != '.') continue;
-				resolved = attempt_resolve(str.substr(0, spos));
-				if (!resolved.empty()) {
-					str = resolved + str.substr(spos);
-					ppos = 1; // break outer loop
-					break;
-				}
-			}
-
-		}
-	}
-
-	auto prefix_node = [&prefix](AstNode* child) {
-		if (child->str.empty()) return;
-		std::string new_name = prefix_id(prefix, child->str);
-		if (child->type == AST_FUNCTION)
-			child->replace_result_wire_name_in_function(child->str, new_name);
-		else
-			child->str = new_name;
-		current_scope[new_name] = child;
-	};
-
-	for (size_t i = 0; i < children.size(); i++) {
-		AstNode *child = children[i];
-
-		switch (child->type) {
-		case AST_WIRE:
-		case AST_MEMORY:
-		case AST_PARAMETER:
-		case AST_LOCALPARAM:
-		case AST_FUNCTION:
-		case AST_TASK:
-		case AST_CELL:
-		case AST_TYPEDEF:
-		case AST_ENUM_ITEM:
-		case AST_GENVAR:
-			prefix_node(child);
-			break;
-
-		case AST_BLOCK:
-		case AST_GENBLOCK:
-			if (!child->str.empty())
-				prefix_node(child);
-			break;
-
-		case AST_ENUM:
-			current_scope[child->str] = child;
-			for (auto enode : child->children){
-				log_assert(enode->type == AST_ENUM_ITEM);
-				prefix_node(enode);
-			}
-			break;
-
-		default:
-			break;
-		}
-	}
-
-	for (size_t i = 0; i < children.size(); i++) {
-		AstNode *child = children[i];
-		// AST_PREFIX member names should not be prefixed; we recurse into them
-		// as normal to ensure indices and ranges are properly resolved, and
-		// then restore the previous string
-		if (type == AST_PREFIX && i == 1) {
-			std::string backup_scope_name = child->str;
-			child->expand_genblock(prefix);
-			child->str = backup_scope_name;
-			continue;
-		}
-		// functions/tasks may reference wires, constants, etc. in this scope
-		if (child->type == AST_FUNCTION || child->type == AST_TASK)
-			continue;
-		// named blocks pick up the current prefix and will expanded later
-		if ((child->type == AST_GENBLOCK || child->type == AST_BLOCK) && !child->str.empty())
-			continue;
-
-		child->expand_genblock(prefix);
-	}
-}
-
-// add implicit AST_GENBLOCK names according to IEEE 1364-2005 Section 12.4.3 or
-// IEEE 1800-2017 Section 27.6
-void AstNode::label_genblks(std::set<std::string>& existing, int &counter)
-{
-	switch (type) {
-	case AST_GENIF:
-	case AST_GENFOR:
-	case AST_GENCASE:
-		// seeing a proper generate control flow construct increments the
-		// counter once
-		++counter;
-		for (AstNode *child : children)
-			child->label_genblks(existing, counter);
-		break;
-
-	case AST_GENBLOCK: {
-		// if this block is unlabeled, generate its corresponding unique name
-		for (int padding = 0; str.empty(); ++padding) {
-			std::string candidate = "\\genblk";
-			for (int i = 0; i < padding; ++i)
-				candidate += '0';
-			candidate += std::to_string(counter);
-			if (!existing.count(candidate))
-				str = candidate;
-		}
-		// within a genblk, the counter starts fresh
-		std::set<std::string> existing_local = existing;
-		int counter_local = 0;
-		for (AstNode *child : children)
-			child->label_genblks(existing_local, counter_local);
-		break;
-	}
-
-	default:
-		// track names which could conflict with implicit genblk names
-		if (str.rfind("\\genblk", 0) == 0)
-			existing.insert(str);
-		for (AstNode *child : children)
-			child->label_genblks(existing, counter);
-		break;
-	}
-}
-
-// helper function for mem2reg_as_needed_pass1
-static void mark_memories_assign_lhs_complex(dict<AstNode*, pool<std::string>> &mem2reg_places,
-		dict<AstNode*, uint32_t> &mem2reg_candidates, AstNode *that)
-{
-	for (auto &child : that->children)
-		mark_memories_assign_lhs_complex(mem2reg_places, mem2reg_candidates, child);
-
-	if (that->type == AST_IDENTIFIER && that->id2ast && that->id2ast->type == AST_MEMORY) {
-		AstNode *mem = that->id2ast;
-		if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_CMPLX_LHS))
-			mem2reg_places[mem].insert(stringf("%s:%d", RTLIL::encode_filename(that->filename).c_str(), that->location.first_line));
-		mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CMPLX_LHS;
-	}
-}
-
-// 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)
-{
-	uint32_t children_flags = 0;
-	int lhs_children_counter = 0;
-
-	if (type == AST_TYPEDEF)
-		return; // don't touch content of typedefs
-
-	if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ)
-	{
-		// mark all memories that are used in a complex expression on the left side of an assignment
-		for (auto &lhs_child : children[0]->children)
-			mark_memories_assign_lhs_complex(mem2reg_places, mem2reg_candidates, lhs_child);
-
-		if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY)
-		{
-			AstNode *mem = children[0]->id2ast;
-
-			// activate mem2reg if this is assigned in an async proc
-			if (flags & AstNode::MEM2REG_FL_ASYNC) {
-				if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ASYNC))
-					mem2reg_places[mem].insert(stringf("%s:%d", RTLIL::encode_filename(filename).c_str(), location.first_line));
-				mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ASYNC;
-			}
-
-			// remember if this is assigned blocking (=)
-			if (type == AST_ASSIGN_EQ) {
-				if (!(proc_flags[mem] & AstNode::MEM2REG_FL_EQ1))
-					mem2reg_places[mem].insert(stringf("%s:%d", RTLIL::encode_filename(filename).c_str(), location.first_line));
-				proc_flags[mem] |= AstNode::MEM2REG_FL_EQ1;
-			}
-
-			// for proper (non-init) writes: remember if this is a constant index or not
-			if ((flags & MEM2REG_FL_INIT) == 0) {
-				if (children[0]->children.size() && children[0]->children[0]->type == AST_RANGE && children[0]->children[0]->children.size()) {
-					if (children[0]->children[0]->children[0]->type == AST_CONSTANT)
-						mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CONST_LHS;
-					else
-						mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_VAR_LHS;
-				}
-			}
-
-			// remember where this is
-			if (flags & MEM2REG_FL_INIT) {
-				if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_INIT))
-					mem2reg_places[mem].insert(stringf("%s:%d", RTLIL::encode_filename(filename).c_str(), location.first_line));
-				mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_INIT;
-			} else {
-				if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ELSE))
-					mem2reg_places[mem].insert(stringf("%s:%d", RTLIL::encode_filename(filename).c_str(), location.first_line));
-				mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ELSE;
-			}
-		}
-
-		lhs_children_counter = 1;
-	}
-
-	if (type == AST_IDENTIFIER && id2ast && id2ast->type == AST_MEMORY)
-	{
-		AstNode *mem = id2ast;
-
-		// flag if used after blocking assignment (in same proc)
-		if ((proc_flags[mem] & AstNode::MEM2REG_FL_EQ1) && !(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_EQ2)) {
-			mem2reg_places[mem].insert(stringf("%s:%d", RTLIL::encode_filename(filename).c_str(), location.first_line));
-			mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_EQ2;
-		}
-	}
-
-	// also activate if requested, either by using mem2reg attribute or by declaring array as 'wire' instead of 'reg' or 'logic'
-	if (type == AST_MEMORY && (get_bool_attribute(ID::mem2reg) || (flags & AstNode::MEM2REG_FL_ALL) || !(is_reg || is_logic)))
-		mem2reg_candidates[this] |= AstNode::MEM2REG_FL_FORCED;
-
-	if ((type == AST_MODULE || type == AST_INTERFACE) && get_bool_attribute(ID::mem2reg))
-		children_flags |= AstNode::MEM2REG_FL_ALL;
-
-	dict<AstNode*, uint32_t> *proc_flags_p = NULL;
-
-	if (type == AST_ALWAYS) {
-		int count_edge_events = 0;
-		for (auto child : children)
-			if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE)
-				count_edge_events++;
-		if (count_edge_events != 1)
-			children_flags |= AstNode::MEM2REG_FL_ASYNC;
-		proc_flags_p = new dict<AstNode*, uint32_t>;
-	}
-	else if (type == AST_INITIAL) {
-		children_flags |= AstNode::MEM2REG_FL_INIT;
-		proc_flags_p = new dict<AstNode*, uint32_t>;
-	}
-
-	uint32_t backup_flags = flags;
-	flags |= children_flags;
-	log_assert((flags & ~0x000000ff) == 0);
-
-	for (auto child : children)
-	{
-		if (lhs_children_counter > 0) {
-			lhs_children_counter--;
-			if (child->children.size() && child->children[0]->type == AST_RANGE && child->children[0]->children.size()) {
-				for (auto c : child->children[0]->children) {
-					if (proc_flags_p)
-						c->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, *proc_flags_p, flags);
-					else
-						c->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, proc_flags, flags);
-				}
-			}
-		} else
-		if (proc_flags_p)
-			child->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, *proc_flags_p, flags);
-		else
-			child->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, proc_flags, flags);
-	}
-
-	flags &= ~children_flags | backup_flags;
-
-	if (proc_flags_p) {
-#ifndef NDEBUG
-		for (auto it : *proc_flags_p)
-			log_assert((it.second & ~0xff000000) == 0);
-#endif
-		delete proc_flags_p;
-	}
-}
-
-bool AstNode::mem2reg_check(pool<AstNode*> &mem2reg_set)
-{
-	if (type != AST_IDENTIFIER || !id2ast || !mem2reg_set.count(id2ast))
-		return false;
-
-	if (children.empty() || children[0]->type != AST_RANGE || GetSize(children[0]->children) != 1)
-		log_file_error(filename, location.first_line, "Invalid array access.\n");
-
-	return true;
-}
-
-void AstNode::mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes)
-{
-	log_assert(mem2reg_set.count(this) == 0);
-
-	if (mem2reg_set.count(id2ast))
-		id2ast = nullptr;
-
-	for (size_t i = 0; i < children.size(); i++) {
-		if (mem2reg_set.count(children[i]) > 0) {
-			delnodes.push_back(children[i]);
-			children.erase(children.begin() + (i--));
-		} else {
-			children[i]->mem2reg_remove(mem2reg_set, delnodes);
-		}
-	}
-}
-
-// actually replace memories with registers
-bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block, AstNode *&async_block)
-{
-	bool did_something = false;
-
-	if (type == AST_BLOCK)
-		block = this;
-
-	if (type == AST_FUNCTION || type == AST_TASK)
-		return false;
-
-	if (type == AST_TYPEDEF)
-		return false;
-
-	if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast))
-	{
-		log_assert(children[0]->type == AST_CONSTANT);
-		log_assert(children[1]->type == AST_CONSTANT);
-		log_assert(children[2]->type == AST_CONSTANT);
-		log_assert(children[3]->type == AST_CONSTANT);
-
-		int cursor = children[0]->asInt(false);
-		Const data = children[1]->bitsAsConst();
-		Const en = children[2]->bitsAsConst();
-		int length = children[3]->asInt(false);
-
-		if (length != 0)
-		{
-			AstNode *block = new AstNode(AST_INITIAL, new AstNode(AST_BLOCK));
-			mod->children.push_back(block);
-			block = block->children[0];
-
-			int wordsz = GetSize(data) / length;
-
-			for (int i = 0; i < length; i++) {
-				int pos = 0;
-				while (pos < wordsz) {
-					if (en[pos] != State::S1) {
-						pos++;
-					} else {
-						int epos = pos + 1;
-						while (epos < wordsz && en[epos] == State::S1)
-							epos++;
-						int clen = epos - pos;
-						AstNode *range = new AstNode(AST_RANGE, AstNode::mkconst_int(cursor+i, false));
-						if (pos != 0 || epos != wordsz) {
-							int left;
-							int right;
-							AstNode *mrange = id2ast->children[0];
-							if (mrange->range_left < mrange->range_right) {
-								right = mrange->range_right - pos;
-								left = mrange->range_right - epos + 1;
-							} else {
-								right = mrange->range_right + pos;
-								left = mrange->range_right + epos - 1;
-							}
-							range = new AstNode(AST_MULTIRANGE, range, new AstNode(AST_RANGE, AstNode::mkconst_int(left, true), AstNode::mkconst_int(right, true)));
-						}
-						AstNode *target = new AstNode(AST_IDENTIFIER, range);
-						target->str = str;
-						target->id2ast = id2ast;
-						target->was_checked = true;
-						block->children.push_back(new AstNode(AST_ASSIGN_EQ, target, mkconst_bits(data.extract(i*wordsz + pos, clen).bits, false)));
-						pos = epos;
-					}
-				}
-			}
-		}
-
-		AstNode *newNode = new AstNode(AST_NONE);
-		newNode->cloneInto(this);
-		delete newNode;
-
-		did_something = true;
-	}
-
-	if (type == AST_ASSIGN && block == NULL && children[0]->mem2reg_check(mem2reg_set))
-	{
-		if (async_block == NULL) {
-			async_block = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
-			mod->children.push_back(async_block);
-		}
-
-		AstNode *newNode = clone();
-		newNode->type = AST_ASSIGN_EQ;
-		newNode->children[0]->was_checked = true;
-		async_block->children[0]->children.push_back(newNode);
-
-		newNode = new AstNode(AST_NONE);
-		newNode->cloneInto(this);
-		delete newNode;
-
-		did_something = true;
-	}
-
-	if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && children[0]->mem2reg_check(mem2reg_set) &&
-			children[0]->children[0]->children[0]->type != AST_CONSTANT)
-	{
-		std::stringstream sstr;
-		sstr << "$mem2reg_wr$" << children[0]->str << "$" << RTLIL::encode_filename(filename) << ":" << location.first_line << "$" << (autoidx++);
-		std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
-
-		int mem_width, mem_size, addr_bits;
-		bool mem_signed = children[0]->id2ast->is_signed;
-		children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
-
-		AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
-		wire_addr->str = id_addr;
-		wire_addr->is_reg = true;
-		wire_addr->was_checked = true;
-		wire_addr->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
-		mod->children.push_back(wire_addr);
-		while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
-
-		AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
-		wire_data->str = id_data;
-		wire_data->is_reg = true;
-		wire_data->was_checked = true;
-		wire_data->is_signed = mem_signed;
-		wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
-		mod->children.push_back(wire_data);
-		while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
-
-		log_assert(block != NULL);
-		size_t assign_idx = 0;
-		while (assign_idx < block->children.size() && block->children[assign_idx] != this)
-			assign_idx++;
-		log_assert(assign_idx < block->children.size());
-
-		AstNode *assign_addr = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());
-		assign_addr->children[0]->str = id_addr;
-		assign_addr->children[0]->was_checked = true;
-		block->children.insert(block->children.begin()+assign_idx+1, assign_addr);
-
-		AstNode *case_node = new AstNode(AST_CASE, new AstNode(AST_IDENTIFIER));
-		case_node->children[0]->str = id_addr;
-		for (int i = 0; i < mem_size; i++) {
-			if (children[0]->children[0]->children[0]->type == AST_CONSTANT && int(children[0]->children[0]->children[0]->integer) != i)
-				continue;
-			AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK));
-			AstNode *assign_reg = new AstNode(type, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER));
-			if (children[0]->children.size() == 2)
-				assign_reg->children[0]->children.push_back(children[0]->children[1]->clone());
-			assign_reg->children[0]->str = stringf("%s[%d]", children[0]->str.c_str(), i);
-			assign_reg->children[1]->str = id_data;
-			cond_node->children[1]->children.push_back(assign_reg);
-			case_node->children.push_back(cond_node);
-		}
-		block->children.insert(block->children.begin()+assign_idx+2, case_node);
-
-		children[0]->delete_children();
-		children[0]->range_valid = false;
-		children[0]->id2ast = NULL;
-		children[0]->str = id_data;
-		type = AST_ASSIGN_EQ;
-		children[0]->was_checked = true;
-
-		did_something = true;
-	}
-
-	if (mem2reg_check(mem2reg_set))
-	{
-		AstNode *bit_part_sel = NULL;
-		if (children.size() == 2)
-			bit_part_sel = children[1]->clone();
-
-		if (children[0]->children[0]->type == AST_CONSTANT)
-		{
-			int id = children[0]->children[0]->integer;
-			int left = id2ast->children[1]->children[0]->integer;
-			int right = id2ast->children[1]->children[1]->integer;
-			bool valid_const_access =
-				(left <= id && id <= right) ||
-				(right <= id && id <= left);
-			if (valid_const_access)
-			{
-				str = stringf("%s[%d]", str.c_str(), id);
-				delete_children();
-				range_valid = false;
-				id2ast = NULL;
-			}
-			else
-			{
-				int width;
-				if (bit_part_sel)
-				{
-					bit_part_sel->dumpAst(nullptr, "? ");
-					if (bit_part_sel->children.size() == 1)
-						width = 0;
-					else
-						width = bit_part_sel->children[0]->integer -
-							bit_part_sel->children[1]->integer;
-					delete bit_part_sel;
-					bit_part_sel = nullptr;
-				}
-				else
-				{
-					width = id2ast->children[0]->children[0]->integer -
-						id2ast->children[0]->children[1]->integer;
-				}
-				width = abs(width) + 1;
-
-				delete_children();
-
-				std::vector<RTLIL::State> x_bits;
-				for (int i = 0; i < width; i++)
-					x_bits.push_back(RTLIL::State::Sx);
-				AstNode *constant = AstNode::mkconst_bits(x_bits, false);
-				constant->cloneInto(this);
-				delete constant;
-			}
-		}
-		else
-		{
-			std::stringstream sstr;
-			sstr << "$mem2reg_rd$" << str << "$" << RTLIL::encode_filename(filename) << ":" << location.first_line << "$" << (autoidx++);
-			std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
-
-			int mem_width, mem_size, addr_bits;
-			bool mem_signed = id2ast->is_signed;
-			id2ast->meminfo(mem_width, mem_size, addr_bits);
-
-			AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
-			wire_addr->str = id_addr;
-			wire_addr->is_reg = true;
-			wire_addr->was_checked = true;
-			if (block)
-				wire_addr->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
-			mod->children.push_back(wire_addr);
-			while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
-
-			AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
-			wire_data->str = id_data;
-			wire_data->is_reg = true;
-			wire_data->was_checked = true;
-			wire_data->is_signed = mem_signed;
-			if (block)
-				wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
-			mod->children.push_back(wire_data);
-			while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
-
-			AstNode *assign_addr = new AstNode(block ? AST_ASSIGN_EQ : AST_ASSIGN, new AstNode(AST_IDENTIFIER), children[0]->children[0]->clone());
-			assign_addr->children[0]->str = id_addr;
-			assign_addr->children[0]->was_checked = true;
-
-			AstNode *case_node = new AstNode(AST_CASE, new AstNode(AST_IDENTIFIER));
-			case_node->children[0]->str = id_addr;
-
-			for (int i = 0; i < mem_size; i++) {
-				if (children[0]->children[0]->type == AST_CONSTANT && int(children[0]->children[0]->integer) != i)
-					continue;
-				AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK));
-				AstNode *assign_reg = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER));
-				assign_reg->children[0]->str = id_data;
-				assign_reg->children[0]->was_checked = true;
-				assign_reg->children[1]->str = stringf("%s[%d]", str.c_str(), i);
-				cond_node->children[1]->children.push_back(assign_reg);
-				case_node->children.push_back(cond_node);
-			}
-
-			std::vector<RTLIL::State> x_bits;
-			for (int i = 0; i < mem_width; i++)
-				x_bits.push_back(RTLIL::State::Sx);
-
-			AstNode *cond_node = new AstNode(AST_COND, new AstNode(AST_DEFAULT), new AstNode(AST_BLOCK));
-			AstNode *assign_reg = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), AstNode::mkconst_bits(x_bits, false));
-			assign_reg->children[0]->str = id_data;
-			assign_reg->children[0]->was_checked = true;
-			cond_node->children[1]->children.push_back(assign_reg);
-			case_node->children.push_back(cond_node);
-
-			if (block)
-			{
-				size_t assign_idx = 0;
-				while (assign_idx < block->children.size() && !block->children[assign_idx]->contains(this))
-					assign_idx++;
-				log_assert(assign_idx < block->children.size());
-				block->children.insert(block->children.begin()+assign_idx, case_node);
-				block->children.insert(block->children.begin()+assign_idx, assign_addr);
-			}
-			else
-			{
-				AstNode *proc = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
-				proc->children[0]->children.push_back(case_node);
-				mod->children.push_back(proc);
-				mod->children.push_back(assign_addr);
-			}
-
-			delete_children();
-			range_valid = false;
-			id2ast = NULL;
-			str = id_data;
-		}
-
-		if (bit_part_sel)
-			children.push_back(bit_part_sel);
-
-		did_something = true;
-	}
-
-	log_assert(id2ast == NULL || mem2reg_set.count(id2ast) == 0);
-
-	auto children_list = children;
-	for (size_t i = 0; i < children_list.size(); i++)
-		if (children_list[i]->mem2reg_as_needed_pass2(mem2reg_set, mod, block, async_block))
-			did_something = true;
-
-	return did_something;
-}
-
-// calculate memory dimensions
-void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits)
-{
-	log_assert(type == AST_MEMORY);
-
-	mem_width = children[0]->range_left - children[0]->range_right + 1;
-	mem_size = children[1]->range_left - children[1]->range_right;
-
-	if (mem_size < 0)
-		mem_size *= -1;
-	mem_size += min(children[1]->range_left, children[1]->range_right) + 1;
-
-	addr_bits = 1;
-	while ((1 << addr_bits) < mem_size)
-		addr_bits++;
-}
-
-bool AstNode::detect_latch(const std::string &var)
-{
-	switch (type)
-	{
-	case AST_ALWAYS:
-		for (auto &c : children)
-		{
-			switch (c->type)
-			{
-			case AST_POSEDGE:
-			case AST_NEGEDGE:
-				return false;
-			case AST_EDGE:
-				break;
-			case AST_BLOCK:
-				if (!c->detect_latch(var))
-					return false;
-				break;
-			default:
-				log_abort();
-			}
-		}
-		return true;
-	case AST_BLOCK:
-		for (auto &c : children)
-			if (!c->detect_latch(var))
-				return false;
-		return true;
-	case AST_CASE:
-		{
-			bool r = true;
-			for (auto &c : children) {
-				if (c->type == AST_COND) {
-					if (c->children.at(1)->detect_latch(var))
-						return true;
-					r = false;
-				}
-				if (c->type == AST_DEFAULT) {
-					if (c->children.at(0)->detect_latch(var))
-						return true;
-					r = false;
-				}
-			}
-			return r;
-		}
-	case AST_ASSIGN_EQ:
-	case AST_ASSIGN_LE:
-		if (children.at(0)->type == AST_IDENTIFIER &&
-				children.at(0)->children.empty() && children.at(0)->str == var)
-			return false;
-		return true;
-	default:
-		return true;
-	}
-}
-
-bool AstNode::has_const_only_constructs()
-{
-	if (type == AST_WHILE || type == AST_REPEAT)
-		return true;
-	for (auto child : children)
-		if (child->has_const_only_constructs())
-			return true;
-	return false;
-}
-
-bool AstNode::is_simple_const_expr()
-{
-	if (type == AST_IDENTIFIER)
-		return false;
-	for (auto child : children)
-		if (!child->is_simple_const_expr())
-			return false;
-	return true;
-}
-
-// helper function for AstNode::eval_const_function()
-bool AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &variables, AstNode *fcall, bool must_succeed)
-{
-	if (type == AST_IDENTIFIER && variables.count(str)) {
-		int offset = variables.at(str).offset, width = variables.at(str).val.bits.size();
-		if (!children.empty()) {
-			if (children.size() != 1 || children.at(0)->type != AST_RANGE) {
-				if (!must_succeed)
-					return false;
-				log_file_error(filename, location.first_line, "Memory access in constant function is not supported\n%s: ...called from here.\n",
-						fcall->loc_string().c_str());
-			}
-			if (!children.at(0)->replace_variables(variables, fcall, must_succeed))
-				return false;
-			while (simplify(true, false, false, 1, -1, false, true)) { }
-			if (!children.at(0)->range_valid) {
-				if (!must_succeed)
-					return false;
-				log_file_error(filename, location.first_line, "Non-constant range\n%s: ... called from here.\n",
-						fcall->loc_string().c_str());
-			}
-			offset = min(children.at(0)->range_left, children.at(0)->range_right);
-			width = min(std::abs(children.at(0)->range_left - children.at(0)->range_right) + 1, width);
-		}
-		offset -= variables.at(str).offset;
-		if (variables.at(str).range_swapped)
-			offset = -offset;
-		std::vector<RTLIL::State> &var_bits = variables.at(str).val.bits;
-		std::vector<RTLIL::State> new_bits(var_bits.begin() + offset, var_bits.begin() + offset + width);
-		AstNode *newNode = mkconst_bits(new_bits, variables.at(str).is_signed);
-		newNode->cloneInto(this);
-		delete newNode;
-		return true;
-	}
-
-	for (auto &child : children)
-		if (!child->replace_variables(variables, fcall, must_succeed))
-			return false;
-	return true;
-}
-
-// attempt to statically evaluate a functions with all-const arguments
-AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed)
-{
-	std::map<std::string, AstNode*> backup_scope = current_scope;
-	std::map<std::string, AstNode::varinfo_t> variables;
-	std::vector<AstNode*> to_delete;
-	AstNode *block = new AstNode(AST_BLOCK);
-	AstNode *result = nullptr;
-
-	size_t argidx = 0;
-	for (auto child : children)
-	{
-		block->children.push_back(child->clone());
-	}
-
-	while (!block->children.empty())
-	{
-		AstNode *stmt = block->children.front();
-
-#if 0
-		log("-----------------------------------\n");
-		for (auto &it : variables)
-			log("%20s %40s\n", it.first.c_str(), log_signal(it.second.val));
-		stmt->dumpAst(NULL, "stmt> ");
-#endif
-
-		if (stmt->type == AST_WIRE)
-		{
-			while (stmt->simplify(true, false, false, 1, -1, false, true)) { }
-			if (!stmt->range_valid) {
-				if (!must_succeed)
-					goto finished;
-				log_file_error(stmt->filename, stmt->location.first_line, "Can't determine size of variable %s\n%s: ... called from here.\n",
-						stmt->str.c_str(), fcall->loc_string().c_str());
-			}
-			AstNode::varinfo_t &variable = variables[stmt->str];
-			int width = abs(stmt->range_left - stmt->range_right) + 1;
-			// if this variable has already been declared as an input, check the
-			// sizes match if it already had an explicit size
-			if (variable.arg && variable.explicitly_sized && variable.val.size() != width) {
-				log_file_error(filename, location.first_line, "Incompatible re-declaration of constant function wire %s.\n", stmt->str.c_str());
-			}
-			variable.val = RTLIL::Const(RTLIL::State::Sx, width);
-			variable.offset = stmt->range_swapped ? stmt->range_left : stmt->range_right;
-			variable.range_swapped = stmt->range_swapped;
-			variable.is_signed = stmt->is_signed;
-			variable.explicitly_sized = stmt->children.size() &&
-				stmt->children.back()->type == AST_RANGE;
-			// identify the argument corresponding to this wire, if applicable
-			if (stmt->is_input && argidx < fcall->children.size()) {
-				variable.arg = fcall->children.at(argidx++);
-			}
-			// load the constant arg's value into this variable
-			if (variable.arg) {
-				if (variable.arg->type == AST_CONSTANT) {
-					variable.val = variable.arg->bitsAsConst(width);
-				} else {
-					log_assert(variable.arg->type == AST_REALVALUE);
-					variable.val = variable.arg->realAsConst(width);
-				}
-			}
-			current_scope[stmt->str] = stmt;
-
-			block->children.erase(block->children.begin());
-			to_delete.push_back(stmt);
-			continue;
-		}
-
-		log_assert(variables.count(str) != 0);
-
-		if (stmt->type == AST_LOCALPARAM)
-		{
-			while (stmt->simplify(true, false, false, 1, -1, false, true)) { }
-
-			current_scope[stmt->str] = stmt;
-
-			block->children.erase(block->children.begin());
-			to_delete.push_back(stmt);
-			continue;
-		}
-
-		if (stmt->type == AST_ASSIGN_EQ)
-		{
-			if (stmt->children.at(0)->type == AST_IDENTIFIER && stmt->children.at(0)->children.size() != 0 &&
-					stmt->children.at(0)->children.at(0)->type == AST_RANGE)
-				if (!stmt->children.at(0)->children.at(0)->replace_variables(variables, fcall, must_succeed))
-					goto finished;
-			if (!stmt->children.at(1)->replace_variables(variables, fcall, must_succeed))
-				goto finished;
-			while (stmt->simplify(true, false, false, 1, -1, false, true)) { }
-
-			if (stmt->type != AST_ASSIGN_EQ)
-				continue;
-
-			if (stmt->children.at(1)->type != AST_CONSTANT) {
-				if (!must_succeed)
-					goto finished;
-				log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here. X\n",
-						fcall->loc_string().c_str());
-			}
-
-			if (stmt->children.at(0)->type != AST_IDENTIFIER) {
-				if (!must_succeed)
-					goto finished;
-				log_file_error(stmt->filename, stmt->location.first_line, "Unsupported composite left hand side in constant function\n%s: ... called from here.\n",
-						fcall->loc_string().c_str());
-			}
-
-			if (!variables.count(stmt->children.at(0)->str)) {
-				if (!must_succeed)
-					goto finished;
-				log_file_error(stmt->filename, stmt->location.first_line, "Assignment to non-local variable in constant function\n%s: ... called from here.\n",
-						fcall->loc_string().c_str());
-			}
-
-			if (stmt->children.at(0)->children.empty()) {
-				variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size());
-			} else {
-				AstNode *range = stmt->children.at(0)->children.at(0);
-				if (!range->range_valid) {
-					if (!must_succeed)
-						goto finished;
-					log_file_error(range->filename, range->location.first_line, "Non-constant range\n%s: ... called from here.\n",
-							fcall->loc_string().c_str());
-				}
-				int offset = min(range->range_left, range->range_right);
-				int width = std::abs(range->range_left - range->range_right) + 1;
-				varinfo_t &v = variables[stmt->children.at(0)->str];
-				RTLIL::Const r = stmt->children.at(1)->bitsAsConst(v.val.bits.size());
-				for (int i = 0; i < width; i++) {
-					int index = i + offset - v.offset;
-					if (v.range_swapped)
-						index = -index;
-					v.val.bits.at(index) = r.bits.at(i);
-				}
-			}
-
-			delete block->children.front();
-			block->children.erase(block->children.begin());
-			continue;
-		}
-
-		if (stmt->type == AST_FOR)
-		{
-			block->children.insert(block->children.begin(), stmt->children.at(0));
-			stmt->children.at(3)->children.push_back(stmt->children.at(2));
-			stmt->children.erase(stmt->children.begin() + 2);
-			stmt->children.erase(stmt->children.begin());
-			stmt->type = AST_WHILE;
-			continue;
-		}
-
-		if (stmt->type == AST_WHILE)
-		{
-			AstNode *cond = stmt->children.at(0)->clone();
-			if (!cond->replace_variables(variables, fcall, must_succeed))
-				goto finished;
-			while (cond->simplify(true, false, false, 1, -1, false, true)) { }
-
-			if (cond->type != AST_CONSTANT) {
-				if (!must_succeed)
-					goto finished;
-				log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n",
-						fcall->loc_string().c_str());
-			}
-
-			if (cond->asBool()) {
-				block->children.insert(block->children.begin(), stmt->children.at(1)->clone());
-			} else {
-				delete block->children.front();
-				block->children.erase(block->children.begin());
-			}
-
-			delete cond;
-			continue;
-		}
-
-		if (stmt->type == AST_REPEAT)
-		{
-			AstNode *num = stmt->children.at(0)->clone();
-			if (!num->replace_variables(variables, fcall, must_succeed))
-				goto finished;
-			while (num->simplify(true, false, false, 1, -1, false, true)) { }
-
-			if (num->type != AST_CONSTANT) {
-				if (!must_succeed)
-					goto finished;
-				log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n",
-						fcall->loc_string().c_str());
-			}
-
-			block->children.erase(block->children.begin());
-			for (int i = 0; i < num->bitsAsConst().as_int(); i++)
-				block->children.insert(block->children.begin(), stmt->children.at(1)->clone());
-
-			delete stmt;
-			delete num;
-			continue;
-		}
-
-		if (stmt->type == AST_CASE)
-		{
-			AstNode *expr = stmt->children.at(0)->clone();
-			if (!expr->replace_variables(variables, fcall, must_succeed))
-				goto finished;
-			while (expr->simplify(true, false, false, 1, -1, false, true)) { }
-
-			AstNode *sel_case = NULL;
-			for (size_t i = 1; i < stmt->children.size(); i++)
-			{
-				bool found_match = false;
-				log_assert(stmt->children.at(i)->type == AST_COND || stmt->children.at(i)->type == AST_CONDX || stmt->children.at(i)->type == AST_CONDZ);
-
-				if (stmt->children.at(i)->children.front()->type == AST_DEFAULT) {
-					sel_case = stmt->children.at(i)->children.back();
-					continue;
-				}
-
-				for (size_t j = 0; j+1 < stmt->children.at(i)->children.size() && !found_match; j++)
-				{
-					AstNode *cond = stmt->children.at(i)->children.at(j)->clone();
-					if (!cond->replace_variables(variables, fcall, must_succeed))
-						goto finished;
-
-					cond = new AstNode(AST_EQ, expr->clone(), cond);
-					while (cond->simplify(true, false, false, 1, -1, false, true)) { }
-
-					if (cond->type != AST_CONSTANT) {
-						if (!must_succeed)
-							goto finished;
-						log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n",
-								fcall->loc_string().c_str());
-					}
-
-					found_match = cond->asBool();
-					delete cond;
-				}
-
-				if (found_match) {
-					sel_case = stmt->children.at(i)->children.back();
-					break;
-				}
-			}
-
-			block->children.erase(block->children.begin());
-			if (sel_case)
-				block->children.insert(block->children.begin(), sel_case->clone());
-			delete stmt;
-			delete expr;
-			continue;
-		}
-
-		if (stmt->type == AST_BLOCK)
-		{
-			if (!stmt->str.empty())
-				stmt->expand_genblock(stmt->str + ".");
-
-			block->children.erase(block->children.begin());
-			block->children.insert(block->children.begin(), stmt->children.begin(), stmt->children.end());
-			stmt->children.clear();
-			delete stmt;
-			continue;
-		}
-
-		if (!must_succeed)
-			goto finished;
-		log_file_error(stmt->filename, stmt->location.first_line, "Unsupported language construct in constant function\n%s: ... called from here.\n",
-				fcall->loc_string().c_str());
-		log_abort();
-	}
-
-	result = AstNode::mkconst_bits(variables.at(str).val.bits, variables.at(str).is_signed);
-
-finished:
-	delete block;
-	current_scope = backup_scope;
-
-	for (auto it : to_delete) {
-		delete it;
-	}
-	to_delete.clear();
-
-	return result;
-}
-
-void AstNode::allocateDefaultEnumValues()
-{
-	log_assert(type==AST_ENUM);
-	log_assert(children.size() > 0);
-	if (children.front()->attributes.count(ID::enum_base_type))
-		return; // already elaborated
-	int last_enum_int = -1;
-	for (auto node : children) {
-		log_assert(node->type==AST_ENUM_ITEM);
-		node->attributes[ID::enum_base_type] = mkconst_str(str);
-		for (size_t i = 0; i < node->children.size(); i++) {
-			switch (node->children[i]->type) {
-			case AST_NONE:
-				// replace with auto-incremented constant
-				delete node->children[i];
-				node->children[i] = AstNode::mkconst_int(++last_enum_int, true);
-				break;
-			case AST_CONSTANT:
-				// explicit constant (or folded expression)
-				// TODO: can't extend 'x or 'z item
-				last_enum_int = node->children[i]->integer;
-				break;
-			default:
-				// ignore ranges
-				break;
-			}
-			// TODO: range check
-		}
-	}
-}
-
-bool AstNode::is_recursive_function() const
-{
-	std::set<const AstNode *> visited;
-	std::function<bool(const AstNode *node)> visit = [&](const AstNode *node) {
-		if (visited.count(node))
-			return node == this;
-		visited.insert(node);
-		if (node->type == AST_FCALL) {
-			auto it = current_scope.find(node->str);
-			if (it != current_scope.end() && visit(it->second))
-				return true;
-		}
-		for (const AstNode *child : node->children) {
-			if (visit(child))
-				return true;
-		}
-		return false;
-	};
-
-	log_assert(type == AST_FUNCTION);
-	return visit(this);
-}
-
-std::pair<AstNode*, AstNode*> AstNode::get_tern_choice()
-{
-	if (!children[0]->isConst())
-		return {};
-
-	bool found_sure_true = false;
-	bool found_maybe_true = false;
-
-	if (children[0]->type == AST_CONSTANT)
-		for (auto &bit : children[0]->bits) {
-			if (bit == RTLIL::State::S1)
-				found_sure_true = true;
-			if (bit > RTLIL::State::S1)
-				found_maybe_true = true;
-		}
-	else
-		found_sure_true = children[0]->asReal(true) != 0;
-
-	AstNode *choice = nullptr, *not_choice = nullptr;
-	if (found_sure_true)
-		choice = children[1], not_choice = children[2];
-	else if (!found_maybe_true)
-		choice = children[2], not_choice = children[1];
-
-	return {choice, not_choice};
-}
-
-std::string AstNode::try_pop_module_prefix() const
-{
-	AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod;
-	size_t pos = str.find('.', 1);
-	if (str[0] == '\\' && pos != std::string::npos) {
-		std::string new_str = "\\" + str.substr(pos + 1);
-		if (current_scope.count(new_str)) {
-			std::string prefix = str.substr(0, pos);
-			auto it = current_scope_ast->attributes.find(ID::hdlname);
-			if ((it != current_scope_ast->attributes.end() && it->second->str == prefix)
-					|| prefix == current_scope_ast->str)
-				return new_str;
-		}
-	}
-	return str;
-}
-
-YOSYS_NAMESPACE_END
+} // namespace systemverilog_plugin
