fixed node resolving
diff --git a/ODIN_II/SRC/ast_elaborate.cpp b/ODIN_II/SRC/ast_elaborate.cpp
index f97d701..5f85c0f 100644
--- a/ODIN_II/SRC/ast_elaborate.cpp
+++ b/ODIN_II/SRC/ast_elaborate.cpp
@@ -82,14 +82,12 @@
{
/* reduce parameters with their values if they have been set */
reduce_parameter(*ast_module);
- /* simplify assignment expressions */
- reduce_assignment_expression(*ast_module);
/* for loop support */
unroll_loops(ast_module);
/* remove unused node preventing module instantiation */
remove_generate(*ast_module);
- /* find multiply or divide operation that can be replaced with shift operation */
- shift_operation(*ast_module);
+ /* simplify assignment expressions */
+ reduce_assignment_expression(*ast_module);
return 1;
}
@@ -1153,86 +1151,6 @@
}
/*---------------------------------------------------------------------------
- * (function: copy_tree)
- * find multiply or divide operation that can be replaced with shift operation
- *-------------------------------------------------------------------------*/
-void shift_operation(ast_node_t *ast_module)
-{
- if(ast_module){
- search_certain_operation(ast_module);
- }
-
-}
-
-/*---------------------------------------------------------------------------
- * (function: change_ast_node)
- * search all AST to find multiply or divide operations
- *-------------------------------------------------------------------------*/
-void search_certain_operation(ast_node_t *node)
-{
- for (long i = 0; node && i < node->num_children; i++){
- check_binary_operation(node->children[i]);
- search_certain_operation(node->children[i]);
- }
-}
-
-/*---------------------------------------------------------------------------
- * (function: change_ast_node)
- * check the children nodes of an operation node
- *-------------------------------------------------------------------------*/
-void check_binary_operation(ast_node_t *node)
-{
- if(node && node->type == BINARY_OPERATION){
- switch(node->types.operation.op){
- case MULTIPLY:
- if (node->children[0]->type == IDENTIFIERS && node->children[1]->type == NUMBERS)
- check_node_number(node, node->children[1], 1); // 1 means multiply and don't need to move children nodes
- if (node->children[0]->type == NUMBERS && node->children[1]->type == IDENTIFIERS)
- check_node_number(node, node->children[0], 2); // 2 means multiply and needs to move children nodes
- break;
- case DIVIDE:
- if (node->children[0]->type == IDENTIFIERS && node->children[1]->type == NUMBERS)
- check_node_number(node, node->children[1], 3); // 3 means divide
- break;
- default:
- break;
- }
- }
-}
-
-/*---------------------------------------------------------------------------
- * (function: change_ast_node)
- * check if the number is the power of 2
- *-------------------------------------------------------------------------*/
-void check_node_number(ast_node_t *parent, ast_node_t *child, int flag)
-{
- long power = 0;
- long number = child->types.vnumber->get_value();
- if (number <= 1)
- return;
- while (((number % 2) == 0) && number > 1) // While number is even and > 1
- {
- number >>= 1;
- power++;
- }
- if (number == 1) // the previous number is a power of 2
- {
- change_to_number_node(child, power);
- if (flag == 1) // multiply
- parent->types.operation.op = SL;
- else if (flag == 2) // multiply and needs to move children nodes
- {
- parent->types.operation.op = SL;
- parent->children[0] = parent->children[1];
- parent->children[1] = child;
- }
- else if (flag == 3) // divide
- parent->types.operation.op = SR;
- }
-}
-
-
-/*---------------------------------------------------------------------------
* (function: check_intermediate_variable)
* check if there are intermediate variables
*-------------------------------------------------------------------------*/
diff --git a/ODIN_II/SRC/ast_util.cpp b/ODIN_II/SRC/ast_util.cpp
index 011a3aa..46b326b 100644
--- a/ODIN_II/SRC/ast_util.cpp
+++ b/ODIN_II/SRC/ast_util.cpp
@@ -325,76 +325,6 @@
return NULL;
}
-void resolve_concat_sizes(ast_node_t *concat_top, char *instance_name_prefix)
-{
- long i;
- if (concat_top->type == CONCATENATE)
- {
- for (i = 0; i < concat_top->num_children; i++)
- {
- resolve_concat_sizes(concat_top->children[i], instance_name_prefix);
- }
- }
- else if (concat_top->type == IDENTIFIERS)
- {
- ast_node_t *temp_node = resolve_node(NULL, instance_name_prefix, concat_top);
- if (temp_node != concat_top)
- {
- oassert(temp_node->type == NUMBERS);
- resolve_concat_sizes(temp_node, instance_name_prefix);
- free(temp_node);
- }
- else
- {
- char *temp_string = make_full_ref_name(NULL, NULL, NULL, concat_top->types.identifier, -1);
- long sc_spot;
- if ((sc_spot = sc_lookup_string(local_symbol_table_sc, temp_string)) == -1)
- {
- error_message(NETLIST_ERROR, concat_top->line_number, concat_top->file_number, "Missing declaration of this symbol %s\n", temp_string);
- }
- else
- {
- temp_node = ((ast_node_t*)local_symbol_table_sc->data[sc_spot]);
-
- if (temp_node->children[1] == NULL && temp_node->children[5] != NULL)
- {
- resolve_concat_sizes(temp_node->children[5], instance_name_prefix);
- }
- else
- {
- oassert(temp_node->children[3] == NULL);
- }
- }
- vtr::free(temp_string);
- }
- }
- else if (concat_top->type == BINARY_OPERATION || concat_top->type == UNARY_OPERATION)
- {
- for (i = 0; i < concat_top->num_children; i++)
- {
- resolve_concat_sizes(concat_top->children[i], instance_name_prefix);
- }
- }
- else if (concat_top->type == IF_Q)
- {
- /* check true/false expressions */
- resolve_concat_sizes(concat_top->children[1], instance_name_prefix);
- resolve_concat_sizes(concat_top->children[2], instance_name_prefix);
- }
- else if (concat_top->type == NUMBERS)
- {
- /* verify that the number that this represents is sized */
- if (!(concat_top->types.vnumber->is_defined_size()))
- {
- error_message(NETLIST_ERROR, concat_top->line_number, concat_top->file_number, "%s", "Unsized constants cannot be concatenated.\n");
- }
- }
- else if (!(concat_top->type == ARRAY_REF || concat_top->type == RANGE_REF))
- {
- error_message(NETLIST_ERROR, concat_top->line_number, concat_top->file_number, "%s", "Unsupported operation within a concatenation.\n");
- }
-}
-
/*---------------------------------------------------------------------------------------------
* (function: make_concat_into_list_of_strings)
* 0th idx will be the MSbit
@@ -885,14 +815,11 @@
if (node)
{
oassert(node->type != NO_ID);
- ast_node_t *node_copy;
- node_copy = ast_node_copy(node);
- node_copy->children = (ast_node_t **)vtr::calloc(node_copy->num_children,sizeof(ast_node_t*));
long i;
for (i = 0; i < node->num_children; i++)
{
- node_copy->children[i] = resolve_node(local_param_table_sc, module_name, node->children[i]);
+ node->children[i] = resolve_node(local_param_table_sc, module_name, node->children[i]);
}
ast_node_t *newNode = NULL;
@@ -900,22 +827,29 @@
case IDENTIFIERS:
{
- if(local_param_table_sc != NULL)
+ 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){
+ 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 = newNode;
+ return node;
}
}
}
break;
case UNARY_OPERATION:
- newNode = fold_unary(node_copy);
+ newNode = fold_unary(node);
break;
case BINARY_OPERATION:
- newNode = fold_binary(node_copy);
+ newNode = fold_binary(&node);
break;
default:
@@ -932,63 +866,6 @@
node = newNode;
}
-
- vtr::free(node_copy->children);
- vtr::free(node_copy);
- }
- return node;
-}
-
-/*----------------------------------------------------------------------------
- * (function: resolve_ast_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_ast_node(STRING_CACHE *local_param_table_sc, short initial, char *module_name, ast_node_t *node)
-{
- if (node)
- {
- ast_node_t *node_copy;
- node_copy = ast_node_copy(node);
- node_copy->children = (ast_node_t **)vtr::calloc(node_copy->num_children,sizeof(ast_node_t*));
-
- long i;
- for (i = 0; i < node->num_children; i++){
- node_copy->children[i] = resolve_ast_node(local_param_table_sc, initial, module_name, node->children[i]);
- }
- ast_node_t *newNode = NULL;
- switch (node->type){
-
- case UNARY_OPERATION:
- newNode = fold_unary(node_copy);
- break;
-
- case BINARY_OPERATION:
- newNode = fold_binary(node_copy);
- break;
-
- default:
- break;
- }
-
- if (node_is_ast_constant(newNode, local_param_table_sc)){
- newNode->shared_node = node->shared_node;
-
- /* clean up */
- if (node->type != IDENTIFIERS) {
- node = free_whole_tree(node);
- }
-
- node = newNode;
- }
-
- vtr::free(node_copy->children);
- vtr::free(node_copy);
}
return node;
}
@@ -1000,7 +877,7 @@
* Make a unique name for a module based on its parameter list
* e.g. for a "mod #(0,1,2,3) a(b,c,d)" instantiation you get name___0_1_2_3
*/
-char *make_module_param_name(STRING_CACHE *defines_for_module_sc, ast_node_t *module_param_list, char *module_name)
+char *make_module_param_name(STRING_CACHE */*defines_for_module_sc*/, ast_node_t *module_param_list, char *module_name)
{
char *module_param_name = (char*)vtr::malloc((strlen(module_name)+1024) * sizeof(char));
strcpy(module_param_name, module_name);
@@ -1012,10 +889,9 @@
strcat(module_param_name, "___");
for (i = 0; i < module_param_list->num_children; i++)
{
- if (module_param_list->children[i]->children[5])
+ ast_node_t *node = module_param_list->children[i]->children[5];
+ if (node && node->type == NUMBERS)
{
- ast_node_t *node = resolve_node(defines_for_module_sc, module_name, module_param_list->children[i]->children[5]);
- oassert(node->type == NUMBERS);
odin_sprintf(module_param_name, "%s_%ld", module_param_name, node->types.vnumber->get_value());
}
}
@@ -1097,6 +973,111 @@
return node_copy;
}
+/*---------------------------------------------------------------------------
+ * (function: expand_power)
+ * expand power operation into multiplication
+ *-------------------------------------------------------------------------*/
+static void expand_power(ast_node_t **node)
+{
+ /* create a node for this array reference */
+ ast_node_t* new_node = NULL;
+
+ ast_node_t *expression1 = (*node)->children[0];
+ ast_node_t *expression2 = (*node)->children[1];
+
+ /* allocate child nodes to this node */
+ int len = expression2->types.vnumber->get_value();
+ if (expression1->type == NUMBERS)
+ {
+ int len1 = expression1->types.vnumber->get_value();
+ long powRes = pow(len1, len);
+ new_node = create_tree_node_number(powRes, (*node)->line_number, (*node)->file_number);
+ }
+ else
+ {
+ if (len == 0)
+ {
+ new_node = create_tree_node_number(1L, (*node)->line_number, (*node)->file_number);
+ }
+ else
+ {
+ new_node = expression1;
+ for (int i=1; i < len; i++)
+ {
+ ast_node_t *temp_node = create_node_w_type(BINARY_OPERATION, (*node)->line_number, (*node)->file_number);
+ temp_node->types.operation.op = MULTIPLY;
+
+ allocate_children_to_node(temp_node, 2, ast_node_deep_copy(expression1), new_node);
+ new_node = temp_node;
+ }
+ }
+ }
+ //free_whole_tree(*node);
+ *node = new_node;
+}
+
+/*---------------------------------------------------------------------------
+ * (function: change_ast_node)
+ * check if the number is the power of 2
+ *-------------------------------------------------------------------------*/
+static void check_node_number(ast_node_t *parent, ast_node_t *child, int flag)
+{
+ long power = 0;
+ long number = child->types.vnumber->get_value();
+ if (number <= 1)
+ return;
+ while (((number % 2) == 0) && number > 1) // While number is even and > 1
+ {
+ number >>= 1;
+ power++;
+ }
+ if (number == 1) // the previous number is a power of 2
+ {
+ change_to_number_node(child, power);
+ if (flag == 1) // multiply
+ parent->types.operation.op = SL;
+ else if (flag == 2) // multiply and needs to move children nodes
+ {
+ parent->types.operation.op = SL;
+ parent->children[0] = parent->children[1];
+ parent->children[1] = child;
+ }
+ else if (flag == 3) // divide
+ parent->types.operation.op = SR;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * (function: change_ast_node)
+ * check the children nodes of an operation node
+ *-------------------------------------------------------------------------*/
+static void check_binary_operation(ast_node_t **node)
+{
+ if((*node) && (*node)->type == BINARY_OPERATION){
+ switch((*node)->types.operation.op){
+ case MULTIPLY:
+ if ((*node)->children[0]->type == IDENTIFIERS && (*node)->children[1]->type == NUMBERS)
+ check_node_number((*node), (*node)->children[1], 1); // 1 means multiply and don't need to move children nodes
+ if ((*node)->children[0]->type == NUMBERS && (*node)->children[1]->type == IDENTIFIERS)
+ check_node_number((*node), (*node)->children[0], 2); // 2 means multiply and needs to move children nodes
+ break;
+ case DIVIDE:
+ if (!node_is_constant((*node)->children[1]))
+ error_message(NETLIST_ERROR, (*node)->line_number, (*node)->file_number, "%s", "Odin only supports constant expressions as divisors\n");
+ if ((*node)->children[0]->type == IDENTIFIERS && (*node)->children[1]->type == NUMBERS)
+ check_node_number((*node), (*node)->children[1], 3); // 3 means divide
+ break;
+ case POWER:
+ if (!node_is_constant((*node)->children[1]))
+ error_message(NETLIST_ERROR, (*node)->line_number, (*node)->file_number, "%s", "Odin only supports constant expressions as exponents\n");
+ expand_power(node);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
/*---------------------------------------------------------------------------------------------
* (function: calculate_unary)
* TODO ! what does verilog say about !d'00001 ??
@@ -1172,30 +1153,35 @@
break;
}
- if(success){
+ if(success)
+ {
ast_node_t *new_num = create_tree_node_number(vresult, child_0->line_number, child_0->file_number);
return new_num;
}
}
+ else if (op_id == CLOG2)
+ {
+ /* $clog2() argument must be a constant expression */
+ error_message(PARSE_ERROR, node->line_number, current_parse_file, "%s", "Argument must be constant\n");
+ }
+
return NULL;
}
/*---------------------------------------------------------------------------------------------
* (function: calculate_binary)
*-------------------------------------------------------------------------------------------*/
-ast_node_t * fold_binary(ast_node_t *node)
+ast_node_t * fold_binary(ast_node_t **node)
{
- operation_list op_id = node->types.operation.op;
- ast_node_t *child_0 = node->children[0];
- ast_node_t *child_1 = node->children[1];
+ operation_list op_id = (*node)->types.operation.op;
+ ast_node_t *child_0 = (*node)->children[0];
+ ast_node_t *child_1 = (*node)->children[1];
if(node_is_constant(child_0) && node_is_constant(child_1))
{
short success = FALSE;
VNumber voperand_0 = *(child_0->types.vnumber);
VNumber voperand_1 = *(child_1->types.vnumber);
- // long size_0 = ;
- // long size_1;
VNumber vresult;
switch (op_id){
@@ -1214,6 +1200,11 @@
success = TRUE;
break;
+ case POWER:
+ vresult = V_POWER(voperand_0, voperand_1);
+ success = true;
+ break;
+
case DIVIDE:
vresult = V_DIV(voperand_0, voperand_1);
success = TRUE;
@@ -1324,11 +1315,17 @@
break;
}
- if(success){
+ if(success)
+ {
ast_node_t *new_num = create_tree_node_number(vresult, child_0->line_number, child_0->file_number);
return new_num;
}
}
+ else
+ {
+ check_binary_operation(node);
+ oassert(!((*node)->type == BINARY_OPERATION && (*node)->types.operation.op == POWER));
+ }
return NULL;
}
@@ -1346,43 +1343,6 @@
return NULL;
}
-/*---------------------------------------------------------------------------------------------
- * (function: node_is_ast_constant)
- *-------------------------------------------------------------------------------------------*/
-ast_node_t *node_is_ast_constant(ast_node_t *node){
- if (node &&
- (node_is_constant(node)
- || (node->types.variable.is_parameter == TRUE)
- || (node->type == UNARY_OPERATION && node_is_ast_constant(node->children[0]))
- || (node->type == BINARY_OPERATION && node_is_ast_constant(node->children[0]) && node_is_ast_constant(node->children[1]))))
- {
- return node;
- }
- return NULL;
-}
-
-/*---------------------------------------------------------------------------------------------
- * (function: node_is_ast_constant)
- *-------------------------------------------------------------------------------------------*/
-ast_node_t *node_is_ast_constant(ast_node_t *node, STRING_CACHE *defines_for_module_sc){
- if (node && (node_is_constant(node)
- || (node->types.variable.is_parameter == TRUE)
- || (node->type == UNARY_OPERATION && node_is_ast_constant(node->children[0], defines_for_module_sc))
- || (node->type == BINARY_OPERATION && node_is_ast_constant(node->children[0], defines_for_module_sc) && node_is_ast_constant(node->children[1], defines_for_module_sc))))
- {
- return node;
- }
- else if (node && node->type == IDENTIFIERS) {
- int sc_spot;
- if ((sc_spot = sc_lookup_string(defines_for_module_sc, node->types.identifier)) != -1
- && node_is_ast_constant((ast_node_t *)defines_for_module_sc->data[sc_spot]))
- {
- return node;
- }
- }
- return NULL;
-}
-
/*---------------------------------------------------------------------------
* (function: initial_node)
*-------------------------------------------------------------------------*/
diff --git a/ODIN_II/SRC/enum_str.cpp b/ODIN_II/SRC/enum_str.cpp
index 7834365..a044010 100644
--- a/ODIN_II/SRC/enum_str.cpp
+++ b/ODIN_II/SRC/enum_str.cpp
@@ -83,7 +83,7 @@
{"MULTIPLY", "MUL"}, // *
{"DIVIDE", "DIV"}, // /
{"MODULO", "MOD"}, // %
- {"OP_POW", "POW"}, // **
+ {"POWER", "POW"}, // **
{"LT", "LT"}, // <
{"GT", "GT"}, // >
{"LOGICAL_EQUAL", "lEQ"}, // ==
diff --git a/ODIN_II/SRC/include/ast_elaborate.h b/ODIN_II/SRC/include/ast_elaborate.h
index 06ca8ce..b5d5c53 100644
--- a/ODIN_II/SRC/include/ast_elaborate.h
+++ b/ODIN_II/SRC/include/ast_elaborate.h
@@ -77,11 +77,6 @@
void remove_para_node(ast_node_t *top, std::vector<ast_node_t *>para);
void change_para_node(ast_node_t *node, std::string name, long value);
void check_operation(enode *begin, enode *end);
-void shift_operation();
-void shift_operation(ast_node_t *ast_module);
-void search_certain_operation(ast_node_t *node);
-void check_binary_operation(ast_node_t *node);
-void check_node_number(ast_node_t *parent, ast_node_t *child, int flag);
bool check_mult_bracket(std::vector<int> list);
short has_intermediate_variable(ast_node_t *node);
diff --git a/ODIN_II/SRC/include/ast_util.h b/ODIN_II/SRC/include/ast_util.h
index a8d82d3..51f21ee 100644
--- a/ODIN_II/SRC/include/ast_util.h
+++ b/ODIN_II/SRC/include/ast_util.h
@@ -26,7 +26,6 @@
void free_assignement_of_node_keep_tree(ast_node_t *node);
char *make_module_param_name(STRING_CACHE *defines_for_module_sc, ast_node_t *module_param_list, char *module_name);
-void resolve_concat_sizes(ast_node_t *concat_top, char *instance_name_prefix);
void make_concat_into_list_of_strings(ast_node_t *concat_top, char *instance_name_prefix);
void change_to_number_node(ast_node_t *node, long number);
@@ -36,11 +35,8 @@
char_list_t *get_name_of_pins_with_prefix(ast_node_t *var_node, char *instance_name_prefix);
ast_node_t *resolve_node(STRING_CACHE *local_param_table_sc, char *module_name, ast_node_t *node);
-ast_node_t *resolve_ast_node(STRING_CACHE *local_param_table_sc, short initial, char *module_name, ast_node_t *node);
ast_node_t *node_is_constant(ast_node_t *node);
-ast_node_t *node_is_ast_constant(ast_node_t *node);
-ast_node_t *node_is_ast_constant(ast_node_t *node, STRING_CACHE *defines_for_module_sc);
-ast_node_t * fold_binary(ast_node_t *node);
+ast_node_t * fold_binary(ast_node_t **node);
ast_node_t *fold_unary(ast_node_t *node);
long clog2(long value_in, int length);
diff --git a/ODIN_II/SRC/include/odin_types.h b/ODIN_II/SRC/include/odin_types.h
index d848c2b..ad81d5b 100644
--- a/ODIN_II/SRC/include/odin_types.h
+++ b/ODIN_II/SRC/include/odin_types.h
@@ -256,7 +256,7 @@
MULTIPLY, // *
DIVIDE, // /
MODULO, // %
- OP_POW, // **
+ POWER, // **
LT, // <
GT, // >
LOGICAL_EQUAL, // ==
diff --git a/ODIN_II/SRC/netlist_create_from_ast.cpp b/ODIN_II/SRC/netlist_create_from_ast.cpp
index 8104bc7..ce51cd0 100644
--- a/ODIN_II/SRC/netlist_create_from_ast.cpp
+++ b/ODIN_II/SRC/netlist_create_from_ast.cpp
@@ -402,7 +402,7 @@
ast_node_t *module = (ast_node_t *)module_names_to_idx->data[sc_spot2];
ast_node_t *symbol_node = newSymbolNode(module_param_name, module->line_number);
ast_node_t* new_node = create_node_w_type(MODULE, module->line_number, module->file_number);
- allocate_children_to_node(new_node, 3, symbol_node, module->children[1], module->children[2]);
+ allocate_children_to_node(new_node, 3, symbol_node, module->children[1], ast_node_deep_copy(module->children[2]));
module->types.module.is_instantiated = TRUE;
new_node->types.module.index = i;
new_node->types.module.is_instantiated = TRUE;
@@ -934,8 +934,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);
break;
- case CONCATENATE:
- resolve_concat_sizes(node, instance_name_prefix);
default:
break;
}
@@ -1399,20 +1397,23 @@
ast_node_t *node_min = resolve_node(NULL, instance_name_prefix, var_declare->children[2]);
oassert(node_min->type == NUMBERS && node_max->type == NUMBERS);
- if(node_min->types.vnumber->get_value() > node_max->types.vnumber->get_value())
+ long max_value = node_max->types.vnumber->get_value();
+ long min_value = node_min->types.vnumber->get_value();
+
+ if(min_value > max_value)
{
error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "%s",
"Odin doesn't support arrays declared [m:n] where m is less than n.");
}
//ODIN doesn't support negative number in index now.
- if(node_min->types.vnumber->get_value() < 0 || node_max->types.vnumber->get_value() < 0)
+ if(min_value < 0 || max_value < 0)
{
warning_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "%s",
"Odin doesn't support negative number in index.");
}
/* assume digit 1 is largest */
- for (k = node_min->types.vnumber->get_value(); k <= node_max->types.vnumber->get_value(); k++)
+ for (k = min_value; k <= max_value; k++)
{
/* get the name of the pin */
full_name = make_full_ref_name(instance_name_prefix, NULL, NULL, var_declare->children[0]->types.identifier, k);
@@ -1488,14 +1489,18 @@
oassert(node_min2->type == NUMBERS && node_max2->type == NUMBERS);
oassert(node_min3->type == NUMBERS && node_max3->type == NUMBERS);
- if((node_min2->types.vnumber->get_value() > node_max2->types.vnumber->get_value())
- ||(node_min3->types.vnumber->get_value() > node_max3->types.vnumber->get_value()))
+ long addr_min = node_min2->types.vnumber->get_value();
+ long addr_max = node_max2->types.vnumber->get_value();
+
+ long addr_min1= node_min3->types.vnumber->get_value();
+ long addr_max1= node_max3->types.vnumber->get_value();
+
+ if((addr_min > addr_max) || (addr_min1 > addr_max1))
{
error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "%s",
"Odin doesn't support arrays declared [m:n] where m is less than n.");
}
- else if((node_min2->types.vnumber->get_value() < 0 || node_max2->types.vnumber->get_value() < 0)
- ||(node_min3->types.vnumber->get_value() < 0 || node_max3->types.vnumber->get_value() < 0))
+ else if((addr_min < 0 || addr_max < 0) || (addr_min1 < 0 || addr_max1 < 0))
{
error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "%s",
"Odin doesn't support negative number in index.");
@@ -1503,12 +1508,6 @@
char *name = var_declare->children[0]->types.identifier;
- long addr_min = node_min2->types.vnumber->get_value();
- long addr_max = node_max2->types.vnumber->get_value();
-
- long addr_min1= node_min3->types.vnumber->get_value();
- long addr_max1= node_max3->types.vnumber->get_value();
-
if (addr_min != 0 || addr_min1 != 0)
error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number,
"%s: right memory address index must be zero\n", name);
@@ -1519,9 +1518,7 @@
STRING_CACHE *local_param_table_sc;
sc_spot = sc_lookup_string(global_param_table_sc, instance_name_prefix);
oassert(sc_spot != -1);
- if (sc_spot != -1){
- local_param_table_sc = (STRING_CACHE *)global_param_table_sc->data[sc_spot];
- }
+ local_param_table_sc = (STRING_CACHE *)global_param_table_sc->data[sc_spot];
temp_string = make_chunk_size_name(instance_name_prefix, name);
@@ -1580,13 +1577,16 @@
/* FOR array driver since sport 3 and 4 are NULL */
oassert(node_min->type == NUMBERS && node_max->type == NUMBERS);
- if(node_min->types.vnumber->get_value() > node_max->types.vnumber->get_value())
+ long min_value = node_min->types.vnumber->get_value();
+ long max_value = node_max->types.vnumber->get_value();
+
+ if(min_value > max_value)
{
error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "%s",
"Odin doesn't support arrays declared [m:n] where m is less than n.");
}
//ODIN doesn't support negative number in index now.
- if(node_min->types.vnumber->get_value() < 0 || node_max->types.vnumber->get_value() < 0)
+ if(min_value < 0 || max_value < 0)
{
warning_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "%s",
"Odin doesn't support negative number in index.");
@@ -1600,7 +1600,7 @@
/* This register declaration is a range as opposed to a single bit so we need to define each element */
/* assume digit 1 is largest */
- for (i = node_min->types.vnumber->get_value(); i <= node_max->types.vnumber->get_value(); i++)
+ for (i = min_value; i <= max_value; i++)
{
/* create the net */
new_net = allocate_nnet();
@@ -1638,26 +1638,32 @@
ast_node_t *node_min2 = resolve_node(NULL, instance_name_prefix, var_declare->children[4]);
oassert(node_min1->type == NUMBERS && node_max1->type == NUMBERS);
- if(node_min1->types.vnumber->get_value() > node_max1->types.vnumber->get_value())
+ long data_min = node_min1->types.vnumber->get_value();
+ long data_max = node_max1->types.vnumber->get_value();
+
+ if(data_min > data_max)
{
error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "%s",
"Odin doesn't support arrays declared [m:n] where m is less than n.");
}
//ODIN doesn't support negative number in index now.
- if(node_min1->types.vnumber->get_value() < 0 || node_max1->types.vnumber->get_value() < 0)
+ if(data_min < 0 || data_max < 0)
{
warning_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "%s",
"Odin doesn't support negative number in index.");
}
oassert(node_min2->type == NUMBERS && node_max2->type == NUMBERS);
- if(node_min2->types.vnumber->get_value() > node_max2->types.vnumber->get_value())
+ long addr_min = node_min2->types.vnumber->get_value();
+ long addr_max = node_max2->types.vnumber->get_value();
+
+ if(addr_min > addr_max)
{
error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "%s",
"Odin doesn't support arrays declared [m:n] where m is less than n.");
}
//ODIN doesn't support negative number in index now.
- if(node_min2->types.vnumber->get_value() < 0 || node_max2->types.vnumber->get_value() < 0)
+ if(addr_min < 0 || addr_max < 0)
{
warning_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "%s",
"Odin doesn't support negative number in index.");
@@ -1665,18 +1671,12 @@
char *name = var_declare->children[0]->types.identifier;
- long data_min = node_min1->types.vnumber->get_value();
- long data_max = node_max1->types.vnumber->get_value();
-
if (data_min != 0)
error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number,
"%s: right memory index must be zero\n", name);
oassert(data_min <= data_max);
- long addr_min = node_min2->types.vnumber->get_value();
- long addr_max = node_max2->types.vnumber->get_value();
-
if (addr_min != 0)
error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number,
"%s: right memory address index must be zero\n", name);
@@ -1752,20 +1752,23 @@
ast_node_t *node_min = resolve_node(NULL, instance_name_prefix, var_declare->children[2]);
oassert(node_min->type == NUMBERS && node_max->type == NUMBERS);
- if(node_min->types.vnumber->get_value() > node_max->types.vnumber->get_value())
+ long min_value = node_min->types.vnumber->get_value();
+ long max_value = node_max->types.vnumber->get_value();
+
+ if(min_value > max_value)
{
error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "%s",
"Odin doesn't support arrays declared [m:n] where m is less than n.");
}
//ODIN doesn't support negative number in index now.
- if(node_min->types.vnumber->get_value() < 0 || node_max->types.vnumber->get_value() < 0)
+ if(min_value < 0 || max_value < 0)
{
warning_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "%s",
"Odin doesn't support negative number in index.");
}
/* assume digit 1 is largest */
- for (i = node_min->types.vnumber->get_value(); i <= node_max->types.vnumber->get_value(); i++)
+ for (i = min_value; i <= max_value; i++)
{
/* create the net */
new_net = allocate_nnet();
@@ -2951,7 +2954,7 @@
if ((sc_spot_input_new = sc_lookup_string(input_nets_sc, full_name)) == -1)
{
/* if this input is not yet used in this module then we'll add it */
- sc_spot_input_new = sc_add_string(input_nets_sc, full_name);
+ sc_spot_input_new = sc_add_string(input_nets_sc, full_name);
/* copy the pin to the old spot */
input_nets_sc->data[sc_spot_input_new] = input_nets_sc->data[sc_spot_input_old];
@@ -3352,8 +3355,6 @@
}
else
{
- // TODO Alex - this is temporary
- // if (right->type == BINARY_OPERATION || right->type == UNARY_OPERATION || right->type)
right = resolve_node(NULL, instance_name_prefix, right);
in_1 = netlist_expand_ast_of_module(right, instance_name_prefix);
@@ -4388,6 +4389,9 @@
signal_list_t *return_list;
nnode_t *if_node;
+ /* try to resolve constant expressions in condition */
+ if_ast->children[0] = resolve_node(NULL, instance_name_prefix, if_ast->children[0]);
+
/* create the node */
if_node = allocate_nnode();
/* store all the relevant info */
@@ -4445,6 +4449,9 @@
signal_list_t *return_list;
nnode_t *if_node;
+ /* try to resolve constant expressions in condition */
+ if_ast->children[0] = resolve_node(NULL, instance_name_prefix, if_ast->children[0]);
+
/* create the node */
if_node = allocate_nnode();
/* store all the relevant info */
diff --git a/ODIN_II/SRC/parse_making_ast.cpp b/ODIN_II/SRC/parse_making_ast.cpp
index ed23903..2d446d2 100644
--- a/ODIN_II/SRC/parse_making_ast.cpp
+++ b/ODIN_II/SRC/parse_making_ast.cpp
@@ -767,7 +767,6 @@
long sc_spot;
STRING_CACHE **this_defines_sc = NULL;
long this_num_modules = 0;
- const char *id_name = (id == PARAMETER) ? "Parameter" : "Localparam";
if (top_type == MODULE)
{
@@ -789,15 +788,6 @@
}
sc_spot = sc_add_string(this_defines_sc[this_num_modules], parameter->children[0]->types.identifier);
- ast_node_t *value = parameter->children[5];
-
- /* make sure that the parameter value is constant */
- if (!node_is_ast_constant(value, this_defines_sc[this_num_modules]))
- {
- error_message(PARSE_ERROR, parameter->children[5]->line_number, current_parse_file, "%s value must be constant\n", id_name);
- }
-
-
this_defines_sc[this_num_modules]->data[sc_spot] = (void*)parameter->children[5];
/* mark the node as shared so we don't delete it */
parameter->children[5]->shared_node = TRUE;
@@ -1019,63 +1009,14 @@
/* allocate child nodes to this node */
allocate_children_to_node(new_node, 2, expression1, expression2);
- /* see if this binary expression can have some constant folding */
- new_node = resolve_ast_node(defines_for_module_sc[num_modules-num_instances],TRUE,NULL,new_node);
-
return new_node;
}
-ast_node_t *newExpandPower(operation_list op_id, ast_node_t *expression1, ast_node_t *expression2, int line_number)
-{
- /* create a node for this array reference */
- ast_node_t* new_node, *node;
- ast_node_t *node_copy;
-
- /* avoid uninitialized warning */
- new_node = NULL;
-
- /* allocate child nodes to this node */
- if( expression2->type == NUMBERS ){
- int len = expression2->types.vnumber->get_value();
- if( expression1->type == NUMBERS ){
- int len1 = expression1->types.vnumber->get_value();
- long powRes = pow(len1, len);
- new_node = create_tree_node_number(powRes, line_number, current_parse_file);
- } else {
- if (len == 0){
- new_node = create_tree_node_number(1L, line_number, current_parse_file);
- } else {
- new_node = expression1;
- for(int i=1; i < len; ++i){
- node = create_node_w_type(BINARY_OPERATION, line_number, current_parse_file);
- node->types.operation.op = op_id;
-
- node_copy = ast_node_deep_copy(expression1);
-
- allocate_children_to_node(node, 2, node_copy, new_node);
- new_node = node;
- }
- }
- }
- }
- else
- {
- error_message(NETLIST_ERROR, line_number, current_parse_file, "%s", "Operation not supported by Odin\n");
- }
- /* see if this binary expression can have some constant folding */
- new_node = resolve_ast_node(defines_for_module_sc[num_modules-num_instances],TRUE,NULL,new_node);
-
- return new_node;
-}
/*---------------------------------------------------------------------------------------------
* (function: newUnaryOperation)
*-------------------------------------------------------------------------------------------*/
ast_node_t *newUnaryOperation(operation_list op_id, ast_node_t *expression, int line_number)
{
- /* $clog2() argument must be a constant expression */
- if (op_id == CLOG2 && !node_is_ast_constant(expression, defines_for_module_sc[num_modules-num_instances]))
- error_message(PARSE_ERROR, expression->line_number, current_parse_file, "%s", "Argument must be constant\n");
-
/* create a node for this array reference */
ast_node_t* new_node = create_node_w_type(UNARY_OPERATION, line_number, current_parse_file);
/* store the operation type */
@@ -1083,9 +1024,6 @@
/* allocate child nodes to this node */
allocate_children_to_node(new_node, 1, expression);
- /* see if this binary expression can have some constant folding */
- new_node = resolve_ast_node(defines_for_module_sc[num_modules-num_instances],TRUE,NULL,new_node);
-
return new_node;
}
@@ -1351,11 +1289,6 @@
symbol_node = NULL;
}
- if (expression && !node_is_ast_constant(expression, defines_for_module_sc[num_modules-num_instances]))
- {
- error_message(PARSE_ERROR, line_number, current_parse_file, "%s", "Parameter value must be constant\n");
- }
-
/* allocate child nodes to this node */
// leave 4 blank nodes so that expression is the 6th node to behave just like
// a default var_declare parameter (see create_symbol_table_for_module)
@@ -1909,10 +1842,6 @@
}
}
new_node = val->children[(val->num_children - 1)];
- if (!node_is_ast_constant(new_node->children[5], defines_for_module_sc[num_modules-num_instances]))
- {
- error_message(PARSE_ERROR, line_number, current_parse_file, "%s", "Parameter value must be constant\n");
- }
new_node->type = MODULE_PARAMETER;
new_node->types.variable.is_parameter = TRUE;
diff --git a/ODIN_II/SRC/verilog_bison.y b/ODIN_II/SRC/verilog_bison.y
index e98fde1..d79cab5 100644
--- a/ODIN_II/SRC/verilog_bison.y
+++ b/ODIN_II/SRC/verilog_bison.y
@@ -513,7 +513,7 @@
| '^' expression %prec UXOR {$$ = newUnaryOperation(BITWISE_XOR, $2, yylineno);}
| vCLOG2 '(' expression ')' {$$ = newUnaryOperation(CLOG2, $3, yylineno);}
| expression '^' expression {$$ = newBinaryOperation(BITWISE_XOR, $1, $3, yylineno);}
- | expression voPOWER expression {$$ = newExpandPower(MULTIPLY,$1, $3, yylineno);}
+ | expression voPOWER expression {$$ = newBinaryOperation(POWER,$1, $3, yylineno);}
| expression '*' expression {$$ = newBinaryOperation(MULTIPLY, $1, $3, yylineno);}
| expression '/' expression {$$ = newBinaryOperation(DIVIDE, $1, $3, yylineno);}
| expression '%' expression {$$ = newBinaryOperation(MODULO, $1, $3, yylineno);}
diff --git a/ODIN_II/regression_test/benchmark/micro/param_override_output b/ODIN_II/regression_test/benchmark/micro/param_override_output
index e157049..be67926 100644
--- a/ODIN_II/regression_test/benchmark/micro/param_override_output
+++ b/ODIN_II/regression_test/benchmark/micro/param_override_output
@@ -1,101 +1,101 @@
b1 b2 b3 b4
-0X09 0X0b 0X0a 0X3b
-0X3f 0X01 0X00 0X33
-0X04 0X06 0X05 0X37
+0X3b 0X3d 0X0a 0X3b
+0X33 0X35 0X00 0X33
+0X37 0X39 0X05 0X37
0X03 0X05 0X04 0X03
-0X21 0X23 0X22 0X1b
-0X09 0X0b 0X0a 0X3b
-0X2b 0X2d 0X2c 0X23
-0X1c 0X1e 0X1d 0X17
-0X26 0X28 0X27 0X1f
-0X17 0X19 0X18 0X13
-0X0d 0X0f 0X0e 0X0b
-0X2b 0X2d 0X2c 0X23
-0X1c 0X1e 0X1d 0X17
-0X09 0X0b 0X0a 0X3b
-0X1c 0X1e 0X1d 0X17
-0X17 0X19 0X18 0X13
+0X1b 0X1d 0X22 0X1b
+0X3b 0X3d 0X0a 0X3b
+0X23 0X25 0X2c 0X23
+0X17 0X19 0X1d 0X17
+0X1f 0X21 0X27 0X1f
+0X13 0X15 0X18 0X13
+0X0b 0X0d 0X0e 0X0b
+0X23 0X25 0X2c 0X23
+0X17 0X19 0X1d 0X17
+0X3b 0X3d 0X0a 0X3b
+0X17 0X19 0X1d 0X17
+0X13 0X15 0X18 0X13
0X03 0X05 0X04 0X03
-0X3a 0X3c 0X3b 0X2f
-0X2b 0X2d 0X2c 0X23
-0X2b 0X2d 0X2c 0X23
-0X2b 0X2d 0X2c 0X23
-0X1c 0X1e 0X1d 0X17
-0X0d 0X0f 0X0e 0X0b
-0X3a 0X3c 0X3b 0X2f
-0X0e 0X10 0X0f 0X3f
-0X0e 0X10 0X0f 0X3f
-0X21 0X23 0X22 0X1b
-0X21 0X23 0X22 0X1b
-0X04 0X06 0X05 0X37
-0X2b 0X2d 0X2c 0X23
-0X1c 0X1e 0X1d 0X17
-0X09 0X0b 0X0a 0X3b
-0X2b 0X2d 0X2c 0X23
-0X08 0X0a 0X09 0X07
-0X35 0X37 0X36 0X2b
-0X26 0X28 0X27 0X1f
-0X3a 0X3c 0X3b 0X2f
-0X35 0X37 0X36 0X2b
-0X26 0X28 0X27 0X1f
-0X3a 0X3c 0X3b 0X2f
-0X09 0X0b 0X0a 0X3b
+0X2f 0X31 0X3b 0X2f
+0X23 0X25 0X2c 0X23
+0X23 0X25 0X2c 0X23
+0X23 0X25 0X2c 0X23
+0X17 0X19 0X1d 0X17
+0X0b 0X0d 0X0e 0X0b
+0X2f 0X31 0X3b 0X2f
+0X3f 0X01 0X0f 0X3f
+0X3f 0X01 0X0f 0X3f
+0X1b 0X1d 0X22 0X1b
+0X1b 0X1d 0X22 0X1b
+0X37 0X39 0X05 0X37
+0X23 0X25 0X2c 0X23
+0X17 0X19 0X1d 0X17
+0X3b 0X3d 0X0a 0X3b
+0X23 0X25 0X2c 0X23
+0X07 0X09 0X09 0X07
+0X2b 0X2d 0X36 0X2b
+0X1f 0X21 0X27 0X1f
+0X2f 0X31 0X3b 0X2f
+0X2b 0X2d 0X36 0X2b
+0X1f 0X21 0X27 0X1f
+0X2f 0X31 0X3b 0X2f
+0X3b 0X3d 0X0a 0X3b
0X03 0X05 0X04 0X03
-0X09 0X0b 0X0a 0X3b
-0X35 0X37 0X36 0X2b
-0X1c 0X1e 0X1d 0X17
-0X12 0X14 0X13 0X0f
-0X2b 0X2d 0X2c 0X23
-0X30 0X32 0X31 0X27
-0X21 0X23 0X22 0X1b
-0X17 0X19 0X18 0X13
-0X12 0X14 0X13 0X0f
+0X3b 0X3d 0X0a 0X3b
+0X2b 0X2d 0X36 0X2b
+0X17 0X19 0X1d 0X17
+0X0f 0X11 0X13 0X0f
+0X23 0X25 0X2c 0X23
+0X27 0X29 0X31 0X27
+0X1b 0X1d 0X22 0X1b
+0X13 0X15 0X18 0X13
+0X0f 0X11 0X13 0X0f
0X03 0X05 0X04 0X03
-0X08 0X0a 0X09 0X07
-0X0d 0X0f 0X0e 0X0b
-0X3f 0X01 0X00 0X33
-0X09 0X0b 0X0a 0X3b
-0X0d 0X0f 0X0e 0X0b
-0X26 0X28 0X27 0X1f
-0X12 0X14 0X13 0X0f
+0X07 0X09 0X09 0X07
+0X0b 0X0d 0X0e 0X0b
+0X33 0X35 0X00 0X33
+0X3b 0X3d 0X0a 0X3b
+0X0b 0X0d 0X0e 0X0b
+0X1f 0X21 0X27 0X1f
+0X0f 0X11 0X13 0X0f
0X03 0X05 0X04 0X03
0X03 0X05 0X04 0X03
-0X1c 0X1e 0X1d 0X17
-0X2b 0X2d 0X2c 0X23
-0X2b 0X2d 0X2c 0X23
-0X3a 0X3c 0X3b 0X2f
-0X26 0X28 0X27 0X1f
-0X04 0X06 0X05 0X37
-0X08 0X0a 0X09 0X07
-0X17 0X19 0X18 0X13
+0X17 0X19 0X1d 0X17
+0X23 0X25 0X2c 0X23
+0X23 0X25 0X2c 0X23
+0X2f 0X31 0X3b 0X2f
+0X1f 0X21 0X27 0X1f
+0X37 0X39 0X05 0X37
+0X07 0X09 0X09 0X07
+0X13 0X15 0X18 0X13
0X03 0X05 0X04 0X03
-0X21 0X23 0X22 0X1b
-0X2b 0X2d 0X2c 0X23
-0X2b 0X2d 0X2c 0X23
-0X30 0X32 0X31 0X27
-0X09 0X0b 0X0a 0X3b
-0X0d 0X0f 0X0e 0X0b
-0X09 0X0b 0X0a 0X3b
-0X21 0X23 0X22 0X1b
-0X08 0X0a 0X09 0X07
-0X0d 0X0f 0X0e 0X0b
-0X08 0X0a 0X09 0X07
-0X17 0X19 0X18 0X13
-0X12 0X14 0X13 0X0f
-0X30 0X32 0X31 0X27
-0X3f 0X01 0X00 0X33
-0X0e 0X10 0X0f 0X3f
-0X17 0X19 0X18 0X13
-0X04 0X06 0X05 0X37
-0X17 0X19 0X18 0X13
-0X0d 0X0f 0X0e 0X0b
-0X3f 0X01 0X00 0X33
-0X30 0X32 0X31 0X27
-0X3a 0X3c 0X3b 0X2f
-0X1c 0X1e 0X1d 0X17
-0X04 0X06 0X05 0X37
-0X0e 0X10 0X0f 0X3f
-0X3f 0X01 0X00 0X33
-0X30 0X32 0X31 0X27
-0X0d 0X0f 0X0e 0X0b
-0X12 0X14 0X13 0X0f
+0X1b 0X1d 0X22 0X1b
+0X23 0X25 0X2c 0X23
+0X23 0X25 0X2c 0X23
+0X27 0X29 0X31 0X27
+0X3b 0X3d 0X0a 0X3b
+0X0b 0X0d 0X0e 0X0b
+0X3b 0X3d 0X0a 0X3b
+0X1b 0X1d 0X22 0X1b
+0X07 0X09 0X09 0X07
+0X0b 0X0d 0X0e 0X0b
+0X07 0X09 0X09 0X07
+0X13 0X15 0X18 0X13
+0X0f 0X11 0X13 0X0f
+0X27 0X29 0X31 0X27
+0X33 0X35 0X00 0X33
+0X3f 0X01 0X0f 0X3f
+0X13 0X15 0X18 0X13
+0X37 0X39 0X05 0X37
+0X13 0X15 0X18 0X13
+0X0b 0X0d 0X0e 0X0b
+0X33 0X35 0X00 0X33
+0X27 0X29 0X31 0X27
+0X2f 0X31 0X3b 0X2f
+0X17 0X19 0X1d 0X17
+0X37 0X39 0X05 0X37
+0X3f 0X01 0X0f 0X3f
+0X33 0X35 0X00 0X33
+0X27 0X29 0X31 0X27
+0X0b 0X0d 0X0e 0X0b
+0X0f 0X11 0X13 0X0f