Merge pull request #819 from CAS-Atlantic/move_resolve_node

ODIN II: initial AST elaboration refactoring
diff --git a/ODIN_II/SRC/ast_elaborate.cpp b/ODIN_II/SRC/ast_elaborate.cpp
index b43f900..67afba5 100644
--- a/ODIN_II/SRC/ast_elaborate.cpp
+++ b/ODIN_II/SRC/ast_elaborate.cpp
@@ -128,18 +128,430 @@
 	}
 }
 
-int simplify_ast_module(ast_node_t **ast_module)
+int simplify_ast_module(ast_node_t **ast_module, STRING_CACHE_LIST *local_string_cache_list)
 {
-	/* for loop support */
-	unroll_loops(ast_module);
-	/* remove unused node preventing module instantiation */
+	/* resolve constant expressions */
+	*ast_module = reduce_expressions(*ast_module, local_string_cache_list, NULL, 0);
+	unroll_loops(ast_module, local_string_cache_list);
 	remove_generate(*ast_module);
-	/* simplify assignment expressions */
-	//reduce_assignment_expression(*ast_module);
 
 	return 1;
 }
 
+// this should replace ^^
+ast_node_t *reduce_expressions(ast_node_t *node, STRING_CACHE_LIST *local_string_cache_list, long *max_size, long assignment_size)
+{
+	if (node)
+	{
+		STRING_CACHE *local_param_table_sc = local_string_cache_list->local_param_table_sc;
+		STRING_CACHE *local_symbol_table_sc = local_string_cache_list->local_symbol_table_sc;
+
+		switch (node->type)
+		{
+			case MODULE:
+			{
+				// skip identifier
+				node->children[1] = reduce_expressions(node->children[1], local_string_cache_list, NULL, 0);
+				node->children[2] = reduce_expressions(node->children[2], local_string_cache_list, NULL, 0);
+				return node;
+			}
+			case FUNCTION:
+			{
+				return node;
+			}
+			case VAR_DECLARE:
+			{
+				if (node->types.variable.is_parameter || node->types.variable.is_localparam)
+				{
+					bool is_stored = false;
+					long sc_spot = sc_lookup_string(local_param_table_sc, node->children[0]->types.identifier);
+					if (sc_spot != -1 && ((ast_node_t*)local_param_table_sc->data[sc_spot]) == node->children[5])
+					{
+						is_stored = true;
+					}
+
+					/* resolve right-hand side */
+					node->children[5] = reduce_expressions(node->children[5], local_string_cache_list, NULL, 0);
+					oassert(node->children[5]->type == NUMBERS);
+
+					/* this forces parameter values as unsigned, since we don't currently support signed keyword...
+						must be changed once support is added */
+					VNumber *temp = node->children[5]->types.vnumber;
+					VNumber *to_unsigned = new VNumber(V_UNSIGNED(*temp));
+					node->children[5]->types.vnumber = to_unsigned;
+					delete temp;
+
+					if (is_stored)
+					{
+						local_param_table_sc->data[sc_spot] = (void *) node->children[5];
+					}
+
+					return node;
+				}
+				break;
+			}
+			case IDENTIFIERS:
+			{
+				if (local_param_table_sc != NULL && node->types.identifier)
+				{
+					long sc_spot = sc_lookup_string(local_param_table_sc, node->types.identifier);
+					if (sc_spot != -1)
+					{
+						ast_node_t *newNode = ast_node_deep_copy((ast_node_t *)local_param_table_sc->data[sc_spot]);
+
+						if (newNode->type != NUMBERS)
+						{
+							newNode = reduce_expressions(newNode, local_string_cache_list, NULL, assignment_size);
+							oassert(newNode->type == NUMBERS);
+
+							/* this forces parameter values as unsigned, since we don't currently support signed keyword...
+							must be changed once support is added */
+							VNumber *temp = newNode->types.vnumber;
+							VNumber *to_unsigned = new VNumber(V_UNSIGNED(*temp));
+							newNode->types.vnumber = to_unsigned;
+							delete temp;
+							
+							if (newNode->type != NUMBERS)
+							{
+								error_message(NETLIST_ERROR, node->line_number, node->file_number, "Parameter %s is not a constant expression\n", node->types.identifier);
+							}
+						}
+
+						node = free_whole_tree(node);
+						node = newNode;
+					}
+					else
+					{
+						break;
+					}
+				}
+			}
+			case FOR:
+				// look ahead for parameters
+				break;
+			case WHILE:
+				// look ahead for parameters
+				break;
+			case GENERATE:
+				break;
+			case BLOCKING_STATEMENT:
+			case NON_BLOCKING_STATEMENT:
+			{
+				/* try to resolve */
+				if (node->children[1]->type != FUNCTION_INSTANCE)
+				{
+					node->children[0] = reduce_expressions(node->children[0], local_string_cache_list, NULL, 0);
+
+					assignment_size = get_size_of_variable(node->children[0], local_string_cache_list);
+					max_size = (long*)calloc(1, sizeof(long));
+					
+					if (node->children[1]->type != NUMBERS)
+					{
+						node->children[1] = reduce_expressions(node->children[1], local_string_cache_list, max_size, assignment_size);
+					}
+					else
+					{
+						VNumber *temp = node->children[1]->types.vnumber;
+						node->children[1]->types.vnumber = new VNumber(*temp, assignment_size);
+						delete temp;
+					}
+
+					vtr::free(max_size);
+
+					/* cast to unsigned if necessary */
+					if (node_is_constant(node->children[1]))
+					{
+						char *id = NULL;
+						if (node->children[0]->type == IDENTIFIERS)
+						{
+							id = node->children[0]->types.identifier;
+						}
+						else
+						{
+							id = node->children[0]->children[0]->types.identifier;
+						}
+
+						long sc_spot = sc_lookup_string(local_symbol_table_sc, id);
+						if (sc_spot > -1)
+						{
+							bool is_signed = ((ast_node_t *)local_symbol_table_sc->data[sc_spot])->types.variable.is_signed;
+							if (!is_signed)
+							{
+								VNumber *temp = node->children[1]->types.vnumber;
+								VNumber *to_unsigned = new VNumber(V_UNSIGNED(*temp));
+								node->children[1]->types.vnumber = to_unsigned;
+								delete temp;
+							}
+							else
+							{
+								/* leave as is */
+							}
+						}
+					}
+					else
+					{
+						/* signed keyword is not supported, meaning unresolved values will already be handled as
+							unsigned at the netlist level... must update once signed support is added */
+					}
+					
+					assignment_size = 0;
+				}
+
+				return node;
+			}
+			case BINARY_OPERATION:
+			case UNARY_OPERATION:
+				break;
+			case CONCATENATE:
+				break;
+			case REPLICATE:
+				break;
+			case NUMBERS:
+				break;
+			case IF_Q:
+				break;
+			case IF:
+				break;
+			case CASE:
+				break;
+			case RANGE_REF:
+			case ARRAY_REF:
+				break;
+			case MODULE_INSTANCE:
+				// flip hard blocks
+				break;
+			default:
+				break;
+		}
+
+		/* recurse */
+		for (int i = 0; i < node->num_children; i++)
+		{
+			node->children[i] = reduce_expressions(node->children[i], local_string_cache_list, max_size, assignment_size);
+		}
+
+		/* post-amble */
+		switch (node->type)
+		{
+			case FOR:
+				// unroll
+				//unroll_loops(node->children[i]); // change this function (dont have to go through whole tree)
+				// recurse for operation resolution
+				break;
+			case WHILE:
+				// unroll
+				// recurse (simplify_ast?)
+			case GENERATE:
+				/* remove unused node preventing module instantiation */
+				//remove_generate(node->children[i]); // change this function (dont have to go through whole tree)
+				break;
+			case BINARY_OPERATION:
+			{
+				ast_node_t *new_node = fold_binary(&node);
+				if (node_is_constant(new_node))
+				{
+					/* resize as needed */
+					long new_size;
+					long this_size = new_node->types.vnumber->size();
+
+					if (assignment_size > 0)
+					{
+						new_size = assignment_size;
+					}
+					else if (max_size)
+					{
+						new_size = *max_size;
+					}
+					else
+					{
+						new_size = this_size;
+					}
+
+					/* clean up */
+					free_resolved_children(node);
+												
+					change_to_number_node(node, VNumber(*(new_node->types.vnumber), new_size));
+					new_node = free_whole_tree(new_node);
+				}
+				break;
+			}
+			case UNARY_OPERATION:
+			{
+				ast_node_t *new_node = fold_unary(&node);
+				if (node_is_constant(new_node))
+				{
+					/* resize as needed */
+					long new_size;
+					long this_size = new_node->types.vnumber->size();
+
+					if (assignment_size > 0)
+					{
+						new_size = assignment_size;
+					}
+					else if (max_size)
+					{
+						new_size = *max_size;
+					}
+					else
+					{
+						new_size = this_size;
+					}
+
+					/* clean up */
+					free_resolved_children(node);
+					
+					change_to_number_node(node, VNumber(*(new_node->types.vnumber), new_size));
+					new_node = free_whole_tree(new_node);
+				}
+				break;
+			}
+			case REPLICATE:
+			{
+				oassert(node_is_constant(node->children[0])); // should be taken care of in parse
+				if( node->children[0]->types.vnumber->is_dont_care_string() )
+				{
+					error_message(NETLIST_ERROR, node->line_number, node->file_number, 
+						"%s","Passing a non constant value to replication command, i.e. 2'bx1{...}");
+				}
+
+				int64_t value = node->children[0]->types.vnumber->get_value();
+				if(value <= 0)
+				{
+					// todo, if this is part of a concat, it is valid
+					error_message(NETLIST_ERROR, node->line_number, node->file_number, 
+						"%s","Passing a number less than or equal to 0 for replication");
+				}
+
+				ast_node_t *new_node = create_node_w_type(CONCATENATE, node->line_number, node->file_number);
+				for (size_t i = 0; i < value; i++)
+				{
+					add_child_to_node(new_node, ast_node_deep_copy(node->children[1]));
+				}
+				node = free_whole_tree(node);
+				node = new_node;
+			} 
+			//fallthrough to resolve concatenation
+			case CONCATENATE:
+			{
+				resolve_concat_sizes(node, local_string_cache_list);
+
+				// for params only
+				// TODO: this is a hack, concats cannot be folded in place as it breaks netlist expand from ast,
+				// to fix we need to move the node resolution before netlist create from ast.
+				if(node->num_children > 0)
+				{
+					size_t index = 1;
+					size_t last_index = 0;
+					
+					while(index < node->num_children)
+					{
+						bool previous_is_constant = node_is_constant(node->children[last_index]);
+						bool current_is_constant = node_is_constant(node->children[index]);
+
+						if(previous_is_constant && current_is_constant)
+						{
+							VNumber new_value = V_CONCAT({*(node->children[last_index]->types.vnumber), *(node->children[index]->types.vnumber)});
+
+							node->children[index] = free_whole_tree(node->children[index]);
+
+							delete node->children[last_index]->types.vnumber;
+							node->children[last_index]->types.vnumber = new VNumber(new_value);
+						}
+						else
+						{
+							last_index += 1;
+							previous_is_constant = current_is_constant;
+							node->children[last_index] = node->children[index];
+						}
+						index += 1;
+					}
+
+					node->num_children = last_index+1;
+
+					if(node->num_children == 1)
+					{
+						ast_node_t *tmp = node->children[0];
+						node->children[0] = NULL;
+						free_whole_tree(node);
+						node = tmp;
+					}
+				}
+
+				break;
+			}
+			case IDENTIFIERS:
+			{
+				// look up to resolve unresolved range refs
+				ast_node_t *var_node = NULL;
+
+				oassert(node->types.identifier);
+				long sc_spot = sc_lookup_string(local_symbol_table_sc, node->types.identifier);
+				if (sc_spot > -1)
+				{
+					var_node = (ast_node_t *)local_symbol_table_sc->data[sc_spot];
+
+					if (var_node->children[1] != NULL)
+					{
+						var_node->children[1] = reduce_expressions(var_node->children[1], local_string_cache_list, NULL, 0);
+						var_node->children[2] = reduce_expressions(var_node->children[2], local_string_cache_list, NULL, 0);
+					}
+					if (var_node->children[3] != NULL)
+					{
+						var_node->children[3] = reduce_expressions(var_node->children[3], local_string_cache_list, NULL, 0);
+						var_node->children[4] = reduce_expressions(var_node->children[4], local_string_cache_list, NULL, 0);
+					}
+					if (var_node->num_children == 8 && var_node->children[5])
+					{
+						var_node->children[5] = reduce_expressions(var_node->children[5], local_string_cache_list, NULL, 0);
+						var_node->children[6] = reduce_expressions(var_node->children[6], local_string_cache_list, NULL, 0);
+					}
+
+					local_symbol_table_sc->data[sc_spot] = (void *)var_node;
+				}
+
+				if (max_size)
+				{
+					long var_size = get_size_of_variable(node, local_string_cache_list);
+					if (var_size > *max_size)
+					{
+						*max_size = var_size;
+					}
+				}
+
+				break;
+			}
+			case NUMBERS:
+			{
+				if (max_size)
+				{
+					if (node->types.vnumber->size() > (*max_size))
+					{
+						*max_size = node->types.vnumber->size();
+					}
+				}
+
+				break;
+			}
+			case IF_Q:
+				break;
+			case IF:
+				break;
+			case CASE:
+				break;
+			case RANGE_REF:
+			case ARRAY_REF:
+				break;
+			case MODULE_INSTANCE:
+				// flip hard blocks
+				break;
+			default:
+				break;
+		}
+	}
+
+	return node;
+}
+
 // /*---------------------------------------------------------------------------
 //  * (function: reduce_assignment_expression)
 //  * reduce the number nodes which can be calculated to optimize the AST
diff --git a/ODIN_II/SRC/ast_loop_unroll.cpp b/ODIN_II/SRC/ast_loop_unroll.cpp
index 77d09ef..314b22e 100644
--- a/ODIN_II/SRC/ast_loop_unroll.cpp
+++ b/ODIN_II/SRC/ast_loop_unroll.cpp
@@ -6,6 +6,7 @@
 #include "odin_globals.h"
 #include "odin_types.h"
 #include "ast_util.h"
+#include "ast_elaborate.h"
 #include "parse_making_ast.h"
 #include "odin_util.h"
 #include "vtr_memory.h"
@@ -20,12 +21,12 @@
 /*
  *  (function: unroll_loops)
  */
-void unroll_loops(ast_node_t **ast_module)
+void unroll_loops(ast_node_t **ast_module, STRING_CACHE_LIST *local_string_cache_list)
 {
 	ast_node_t **removed_instances = NULL;
 	int num_removed = 0;
 
-	ast_node_t* module = for_preprocessor((*ast_module), (*ast_module), &removed_instances, &num_removed);
+	ast_node_t* module = for_preprocessor((*ast_module), (*ast_module), local_string_cache_list, &removed_instances, &num_removed);
 	
 	for (int i = 0; i < num_removed; i++)
 	{
@@ -52,7 +53,7 @@
 		if ((idx = find_module_instance(ast_module, instance_name, module_instantiations, module_instantiations_size)) != -1)
 		{
 			(*removed_instances) = (ast_node_t **)vtr::realloc((*removed_instances), sizeof(ast_node_t*)*((*num_removed)+1));
-			(*removed_instances)[*num_removed] = (*module_instantiations)[idx];
+			(*removed_instances)[*num_removed] = ast_node_deep_copy((*module_instantiations)[idx]);
 			(*num_removed)++;
 
 			(*module_instantiations) = expand_node_list_at(*module_instantiations, *module_instantiations_size, (*num_unrolled) - 1, idx + 1);
@@ -142,7 +143,7 @@
 /*
  *  (function: for_preprocessor)
  */
-ast_node_t* for_preprocessor(ast_node_t *ast_module, ast_node_t* node, ast_node_t ***removed_instances, int *num_removed)
+ast_node_t* for_preprocessor(ast_node_t *ast_module, ast_node_t* node, STRING_CACHE_LIST *local_string_cache_list, ast_node_t ***removed_instances, int *num_removed)
 {
 	if(!node)
 		return nullptr;
@@ -158,7 +159,7 @@
 	ast_node_t* new_node = NULL;
 	if(for_loops)
 	{
-		new_node = replace_fors(ast_module, node, removed_instances, num_removed);
+		new_node = replace_fors(ast_module, node, local_string_cache_list, removed_instances, num_removed);
 	}
 	else
 	{
@@ -169,7 +170,7 @@
 	{
 		/* Run this function recursively on the children */
 		for(int i=0; i<new_node->num_children; i++){
-			ast_node_t* new_child = for_preprocessor(ast_module, new_node->children[i], removed_instances, num_removed);
+			ast_node_t* new_child = for_preprocessor(ast_module, new_node->children[i], local_string_cache_list, removed_instances, num_removed);
 
 			/* Cleanup replaced child */
 			if(new_node->children[i] != new_child){
@@ -185,7 +186,7 @@
 /*
  *  (function: replace_fors)
  */
-ast_node_t* replace_fors(ast_node_t *ast_module, ast_node_t* node, ast_node_t ***removed_instances, int *num_removed)
+ast_node_t* replace_fors(ast_node_t *ast_module, ast_node_t* node, STRING_CACHE_LIST *local_string_cache_list, ast_node_t ***removed_instances, int *num_removed)
 {
 	oassert(!is_for_node(node));
 	oassert(node != nullptr);
@@ -204,7 +205,7 @@
 			int num_unrolled_module_instances = 0;
 			int num_original_module_instances = 0;
 
-			ast_node_t* unrolled_for = resolve_for(ast_module, new_node->children[i], &unrolled_module_instances, &num_unrolled_module_instances, &num_original_module_instances);
+			ast_node_t* unrolled_for = resolve_for(ast_module, new_node->children[i], local_string_cache_list, &unrolled_module_instances, &num_unrolled_module_instances, &num_original_module_instances);
 			oassert(unrolled_for != nullptr);
 			free_whole_tree(new_node->children[i]);
 			new_node->children[i] = unrolled_for;
@@ -231,7 +232,7 @@
 /*
  *  (function: resolve_for)
  */
-ast_node_t* resolve_for(ast_node_t *ast_module, ast_node_t* node, ast_node_t ****instances, int *num_unrolled, int *num_original)
+ast_node_t* resolve_for(ast_node_t *ast_module, ast_node_t* node, STRING_CACHE_LIST *local_string_cache_list, ast_node_t ****instances, int *num_unrolled, int *num_original)
 {
 	oassert(is_for_node(node));
 	oassert(node != nullptr);
@@ -285,6 +286,8 @@
 	}
 
 	free_whole_tree(value);
+
+	body_parent = reduce_expressions(body_parent, local_string_cache_list, NULL, 0);
 	return body_parent;
 }
 
diff --git a/ODIN_II/SRC/ast_util.cpp b/ODIN_II/SRC/ast_util.cpp
index c05d002..d06b536 100644
--- a/ODIN_II/SRC/ast_util.cpp
+++ b/ODIN_II/SRC/ast_util.cpp
@@ -409,9 +409,6 @@
 				else if (var_declare->children[3] == NULL)
 				{
 					/* reverse thorugh the range since highest bit in index will be lower in the string indx */
-					var_declare->children[1] = resolve_node(local_string_cache_list, var_declare->children[1], NULL, 0);
-					var_declare->children[2] = resolve_node(local_string_cache_list, var_declare->children[2], NULL, 0);
-					
 					rnode[1] = var_declare->children[1];
 					rnode[2] = var_declare->children[2];
 					oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS);
@@ -438,9 +435,6 @@
 		}
 		else if (concat_top->children[i]->type == RANGE_REF)
 		{
-			concat_top->children[i]->children[1] = resolve_node(local_string_cache_list, concat_top->children[i]->children[1], NULL, 0);
-			concat_top->children[i]->children[2] = resolve_node(local_string_cache_list, concat_top->children[i]->children[2], NULL, 0);
-
 			rnode[1] = concat_top->children[i]->children[1];
 			rnode[2] = concat_top->children[i]->children[2];
 			oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS);
@@ -563,7 +557,6 @@
 
 	if (var_node->type == ARRAY_REF)
 	{
-		var_node->children[1] = resolve_node(local_string_cache_list, var_node->children[1], NULL, 0);
 		oassert(var_node->children[0]->type == IDENTIFIERS);
 		oassert(var_node->children[1]->type == NUMBERS);
 		return_string = make_full_ref_name(NULL, NULL, NULL, var_node->children[0]->types.identifier, (int)var_node->children[1]->types.vnumber->get_value());
@@ -572,9 +565,6 @@
 	{		
 		oassert(bit >= 0);
 
-		var_node->children[1] = resolve_node(local_string_cache_list, var_node->children[1], NULL, 0);
-		var_node->children[2] = resolve_node(local_string_cache_list, var_node->children[2], NULL, 0);
-
 		rnode[1] = var_node->children[1];
 		rnode[2] = var_node->children[2];
 
@@ -630,7 +620,6 @@
 			if (var_node->types.concat.num_bit_strings == -1)
 			{
 				/* If this hasn't been made into a string list then do it */
-				var_node = resolve_node(local_string_cache_list, var_node, NULL, 0);
 				make_concat_into_list_of_strings(var_node, instance_name_prefix, local_string_cache_list);
 			}
 
@@ -709,18 +698,15 @@
 	{
 		width = 1;
 		return_string = (char**)vtr::malloc(sizeof(char*));
-		var_node->children[1] = resolve_node(local_string_cache_list, var_node->children[1], NULL, 0);
+
 		rnode[1] = var_node->children[1];
 		oassert(rnode[1] && rnode[1]->type == NUMBERS);
 		oassert(var_node->children[0]->type == IDENTIFIERS);
+
 		return_string[0] = make_full_ref_name(NULL, NULL, NULL, var_node->children[0]->types.identifier, rnode[1]->types.vnumber->get_value());	
 	}
 	else if (var_node->type == RANGE_REF)
 	{
-		var_node->children[0] = resolve_node(local_string_cache_list, var_node->children[0], NULL, 0);
-		var_node->children[1] = resolve_node(local_string_cache_list, var_node->children[1], NULL, 0);
-		var_node->children[2] = resolve_node(local_string_cache_list, var_node->children[2], NULL, 0);
-
 		rnode[0] = var_node->children[0];
 		rnode[1] = var_node->children[1];
 		rnode[2] = var_node->children[2];
@@ -744,66 +730,55 @@
 		/* need to look in the symbol table for details about this identifier (i.e. is it a port) */
 		long sc_spot;
 
-		// try and resolve var_node
-		var_node = resolve_node(local_string_cache_list, var_node, NULL, 0);
+		ast_node_t *sym_node = NULL;
+		char *temp_string = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, -1);
 
-		if (var_node->type != NUMBERS)
+		if ((sc_spot = sc_lookup_string(function_local_symbol_table_sc, temp_string)) > -1)
 		{
-			ast_node_t *sym_node = NULL;
-			char *temp_string = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, -1);
-
-            if ((sc_spot = sc_lookup_string(function_local_symbol_table_sc, temp_string)) > -1)
-			{
-                sym_node = (ast_node_t*)function_local_symbol_table_sc->data[sc_spot];
-			}
-		    else if ((sc_spot = sc_lookup_string(local_symbol_table_sc, temp_string)) > -1)
-			{
-                sym_node = (ast_node_t*)local_symbol_table_sc->data[sc_spot];
-			}
-            else 
-			{
-                error_message(NETLIST_ERROR, var_node->line_number, var_node->file_number, "Missing declaration of this symbol %s\n", temp_string);
-            }
-			
-			vtr::free(temp_string);
-
-			if (sym_node && sym_node->children && sym_node->type)
-			{
-				if (sym_node->children[1] == NULL || sym_node->type == BLOCKING_STATEMENT)
-				{
-					width = 1;
-					return_string = (char**)vtr::malloc(sizeof(char*)*width);
-					return_string[0] = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, -1);
-				}
-				else if (sym_node->children[2] != NULL && sym_node->children[3] == NULL)
-				{
-					int index = 0;
-					sym_node->children[1] = resolve_node(local_string_cache_list, sym_node->children[1], NULL, 0);
-					sym_node->children[2] = resolve_node(local_string_cache_list, sym_node->children[2], NULL, 0);
-
-					rnode[1] = sym_node->children[1];
-					rnode[2] = sym_node->children[2];
-					oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS);
-					width = (rnode[1]->types.vnumber->get_value() - rnode[2]->types.vnumber->get_value() + 1);
-					return_string = (char**)vtr::malloc(sizeof(char*)*width);
-					for (i = 0; i < width; i++)
-					{
-						return_string[index] = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier,
-							i+rnode[2]->types.vnumber->get_value());
-						index++;
-					}
-				}
-
-				else if (sym_node->children[3] != NULL)
-				{
-					oassert(false);
-				}
-			}
+			sym_node = (ast_node_t*)function_local_symbol_table_sc->data[sc_spot];
 		}
-		else
+		else if ((sc_spot = sc_lookup_string(local_symbol_table_sc, temp_string)) > -1)
 		{
-			width = var_node->types.vnumber->size();
-			return_string = get_name_of_pins_number(var_node, 0, width);
+			sym_node = (ast_node_t*)local_symbol_table_sc->data[sc_spot];
+		}
+		else 
+		{
+			error_message(NETLIST_ERROR, var_node->line_number, var_node->file_number, "Missing declaration of this symbol %s\n", temp_string);
+		}
+		
+		vtr::free(temp_string);
+
+		if (sym_node && sym_node->children && sym_node->type)
+		{
+			if (sym_node->children[1] == NULL || sym_node->type == BLOCKING_STATEMENT)
+			{
+				width = 1;
+				return_string = (char**)vtr::malloc(sizeof(char*)*width);
+				return_string[0] = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, -1);
+			}
+			else if (sym_node->children[2] != NULL && sym_node->children[3] == NULL)
+			{
+				int index = 0;
+
+				rnode[1] = sym_node->children[1];
+				rnode[2] = sym_node->children[2];
+				oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS);
+
+				width = (rnode[1]->types.vnumber->get_value() - rnode[2]->types.vnumber->get_value() + 1);
+				return_string = (char**)vtr::malloc(sizeof(char*)*width);
+
+				for (i = 0; i < width; i++)
+				{
+					return_string[index] = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier,
+						i+rnode[2]->types.vnumber->get_value());
+					index++;
+				}
+			}
+
+			else if (sym_node->children[3] != NULL)
+			{
+				oassert(false);
+			}
 		}
 	}
 	else if (var_node->type == NUMBERS)
@@ -821,8 +796,6 @@
 		{
 			if (var_node->types.concat.num_bit_strings == -1)
 			{
-				/* If this hasn't been made into a string list then do it */
-				var_node = resolve_node(local_string_cache_list, var_node, NULL, 0);
 				make_concat_into_list_of_strings(var_node, instance_name_prefix, local_string_cache_list);
 			}
 
@@ -959,9 +932,6 @@
 	}
 	else if (var_declare && var_declare->children[1] && var_declare->children[2])
 	{
-		var_declare->children[1] = resolve_node(local_string_cache_list, var_declare->children[1], NULL, 0);
-		var_declare->children[2] = resolve_node(local_string_cache_list, var_declare->children[2], NULL, 0);
-		
 		ast_node_t *node_max = var_declare->children[1];
 		ast_node_t *node_min = var_declare->children[2];
 
@@ -977,201 +947,6 @@
 }
 
 /*----------------------------------------------------------------------------
- * (function: resolve_node)
- *--------------------------------------------------------------------------*/
-/**
- * Recursively resolves an IDENTIFIER to a parameter into its actual value,
- * by looking it up in the local_param_table_sc
- * Also try and fold any BINARY_OPERATIONs now that an IDENTIFIER has been
- * resolved
- */
-ast_node_t *resolve_node(STRING_CACHE_LIST *local_string_cache_list, ast_node_t *node, long *max_size, long assignment_size)
-{
-	STRING_CACHE *local_param_table_sc = local_string_cache_list->local_param_table_sc;
-	bool top_case = false;
-	
-	long my_max = 0;
-	if (max_size == NULL)
-	{
-		max_size = &my_max;
-		top_case = true;
-	}
-
-	long sc_spot = -1;
-
-	if (node)
-	{
-		oassert(node->type != NO_ID);
-
-		if (node->type == NUMBERS && node->types.vnumber->size() > (*max_size))
-		{
-			*max_size = node->types.vnumber->size();
-		}
-		else if (node->type == IDENTIFIERS)
-		{
-			// have to check symbol table AND parameter table for sizes
-			if (local_string_cache_list->local_symbol_table_sc || local_string_cache_list->function_local_symbol_table_sc)
-			{
-				long var_size = get_size_of_variable(node, local_string_cache_list);
-				if (var_size > *max_size)
-				{
-					*max_size = var_size;
-				}
-			}
-		}
-
-		for (size_t i = 0; i < node->num_children; i++)
-		{
-			node->children[i] = resolve_node(local_string_cache_list, node->children[i], max_size, assignment_size);
-		}
-
-		ast_node_t *newNode = NULL;
-		switch (node->type)
-		{
-			case IDENTIFIERS:
-			{
-				if (local_param_table_sc != NULL && node->types.identifier)
-				{
-					sc_spot = sc_lookup_string(local_param_table_sc, node->types.identifier);
-					if (sc_spot != -1)
-					{
-						newNode = ast_node_deep_copy((ast_node_t *)local_param_table_sc->data[sc_spot]);
-						if (newNode->type != NUMBERS)
-						{
-							error_message(NETLIST_ERROR, node->line_number, node->file_number, "Parameter %s is not a constant expression\n", node->types.identifier);
-						}
-						node = free_whole_tree(node);
-						node = newNode;
-					}
-					else
-					{
-						break;
-					}
-				}
-				else
-				{
-					break;
-				}
-			}
-			// fallthrough
-
-			case NUMBERS:
-			{
-				if (top_case && assignment_size > 0) 
-				{
-					VNumber *temp = node->types.vnumber;
-					node->types.vnumber = new VNumber(*temp, assignment_size);
-					delete temp;
-				}
-				return node;
-			}
-			break;
-
-			case UNARY_OPERATION:
-				newNode = fold_unary(&node);
-				break;
-
-			case BINARY_OPERATION:
-				newNode = fold_binary(&node);
-				break;
-			
-			case REPLICATE:
-			{
-				oassert(node_is_constant(node->children[0])); // should be taken care of in parse
-				if( node->children[0]->types.vnumber->is_dont_care_string() )
-				{
-					error_message(NETLIST_ERROR, node->line_number, node->file_number, 
-						"%s","Passing a non constant value to replication command, i.e. 2'bx1{...}");
-				}
-
-				int64_t value = node->children[0]->types.vnumber->get_value();
-				if(value <= 0)
-				{
-					// todo, if this is part of a concat, it is valid
-					error_message(NETLIST_ERROR, node->line_number, node->file_number, 
-						"%s","Passing a number less than or equal to 0 for replication");
-				}
-
-				newNode = create_node_w_type(CONCATENATE, node->line_number, node->file_number); // ????
-				for (size_t i = 0; i < value; i++)
-				{
-					add_child_to_node(newNode, ast_node_deep_copy(node->children[1]));
-				}
-				node = free_whole_tree(node); // this might free stuff we don't want to free?
-				node = newNode;
-
-				break;
-			}
-			
-			case CONCATENATE:
-			{
-				// for params only
-				// TODO: this is a hack, concats cannot be folded in place as it breaks netlist expand from ast,
-				// to fix we need to move the node resolution before netlist create from ast.
-				if(assignment_size == -1)
-				{
-					size_t index = 1;
-					size_t last_index = 0;
-					
-					while(index < node->num_children)
-					{
-						bool previous_is_constant = node_is_constant(node->children[last_index]);
-						bool current_is_constant = node_is_constant(node->children[index]);
-
-						if(previous_is_constant && current_is_constant)
-						{
-							VNumber new_value = V_CONCAT({*(node->children[last_index]->types.vnumber), *(node->children[index]->types.vnumber)});
-
-							node->children[index] = free_whole_tree(node->children[index]);
-
-							delete node->children[last_index]->types.vnumber;
-							node->children[last_index]->types.vnumber = new VNumber(new_value);
-						}
-						else
-						{
-							last_index += 1;
-							previous_is_constant = current_is_constant;
-							node->children[last_index] = node->children[index];
-						}
-						index += 1;
-					}
-
-					node->num_children = last_index+1;
-
-					if(node->num_children == 1)
-					{
-						ast_node_t *tmp = node->children[0];
-						node->children[0] = NULL;
-						free_whole_tree(node);
-						node = tmp;
-					}
-				}
-
-				break;
-			}
-			
-			default:
-				break;
-		}
-
-		if (node_is_constant(newNode)){
-			/* resize as needed */
-			if (assignment_size > 0)
-			{
-				*max_size = assignment_size;
-			}
-
-			/* clean up */
-			free_resolved_children(node);
-			
-			change_to_number_node(node, VNumber(*(newNode->types.vnumber), *max_size));
-			newNode = free_whole_tree(newNode);
-		}
-	}
-	return node;
-}
-
-/*----------------------------------------------------------------------------
  * (function: make_module_param_name)
  *--------------------------------------------------------------------------*/
 /**
diff --git a/ODIN_II/SRC/include/ast_elaborate.h b/ODIN_II/SRC/include/ast_elaborate.h
index 9f1a04f..ce6e602 100644
--- a/ODIN_II/SRC/include/ast_elaborate.h
+++ b/ODIN_II/SRC/include/ast_elaborate.h
@@ -24,6 +24,7 @@
 #ifndef AST_ELABORATE_H
 #define AST_ELABORATE_H
 
-int simplify_ast_module(ast_node_t **ast_module);
+int simplify_ast_module(ast_node_t **ast_module, STRING_CACHE_LIST *local_string_cache_list);
+ast_node_t *reduce_expressions(ast_node_t *node, STRING_CACHE_LIST *local_string_cache_list, long *max_size, long assignment_size);
 
 #endif
\ No newline at end of file
diff --git a/ODIN_II/SRC/include/ast_loop_unroll.h b/ODIN_II/SRC/include/ast_loop_unroll.h
index 30e7782..ca8ade1 100644
--- a/ODIN_II/SRC/include/ast_loop_unroll.h
+++ b/ODIN_II/SRC/include/ast_loop_unroll.h
@@ -15,7 +15,7 @@
 typedef std::function<bool(long)> condition_function;
 typedef std::function<long(long)> post_condition_function;
 
-void unroll_loops(ast_node_t **ast_module);
+void unroll_loops(ast_node_t **ast_module, STRING_CACHE_LIST *local_string_cache_list);
 
 inline bool is_for_node(ast_node_t* node)
 {
@@ -33,9 +33,9 @@
 bool is_unsupported_post(ast_node_t* node, ast_node_t* symbol);
 bool is_unsupported_condition(ast_node_t* node, ast_node_t* symbol);
 
-ast_node_t* for_preprocessor(ast_node_t *ast_module, ast_node_t* node, ast_node_t ***removed_instances, int *num_removed);
-ast_node_t* replace_fors(ast_node_t *ast_module, ast_node_t* node, ast_node_t ***removed_instances, int *num_removed);
-ast_node_t* resolve_for(ast_node_t *ast_module, ast_node_t* node, ast_node_t ****instances, int *num_unrolled, int *num_original);
+ast_node_t* for_preprocessor(ast_node_t *ast_module, ast_node_t* node, STRING_CACHE_LIST *local_string_cache_list, ast_node_t ***removed_instances, int *num_removed);
+ast_node_t* replace_fors(ast_node_t *ast_module, ast_node_t* node, STRING_CACHE_LIST *local_string_cache_list, ast_node_t ***removed_instances, int *num_removed);
+ast_node_t* resolve_for(ast_node_t *ast_module, ast_node_t* node, STRING_CACHE_LIST *local_string_cache_list, ast_node_t ****instances, int *num_unrolled, int *num_original);
 int resolve_pre_condition(ast_node_t* node, ast_node_t** number);
 condition_function resolve_condition(ast_node_t* node, ast_node_t* symbol, int* error_code);
 post_condition_function resolve_binary_operation(ast_node_t* node);
diff --git a/ODIN_II/SRC/include/ast_util.h b/ODIN_II/SRC/include/ast_util.h
index db26429..8891f15 100644
--- a/ODIN_II/SRC/include/ast_util.h
+++ b/ODIN_II/SRC/include/ast_util.h
@@ -41,7 +41,6 @@
 char_list_t *get_name_of_pins_with_prefix(ast_node_t *var_node, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
 long get_size_of_variable(ast_node_t *node, STRING_CACHE_LIST *local_string_cache_list);
 
-ast_node_t *resolve_node(STRING_CACHE_LIST *local_string_cache_list, ast_node_t *node, long *max_size, long assignment_size);
 ast_node_t *node_is_constant(ast_node_t *node);
 ast_node_t *fold_binary(ast_node_t **node);
 ast_node_t *fold_unary(ast_node_t **node);
diff --git a/ODIN_II/SRC/netlist_create_from_ast.cpp b/ODIN_II/SRC/netlist_create_from_ast.cpp
index a1e1884..34f3f81 100644
--- a/ODIN_II/SRC/netlist_create_from_ast.cpp
+++ b/ODIN_II/SRC/netlist_create_from_ast.cpp
@@ -88,17 +88,17 @@
 void create_all_driver_nets_in_this_module(char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
 void create_all_driver_nets_in_this_function(char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
 
-void create_top_driver_nets(ast_node_t* module, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
-void create_top_output_nodes(ast_node_t* module, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
+void create_top_driver_nets(ast_node_t* module, char *instance_name_prefix);
+void create_top_output_nodes(ast_node_t* module, char *instance_name_prefix);
 nnet_t* define_nets_with_driver(ast_node_t* var_declare, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
-nnet_t* define_nodes_and_nets_with_driver(ast_node_t* var_declare, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
+nnet_t* define_nodes_and_nets_with_driver(ast_node_t* var_declare, char *instance_name_prefix);
 
 void connect_hard_block_and_alias(ast_node_t* hb_instance, char *instance_name_prefix, int outport_size, STRING_CACHE_LIST *local_string_cache_list);
 void connect_module_instantiation_and_alias(short PASS, ast_node_t* module_instance, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
 signal_list_t * connect_function_instantiation_and_alias(short PASS, ast_node_t* module_instance, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
-void create_symbol_table_for_module(ast_node_t* module_items, char *module_name, STRING_CACHE_LIST *local_string_cache_list);
-void create_symbol_table_for_function(ast_node_t* module_items, char *module_name, STRING_CACHE_LIST *local_string_cache_list);
-int check_for_initial_reg_value(STRING_CACHE_LIST *local_string_cache_list, ast_node_t* var_declare, long *value);
+void create_symbol_table_for_module(ast_node_t* module_items, STRING_CACHE_LIST *local_string_cache_list);
+void create_symbol_table_for_function(ast_node_t* module_items, STRING_CACHE_LIST *local_string_cache_list);
+int check_for_initial_reg_value(ast_node_t* var_declare, long *value);
 void define_latchs_initial_value_inside_initial_statement(ast_node_t *initial_node, char * /*instance_name_prefix*/, STRING_CACHE_LIST *local_string_cache_list);
 
 signal_list_t *concatenate_signal_lists(signal_list_t **signal_lists, int num_signal_lists);
@@ -108,7 +108,7 @@
 signal_list_t *create_pins(ast_node_t* var_declare, char *name, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
 signal_list_t *create_output_pin(ast_node_t* var_declare, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
 signal_list_t *assignment_alias(ast_node_t* assignment, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
-signal_list_t *create_operation_node(ast_node_t *op, signal_list_t **input_lists, int list_size, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
+signal_list_t *create_operation_node(ast_node_t *op, signal_list_t **input_lists, int list_size, char *instance_name_prefix);
 
 void terminate_continuous_assignment(ast_node_t *node, signal_list_t* assignment, char *instance_name_prefix);
 void terminate_registered_assignment(ast_node_t *always_node, signal_list_t* assignment, signal_list_t *potential_clocks, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list);
@@ -332,35 +332,6 @@
 	oassert(parent_string_cache_list);
 	parent_string_cache_list->local_param_table_sc = parent_param_table_sc; // to check parent parameters
 
-	for (i = 0; i < parameter_num; i++) 
-	{
-		sc_spot = sc_lookup_string(local_param_table_sc, temp_parameter_list[i]);
-		if(sc_spot == -1)
-		{
-			error_message(NETLIST_ERROR, parent_parameter_list->line_number, parent_parameter_list->file_number,
-					"Can't find parameter name %s in module %s\n",
-					temp_parameter_list[i],
-					module_name);
-		}
-		ast_node_t *node = (ast_node_t *)local_param_table_sc->data[sc_spot];
-		oassert(node);
-		node = resolve_node(local_string_cache_list, node, NULL, -1);
-		if (node->type != NUMBERS) 
-		{
-			node = resolve_node(parent_string_cache_list, node, NULL, -1); // may contain parameters from parent
-		}
-		oassert(node->type == NUMBERS);
-
-		/* this forces parameter values as unsigned, since we don't currently support signed keyword...
-		   must be changed once support is added */
-		VNumber *temp = node->types.vnumber;
-		VNumber *to_unsigned = new VNumber(V_UNSIGNED(*temp));
-		node->types.vnumber = to_unsigned;
-		delete temp;
-
-		local_param_table_sc->data[sc_spot] = (void *)node;
-	}
-
 	/* clean up */
 	if (temp_parameter_list) {
 		for (i = 0; i < parameter_num; i++) {
@@ -439,19 +410,32 @@
 	/* initialize the storage of the top level drivers.  Assigned in create_top_driver_nets */
 	verilog_netlist = allocate_netlist();
 
-	// create the parameter table for the top module
-	STRING_CACHE *top_param_table_sc = create_param_table_for_module(NULL, top_module->children[2], top_string, NULL);
 	STRING_CACHE_LIST *top_sc_list = (STRING_CACHE_LIST*)vtr::calloc(1, sizeof(STRING_CACHE_LIST));
-	top_sc_list->local_param_table_sc = top_param_table_sc;
+
+	/* create the parameter table for the top module */
+	top_sc_list->local_param_table_sc = create_param_table_for_module(NULL, top_module->children[2], top_string, NULL);
+	
+	/* create the symbol table for the top module */
+	top_sc_list->local_symbol_table_sc = sc_new_string_cache();
+	top_sc_list->num_local_symbol_table = 0;
+	top_sc_list->local_symbol_table = NULL;
+	create_symbol_table_for_module(top_module->children[2], top_sc_list);
+
+	/* elaboration */
+	simplify_ast_module(&top_module, top_sc_list);
 
 	/* now recursively parse the modules by going through the tree of modules starting at top */
-	create_top_driver_nets(top_module, top_string, top_sc_list);
+	create_top_driver_nets(top_module, top_string);
 	init_implicit_memory_index();
 	convert_ast_to_netlist_recursing_via_modules(&top_module, top_string, top_sc_list, 0);
 	free_implicit_memory_index_and_finalize_memories();
-	create_top_output_nodes(top_module, top_string, top_sc_list);
+	create_top_output_nodes(top_module, top_string);
 
-	top_sc_list->local_param_table_sc = sc_free_string_cache(top_param_table_sc);
+	top_sc_list->local_param_table_sc = sc_free_string_cache(top_sc_list->local_param_table_sc);
+	top_sc_list->local_symbol_table_sc = sc_free_string_cache(top_sc_list->local_symbol_table_sc);
+	top_sc_list->num_local_symbol_table = 0;
+	top_sc_list->local_symbol_table = (ast_node_t **)vtr::free(top_sc_list->local_symbol_table);
+
 	vtr::free(top_sc_list);
 
 	/* now look for high-level signals */
@@ -587,7 +571,6 @@
 void convert_ast_to_netlist_recursing_via_modules(ast_node_t** current_module, char *instance_name, STRING_CACHE_LIST *local_string_cache_list, int level)
 {
 	signal_list_t *list = NULL;
-	simplify_ast_module(current_module/*, local_string_cache_list*/);
 
 	STRING_CACHE *local_param_table_sc = local_string_cache_list->local_param_table_sc;
 
@@ -673,12 +656,26 @@
 			STRING_CACHE_LIST *module_string_cache_list = (STRING_CACHE_LIST*)calloc(1, sizeof(STRING_CACHE_LIST));
 			module_string_cache_list->local_param_table_sc = module_param_table_sc;
 
+			// create the symbol table for the instantiated module
+			module_string_cache_list->local_symbol_table_sc = sc_new_string_cache();
+			module_string_cache_list->num_local_symbol_table = 0;
+			module_string_cache_list->local_symbol_table = NULL;
+			create_symbol_table_for_module(((ast_node_t*)module_names_to_idx->data[sc_spot])->children[2], module_string_cache_list);
+
+			/* elaboration */
+			simplify_ast_module(((ast_node_t**)&module_names_to_idx->data[sc_spot]), module_string_cache_list);
+
 			/* recursive call point */
 			convert_ast_to_netlist_recursing_via_modules(((ast_node_t**)&module_names_to_idx->data[sc_spot]), temp_instance_name, module_string_cache_list, level+1);
 
 			/* clean up */
 			vtr::free(temp_instance_name);
-			module_param_table_sc = sc_free_string_cache(module_param_table_sc);
+
+			module_string_cache_list->local_param_table_sc = sc_free_string_cache(module_string_cache_list->local_param_table_sc);
+			module_string_cache_list->local_symbol_table_sc = sc_free_string_cache(module_string_cache_list->local_symbol_table_sc);
+			module_string_cache_list->num_local_symbol_table = 0;
+			module_string_cache_list->local_symbol_table = (ast_node_t **)vtr::free(module_string_cache_list->local_symbol_table);
+			
 			vtr::free(module_string_cache_list);
 		}
         for (k = 0; k < (*current_module)->types.function.size_function_instantiations; k++)
@@ -702,7 +699,7 @@
 
 			ast_node_t *parent_parameter_list = (*current_module)->types.function.function_instantiations_instance[k]->children[1]->children[2];
 
-			// create the parameter table for the instantiated module
+			// create the parameter table for the instantiated function
 			STRING_CACHE *function_param_table_sc = create_param_table_for_module(parent_parameter_list,
 				/* module_items */
 				((ast_node_t*)module_names_to_idx->data[sc_spot])->children[2],
@@ -711,12 +708,26 @@
 			STRING_CACHE_LIST *function_string_cache_list = (STRING_CACHE_LIST*)calloc(1, sizeof(STRING_CACHE_LIST));
 			function_string_cache_list->local_param_table_sc = function_param_table_sc;
 
+			// create the symbol table for the instantiated function
+			function_string_cache_list->function_local_symbol_table_sc = sc_new_string_cache();
+			function_string_cache_list->function_num_local_symbol_table = 0;
+			function_string_cache_list->function_local_symbol_table = NULL;
+			create_symbol_table_for_function(((ast_node_t*)module_names_to_idx->data[sc_spot])->children[2], function_string_cache_list);
+
+			/* elaboration */
+			simplify_ast_module(((ast_node_t**)&module_names_to_idx->data[sc_spot]), function_string_cache_list);
+
 			/* recursive call point */
 			convert_ast_to_netlist_recursing_via_modules(((ast_node_t**)&module_names_to_idx->data[sc_spot]), temp_instance_name,function_string_cache_list, level+1);
 
 			/* clean up */
 			vtr::free(temp_instance_name);
-			function_param_table_sc = sc_free_string_cache(function_param_table_sc);
+			
+			function_string_cache_list->local_param_table_sc = sc_free_string_cache(function_string_cache_list->local_param_table_sc);
+			function_string_cache_list->function_local_symbol_table_sc = sc_free_string_cache(function_string_cache_list->function_local_symbol_table_sc);
+			function_string_cache_list->num_local_symbol_table = 0;
+			function_string_cache_list->function_local_symbol_table = (ast_node_t **)vtr::free(function_string_cache_list->function_local_symbol_table);
+
 			vtr::free(function_string_cache_list);
 		}
 
@@ -766,11 +777,6 @@
 				oassert(false);
 				break;
 			case MODULE:
-				oassert(child_skip_list);
-				local_string_cache_list->local_symbol_table_sc = sc_new_string_cache();
-				local_string_cache_list->num_local_symbol_table = 0;
-				local_string_cache_list->local_symbol_table = NULL;
-
 				/* set the skip list */
 				child_skip_list[0] = true; /* skip the identifier */
 				child_skip_list[1] = true; /* skip portlist ... we'll use where they're defined */
@@ -785,8 +791,6 @@
 			case MODULE_ITEMS:
 				/* items include: wire, reg, input, outputs, assign, gate, module_instance, always */
 
-				/* make the symbol table */
-				create_symbol_table_for_module(node, instance_name_prefix, local_string_cache_list);
 				local_clock_found = false;
 
 				/* check for initial register values set in initial block.*/
@@ -871,11 +875,7 @@
                 break;
             case FUNCTION_ITEMS:
 				/* items include: wire, reg, input, outputs, assign, gate, always */
-				/* make the symbol table */
-				local_string_cache_list->function_local_symbol_table_sc = sc_new_string_cache();
-				local_string_cache_list->function_num_local_symbol_table = 0;
-				local_string_cache_list->function_local_symbol_table = NULL;
-				create_symbol_table_for_function(node, instance_name_prefix, local_string_cache_list);
+
 				local_clock_found = false;
 
 				/* create all the driven nets based on the "reg" registers */
@@ -920,7 +920,6 @@
 			case RANGE_REF:
 			case NUMBERS:
 			{
-				node = resolve_node(local_string_cache_list, node, NULL, 0);
 				return_sig_list = create_pins(node, NULL, instance_name_prefix, local_string_cache_list);
 				break;
 			}
@@ -963,10 +962,6 @@
 				child_skip_list[1] = true; /* skip portlist ... we'll use where they're defined */
 				return_sig_list = create_hard_block(node, instance_name_prefix, local_string_cache_list);
 				break;
-			case CONCATENATE:
-				resolve_concat_sizes(node, local_string_cache_list);
-				node = resolve_node(local_string_cache_list, node, NULL, 0);
-				break;
 			default:
 				break;
 		}
@@ -989,29 +984,6 @@
 		/* POST AMBLE - process the children */
 		switch(node->type)
 		{
-			case MODULE:
-			{
-				/* resolved ports need to be updated */
-				ast_node_t *port_list = node->children[1];
-				STRING_CACHE *local_symbol_table_sc = local_string_cache_list->local_symbol_table_sc;
-
-				for (i = 0; i < port_list->num_children; i++)
-				{	
-					oassert(port_list->children[i]->type == VAR_DECLARE);
-					char *id = port_list->children[i]->children[0]->types.identifier;
-
-					long sc_spot = sc_lookup_string(local_symbol_table_sc, id);
-					oassert (sc_spot > -1);
-					port_list->children[i] = (ast_node_t *)local_symbol_table_sc->data[sc_spot];
-					port_list->children[i] = resolve_node(local_string_cache_list, port_list->children[i], NULL, 0);
-				}
-
-				/* free the symbol table for this module since we're done processing */
-				local_string_cache_list->local_symbol_table_sc = sc_free_string_cache(local_string_cache_list->local_symbol_table_sc);
-				local_string_cache_list->local_symbol_table = (ast_node_t**) vtr::free(local_string_cache_list->local_symbol_table);
-				local_string_cache_list->local_symbol_table = NULL;
-				break;
-			}
 			case FILE_ITEMS:
 				error_message(NETLIST_ERROR, node->line_number, node->file_number,"%s",
 						"FILE_ITEMS are not supported by Odin.\n");
@@ -1037,14 +1009,6 @@
 				}
 				break;
 			}
-			case FUNCTION_ITEMS:
-			{
-				/* free the symbol table for this function since we're done processing */
-				local_string_cache_list->function_local_symbol_table_sc = sc_free_string_cache(local_string_cache_list->function_local_symbol_table_sc);
-				local_string_cache_list->function_local_symbol_table = (ast_node_t**) vtr::free(local_string_cache_list->function_local_symbol_table);
-				local_string_cache_list->function_local_symbol_table = NULL;
-				break;
-			}
 			case FUNCTION_INSTANCE:
 			{
 				signal_list_t *temp_list = connect_function_instantiation_and_alias(ALIAS_INPUTS, node, instance_name_prefix, local_string_cache_list);
@@ -1096,11 +1060,11 @@
 				break;
 			case BINARY_OPERATION:
 				oassert(node->num_children == 2);
-				return_sig_list = create_operation_node(node, children_signal_list, node->num_children, instance_name_prefix, local_string_cache_list);
+				return_sig_list = create_operation_node(node, children_signal_list, node->num_children, instance_name_prefix);
 				break;
 			case UNARY_OPERATION:
 				oassert(node->num_children == 1);
-				return_sig_list = create_operation_node(node, children_signal_list, node->num_children, instance_name_prefix, local_string_cache_list);
+				return_sig_list = create_operation_node(node, children_signal_list, node->num_children, instance_name_prefix);
 				break;
 			case BLOCK:
 				if (node->num_children > 0)
@@ -1276,7 +1240,7 @@
  * 	Also make the 0 and 1 constant nodes at this point.
  *  Note: Also creates hbpad signal for padding hard block inputs.
  *-------------------------------------------------------------------------*/
-void create_top_driver_nets(ast_node_t* module, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list)
+void create_top_driver_nets(ast_node_t* module, char *instance_name_prefix)
 {
 	/* with the top module we need to visit the entire ast tree */
 	long i, j;
@@ -1298,7 +1262,7 @@
 				{
 					if (module_items->children[i]->children[j]->types.variable.is_input)
 					{
-						define_nodes_and_nets_with_driver(module_items->children[i]->children[j], instance_name_prefix, local_string_cache_list);
+						define_nodes_and_nets_with_driver(module_items->children[i]->children[j], instance_name_prefix);
 					}
 				}
 			}
@@ -1386,7 +1350,7 @@
  * 	as actual nodes in the netlist and hooks them up to the netlist as it has been
  * 	created.  Therefore, this is one of the last steps when creating the netlist.
  *-------------------------------------------------------------------------------------------*/
-void create_top_output_nodes(ast_node_t* module, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list)
+void create_top_output_nodes(ast_node_t* module, char *instance_name_prefix)
 {
 	/* with the top module we need to visit the entire ast tree */
 	long i, j;
@@ -1450,8 +1414,6 @@
 						}
 						else if (var_declare->children[3] == NULL)
 						{
-							var_declare->children[1] = resolve_node(local_string_cache_list, var_declare->children[1], NULL, 0);
-							var_declare->children[2] = resolve_node(local_string_cache_list, var_declare->children[2], NULL, 0);
 							ast_node_t *node_max  = var_declare->children[1];
 							ast_node_t *node_min  = var_declare->children[2];
 							
@@ -1538,12 +1500,6 @@
 	&& var_declare->children[5] 
 	&& var_declare->children[6])
 	{
-		var_declare->children[3] = resolve_node(local_string_cache_list, var_declare->children[3], NULL, 0);
-		var_declare->children[4] = resolve_node(local_string_cache_list, var_declare->children[4], NULL, 0);
-
-		var_declare->children[5] = resolve_node(local_string_cache_list, var_declare->children[5], NULL, 0);
-		var_declare->children[6] = resolve_node(local_string_cache_list, var_declare->children[6], NULL, 0);
-
 		ast_node_t *node_max2  = var_declare->children[3];
 		ast_node_t *node_min2  = var_declare->children[4];
 
@@ -1635,10 +1591,7 @@
 		}
 	}
 	else if (var_declare->children[3] == NULL)
-	{
-		var_declare->children[1] = resolve_node(local_string_cache_list, var_declare->children[1], NULL, 0);
-		var_declare->children[2] = resolve_node(local_string_cache_list, var_declare->children[2], NULL, 0);
-		
+	{		
 		ast_node_t *node_max  = var_declare->children[1];
 		ast_node_t *node_min  = var_declare->children[2];
 
@@ -1698,8 +1651,6 @@
 	/* Implicit memory */
 	else if (var_declare->children[3] != NULL)
 	{
-		var_declare->children[1] = resolve_node(local_string_cache_list, var_declare->children[1], NULL, 0);
-		var_declare->children[2] = resolve_node(local_string_cache_list, var_declare->children[2], NULL, 0);
 		ast_node_t *node_max1  = var_declare->children[1];
 		ast_node_t *node_min1  = var_declare->children[2];
 
@@ -1719,8 +1670,6 @@
 					"Odin doesn't support negative number in index.");
 		}
 		
-		var_declare->children[3] = resolve_node(local_string_cache_list, var_declare->children[3], NULL, 0);
-		var_declare->children[4] = resolve_node(local_string_cache_list, var_declare->children[4], NULL, 0);
 		ast_node_t *node_max2  = var_declare->children[3];
 		ast_node_t *node_min2  = var_declare->children[4];
 
@@ -1768,7 +1717,7 @@
  * 	Similar to define_nets_with_driver except this one is for top level nodes and
  * 	is making the input pins into nodes and drivers.
  *-------------------------------------------------------------------------------------------*/
-nnet_t* define_nodes_and_nets_with_driver(ast_node_t* var_declare, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list)
+nnet_t* define_nodes_and_nets_with_driver(ast_node_t* var_declare, char *instance_name_prefix)
 {
 	int i;
 	char *temp_string;
@@ -1819,8 +1768,6 @@
 	else if (var_declare->children[3] == NULL)
 	{
 		/* FOR array driver  since sport 3 and 4 are NULL */
-		var_declare->children[1] = resolve_node(local_string_cache_list, var_declare->children[1], NULL, 0);
-		var_declare->children[2] = resolve_node(local_string_cache_list, var_declare->children[2], NULL, 0);
 		ast_node_t *node_max  = var_declare->children[1];
 		ast_node_t *node_min  = var_declare->children[2];
 
@@ -1894,7 +1841,7 @@
  * 	Creates a lookup of the variables declared here so that in the analysis we can look
  * 	up the definition of it to decide what to do.
  *-------------------------------------------------------------------------------------------*/
-void create_symbol_table_for_module(ast_node_t* module_items, char * /*module_name*/, STRING_CACHE_LIST *local_string_cache_list)
+void create_symbol_table_for_module(ast_node_t* module_items, STRING_CACHE_LIST *local_string_cache_list)
 {
 	/* with the top module we need to visit the entire ast tree */
 	long i, j;
@@ -1963,7 +1910,7 @@
 
 							/* check for an initial value and copy it over if found */
 							long initial_value;
-							if(check_for_initial_reg_value(local_string_cache_list, var_declare, &initial_value)){
+							if(check_for_initial_reg_value(var_declare, &initial_value)){
 								((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.is_initialized = true;
 								((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.initial_value = initial_value;
 							}
@@ -1977,7 +1924,7 @@
 							((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.is_integer = var_declare->types.variable.is_integer;
 							/* check for an initial value and copy it over if found */
 							long initial_value;
-							if(check_for_initial_reg_value(local_string_cache_list, var_declare, &initial_value)){
+							if(check_for_initial_reg_value(var_declare, &initial_value)){
 								((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.is_initialized = true;
 								((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.initial_value = initial_value;
 							}
@@ -1999,7 +1946,7 @@
 
 						/* check for an initial value and store it if found */
 						long initial_value;
-						if(check_for_initial_reg_value(local_string_cache_list, var_declare, &initial_value)){
+						if(check_for_initial_reg_value(var_declare, &initial_value)){
 							var_declare->types.variable.is_initialized = true;
 							var_declare->types.variable.initial_value = initial_value;
 						}
@@ -2007,6 +1954,41 @@
 					vtr::free(temp_string);
 				}
 			}
+			else if(module_items->children[i]->type == ASSIGN)
+			{
+				/* might be an implicit declaration */
+				if((module_items->children[i]->children[0]) && (module_items->children[i]->children[0]->type == BLOCKING_STATEMENT))
+				{
+					if((module_items->children[i]->children[0]->children[0]) && (module_items->children[i]->children[0]->children[0]->type == IDENTIFIERS))
+					{ 
+						temp_string = make_full_ref_name(NULL, NULL, NULL, module_items->children[i]->children[0]->children[0]->types.identifier, -1);
+						/* look for that element */
+						sc_spot = sc_lookup_string(local_symbol_table_sc, temp_string);
+						if( sc_spot == -1 )
+						{
+							sc_spot = sc_add_string(local_symbol_table_sc, temp_string);
+
+							/* store the data which is an idx here */
+							local_symbol_table_sc->data[sc_spot]= module_items->children[i]->children[0];
+
+							/* store the symbol */
+							local_symbol_table = (ast_node_t **)vtr::realloc(local_symbol_table, sizeof(ast_node_t*)*(num_local_symbol_table+1));
+							local_symbol_table[num_local_symbol_table] = (ast_node_t *)module_items->children[i]->children[0];
+							num_local_symbol_table ++;
+
+
+							/* copy the output status over */
+							((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.is_wire = true;
+							((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.is_reg = false;
+
+							((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.is_integer = false;
+							((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.is_input = false;
+
+						}
+						vtr::free(temp_string);
+					}
+				}
+			}
 		}
 		local_string_cache_list->local_symbol_table = local_symbol_table;
 		local_string_cache_list->num_local_symbol_table = num_local_symbol_table;
@@ -2022,7 +2004,7 @@
  * 	Creates a lookup of the variables declared here so that in the analysis we can look
  * 	up the definition of it to decide what to do.
  *-------------------------------------------------------------------------------------------*/
-void create_symbol_table_for_function(ast_node_t* function_items, char * /*module_name*/, STRING_CACHE_LIST *local_string_cache_list)
+void create_symbol_table_for_function(ast_node_t* function_items, STRING_CACHE_LIST *local_string_cache_list)
 {
 	/* with the top module we need to visit the entire ast tree */
 	long i, j;
@@ -2075,7 +2057,7 @@
 
 							/* check for an initial value and copy it over if found */
 							long initial_value;
-							if(check_for_initial_reg_value(local_string_cache_list, var_declare, &initial_value)){
+							if(check_for_initial_reg_value(var_declare, &initial_value)){
 								((ast_node_t*)function_local_symbol_table_sc->data[sc_spot])->types.variable.is_initialized = true;
 								((ast_node_t*)function_local_symbol_table_sc->data[sc_spot])->types.variable.initial_value = initial_value;
 							}
@@ -2090,7 +2072,7 @@
 
 							/* check for an initial value and copy it over if found */
 							long initial_value;
-							if(check_for_initial_reg_value(local_string_cache_list, var_declare, &initial_value)){
+							if(check_for_initial_reg_value(var_declare, &initial_value)){
 								((ast_node_t*)function_local_symbol_table_sc->data[sc_spot])->types.variable.is_initialized = true;
 								((ast_node_t*)function_local_symbol_table_sc->data[sc_spot])->types.variable.initial_value = initial_value;
 							}
@@ -2112,7 +2094,7 @@
 
 						/* check for an initial value and store it if found */
 						long initial_value;
-						if(check_for_initial_reg_value(local_string_cache_list, var_declare, &initial_value)){
+						if(check_for_initial_reg_value(var_declare, &initial_value)){
 							var_declare->types.variable.is_initialized = true;
 							var_declare->types.variable.initial_value = initial_value;
 						}
@@ -2136,24 +2118,22 @@
  *  Returns the initial value in *value if one is found.
  *  Added by Conor
  *-------------------------------------------------------------------------*/
-int check_for_initial_reg_value(STRING_CACHE_LIST *local_string_cache_list, ast_node_t* var_declare, long *value)
+int check_for_initial_reg_value(ast_node_t* var_declare, long *value)
 {
 	oassert(var_declare->type == VAR_DECLARE);
 
-	var_declare->children[5] = resolve_node(local_string_cache_list, var_declare->children[5], NULL, 0);
-	ast_node_t *resolved_number  = var_declare->children[5];
 	// Initial value is always the last child, if one exists
-	if(resolved_number != NULL)
+	if(var_declare->children[5] != NULL)
 	{
-		if(resolved_number->type == NUMBERS)
+		if(var_declare->children[5]->type == NUMBERS)
 		{
-			*value = resolved_number->types.vnumber->get_value();
+			*value = var_declare->children[5]->types.vnumber->get_value();
 			return true;
 		}
 		else
 		{
 			warning_message(NETLIST_ERROR, var_declare->line_number, var_declare->file_number, 
-				"%s", "Could not resolve initial assignement to a constant value, skipping\n");
+				"%s", "Could not resolve initial assignment to a constant value, skipping\n");
 		}
 	}
 	return false;
@@ -2545,9 +2525,6 @@
 			}
 			else if (module_var_node->children[3] == NULL)
 			{
-				module_var_node->children[1] = resolve_node(local_string_cache_list, module_var_node->children[1], NULL, 0);
-				module_var_node->children[2] = resolve_node(local_string_cache_list, module_var_node->children[2], NULL, 0);
-
 				ast_node_t *node1  = module_var_node->children[1];
 				ast_node_t *node2  = module_var_node->children[2];
 
@@ -2558,11 +2535,6 @@
 			}
 			else if (module_var_node->children[5] == NULL)
 			{
-				module_var_node->children[1] = resolve_node(local_string_cache_list, module_var_node->children[1], NULL, 0);
-				module_var_node->children[2] = resolve_node(local_string_cache_list, module_var_node->children[2], NULL, 0);
-				module_var_node->children[3] = resolve_node(local_string_cache_list, module_var_node->children[3], NULL, 0);
-				module_var_node->children[4] = resolve_node(local_string_cache_list, module_var_node->children[4], NULL, 0);
-
 				ast_node_t *node1  = module_var_node->children[1];
 				ast_node_t *node2  = module_var_node->children[2];
 				ast_node_t *node3  = module_var_node->children[3];
@@ -2879,8 +2851,6 @@
 				module_instance->children[1]->children[0]->types.identifier,
 				NULL, -1);
 
-			module_var_node->children[1] = resolve_node(local_string_cache_list, module_var_node->children[1], NULL, 0);
-			module_var_node->children[2] = resolve_node(local_string_cache_list, module_var_node->children[2], NULL, 0);
 			ast_node_t *node1  = module_var_node->children[1];
 			ast_node_t *node2  = module_var_node->children[2];
 
@@ -2899,11 +2869,6 @@
 				module_instance->children[1]->children[0]->types.identifier,
 				NULL, -1);
 
-			module_var_node->children[1] = resolve_node(local_string_cache_list, module_var_node->children[1], NULL, 0);
-			module_var_node->children[2] = resolve_node(local_string_cache_list, module_var_node->children[2], NULL, 0);
-			module_var_node->children[3] = resolve_node(local_string_cache_list, module_var_node->children[3], NULL, 0);
-			module_var_node->children[4] = resolve_node(local_string_cache_list, module_var_node->children[4], NULL, 0);
-			
 			ast_node_t *node1  = module_var_node->children[1];
 			ast_node_t *node2  = module_var_node->children[2];
 			ast_node_t *node3  = module_var_node->children[3];
@@ -3307,56 +3272,6 @@
  *-------------------------------------------------------------------------------------------*/
 signal_list_t *assignment_alias(ast_node_t* assignment, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list)
 {
-	/* try to resolve */
-	if (assignment->children[1]->type != FUNCTION_INSTANCE)
-	{
-		long assignment_size = get_size_of_variable(assignment->children[0], local_string_cache_list);
-		assignment->children[1] = resolve_node(local_string_cache_list, assignment->children[1], NULL, assignment_size);
-	
-		/* cast to unsigned if necessary */
-		if (node_is_constant(assignment->children[1]))
-		{
-			char *id = NULL;
-			if (assignment->children[0]->type == IDENTIFIERS)
-			{
-				id = assignment->children[0]->types.identifier;
-			}
-			else
-			{
-				id = assignment->children[0]->children[0]->types.identifier;
-			}
-
-			STRING_CACHE *local_symbol_table_sc = local_string_cache_list->local_symbol_table_sc;
-			long sc_spot = sc_lookup_string(local_symbol_table_sc, id);
-			if (sc_spot > -1)
-			{
-				bool is_signed = ((ast_node_t *)local_symbol_table_sc->data[sc_spot])->types.variable.is_signed;
-				if (!is_signed)
-				{
-					VNumber *temp = assignment->children[1]->types.vnumber;
-					VNumber *to_unsigned = new VNumber(V_UNSIGNED(*temp));
-					assignment->children[1]->types.vnumber = to_unsigned;
-					delete temp;
-				}
-				else
-				{
-					/* leave as is */
-				}
-			}
-		}
-		else
-		{
-			/* signed keyword is not supported, meaning unresolved values will already be handled as
-				unsigned at the netlist level... must update once signed support is added */
-		}
-	}
-	
-	if (assignment->children[0]->type != FUNCTION_INSTANCE)
-	{
-		long assignment_size = get_size_of_variable(assignment->children[0], local_string_cache_list);
-		assignment->children[0] = resolve_node(local_string_cache_list, assignment->children[0], NULL, assignment_size);
-	}
-
 	ast_node_t *left  = assignment->children[0];
 	ast_node_t *right = assignment->children[1];
 
@@ -4185,7 +4100,7 @@
 /*----------------------------------------------------------------------------
  * (function: create_operation_node)
  *--------------------------------------------------------------------------*/
-signal_list_t *create_operation_node(ast_node_t *op, signal_list_t **input_lists, int list_size, char *instance_name_prefix, STRING_CACHE_LIST *local_string_cache_list)
+signal_list_t *create_operation_node(ast_node_t *op, signal_list_t **input_lists, int list_size, char *instance_name_prefix)
 {
 	long i;
 	signal_list_t *return_list = init_signal_list();
@@ -4336,7 +4251,6 @@
 		if ((operation_node->type == SR) || (operation_node->type == SL) || (operation_node->type == ASR))
 		{
 			/* Need to check that 2nd operand is constant */
-			op->children[1] = resolve_node(local_string_cache_list, op->children[1], NULL, 0);
 			ast_node_t *second  = op->children[1];
 			if (second->type != NUMBERS)
 				error_message(NETLIST_ERROR, op->line_number, op->file_number, "%s", "Odin only supports constant shifts at present\n");
@@ -4461,8 +4375,6 @@
 				}
 			}
 
-			delay_control->children[i] = resolve_node(local_string_cache_list, delay_control->children[i], NULL, 0);
-
 			switch(child_sensitivity)
 			{
 				case FALLING_EDGE_SENSITIVITY: //falltrhough
@@ -4506,9 +4418,6 @@
 	signal_list_t *return_list;
 	nnode_t *if_node;
 
-	/* try to resolve constant expressions in condition */
-	if_ast->children[0] = resolve_node(local_string_cache_list, if_ast->children[0], NULL, 0);
-
 	/* create the node */
 	if_node = allocate_nnode();
 	/* store all the relevant info */
@@ -4566,9 +4475,6 @@
 	signal_list_t *return_list;
 	nnode_t *if_node;
 
-	/* try to resolve constant expressions in condition */
-	if_ast->children[0] = resolve_node(local_string_cache_list, if_ast->children[0], NULL, 0);
-
 	/* create the node */
 	if_node = allocate_nnode();
 	/* store all the relevant info */
@@ -4747,7 +4653,7 @@
 			case_compares[1] = netlist_expand_ast_of_module(&(case_list_of_items->children[i]->children[0]), instance_name_prefix, local_string_cache_list);
 
 			/* make a LOGIC_EQUAL gate that collects all the other signals and if they're all off */
-			case_compare_expression = create_operation_node(logical_equal, case_compares, 2, instance_name_prefix, local_string_cache_list);
+			case_compare_expression = create_operation_node(logical_equal, case_compares, 2, instance_name_prefix);
 			oassert(case_compare_expression->count == 1);
 
 			/* hookup this pin to the spot in the case_node */
@@ -6159,12 +6065,6 @@
 	new_node_1 = newBinaryOperation(MULTIPLY, array_row, array_size, node->children[0]->line_number);
 	new_node_2 = newBinaryOperation(ADD, new_node_1, array_col, node->children[0]->line_number);
 
-	// see if this operation can be resolved
-	if (new_node_2->type != NUMBERS)
-	{
-		new_node_2 = resolve_node(local_string_cache_list, new_node_2, NULL, 0);
-	}
-
 	vtr::free(array_name);
 
 	node->children[1] = new_node_2;
diff --git a/ODIN_II/SRC/parse_making_ast.cpp b/ODIN_II/SRC/parse_making_ast.cpp
index 48eb556..58720f3 100644
--- a/ODIN_II/SRC/parse_making_ast.cpp
+++ b/ODIN_II/SRC/parse_making_ast.cpp
@@ -1401,7 +1401,8 @@
 	long i;
 	/* create a node for this array reference */
 	ast_node_t* new_master_node = create_node_w_type(MODULE_INSTANCE, line_number, current_parse_file);
-	for(i = 0; i < module_named_instance->num_children; i++){
+	for(i = 0; i < module_named_instance->num_children; i++)
+	{
 		if
 		(
 			sc_lookup_string(hard_block_names, module_ref_name) != -1
@@ -1451,11 +1452,10 @@
 
 		/* store the module symbol name that this calls in a list that will at the end be asociated with the module node */
 		module_instantiations_instance = (ast_node_t **)vtr::realloc(module_instantiations_instance, sizeof(ast_node_t*)*(size_module_instantiations+1));
-		module_instantiations_instance[size_module_instantiations] = ast_node_deep_copy(new_node);
+		module_instantiations_instance[size_module_instantiations] = new_node;
 		size_module_instantiations++;
-
 	}
-	//TODO: free_whole_tree ??
+
 	vtr::free(module_named_instance->children);
 	vtr::free(module_named_instance);
 	vtr::free(module_ref_name);
@@ -1467,16 +1467,6 @@
  *-----------------------------------------------------------------------*/
 ast_node_t *newFunctionInstance(char* function_ref_name, ast_node_t *function_named_instance, int line_number)
 {
-	if
-	(
-		sc_lookup_string(hard_block_names, function_ref_name) != -1
-		|| !strcmp(function_ref_name, SINGLE_PORT_RAM_string)
-		|| !strcmp(function_ref_name, DUAL_PORT_RAM_string)
-	)
-	{
-		return newHardBlockInstance(function_ref_name, function_named_instance, line_number);
-	}
-
 	// make a unique module name based on its parameter list
 	ast_node_t *function_param_list = function_named_instance->children[2];