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];