diff --git a/ODIN_II/README.rst b/ODIN_II/README.rst index dcd7fd33749..a9804850904 100644 --- a/ODIN_II/README.rst +++ b/ODIN_II/README.rst @@ -309,8 +309,10 @@ Verilog Synthesizable Keyword Support: +-------------------+------------------+---------------------+--------------------+ | macromodule | | | | +-------------------+------------------+---------------------+--------------------+ - - +| +: | | | | ++-------------------+------------------+---------------------+--------------------+ +| -: | | | | ++-------------------+------------------+---------------------+--------------------+ Verilog NON-Synthesizable Keyword Support: ********************************* diff --git a/ODIN_II/SRC/include/ast_util.h b/ODIN_II/SRC/include/ast_util.h index 458f6215c1a..0e773c2498a 100644 --- a/ODIN_II/SRC/include/ast_util.h +++ b/ODIN_II/SRC/include/ast_util.h @@ -24,6 +24,7 @@ void make_concat_into_list_of_strings(ast_node_t *concat_top, char *instance_nam void change_to_number_node(ast_node_t *node, long number); int get_range(ast_node_t* first_node); + char *get_name_of_pin_at_bit(ast_node_t *var_node, int bit, char *instance_name_prefix); char *get_name_of_var_declare_at_bit(ast_node_t *var_declare, int bit); char_list_t *get_name_of_pins(ast_node_t *var_node, char *instance_name_prefix); diff --git a/ODIN_II/SRC/include/parse_making_ast.h b/ODIN_II/SRC/include/parse_making_ast.h index 7ff8d14f5ef..53c458b3732 100644 --- a/ODIN_II/SRC/include/parse_making_ast.h +++ b/ODIN_II/SRC/include/parse_making_ast.h @@ -21,6 +21,8 @@ ast_node_t *markAndProcessSymbolListWith(ids top_type, ids id, ast_node_t *symbo ast_node_t *newArrayRef(char *id, ast_node_t *expression, int line_number); ast_node_t *newArrayRef2D(char *id, ast_node_t *expression1, ast_node_t *expression2, int line_number); ast_node_t *newRangeRef(char *id, ast_node_t *expression1, ast_node_t *expression2, int line_number); +ast_node_t *newPartSelectRangeRef(char *id, ast_node_t *expression1, ast_node_t *expression2, char direction, + int line_number); ast_node_t *newRangeRef2D(char *id, ast_node_t *expression1, ast_node_t *expression2, ast_node_t *expression3, ast_node_t *expression4, int line_number); ast_node_t *newBinaryOperation(operation_list op_id, ast_node_t *expression1, ast_node_t *expression2, int line_number); ast_node_t *newExpandPower(operation_list op_id, ast_node_t *expression1, ast_node_t *expression2, int line_number); diff --git a/ODIN_II/SRC/parse_making_ast.cpp b/ODIN_II/SRC/parse_making_ast.cpp index 2e75cd1b116..67074ca648c 100644 --- a/ODIN_II/SRC/parse_making_ast.cpp +++ b/ODIN_II/SRC/parse_making_ast.cpp @@ -835,6 +835,54 @@ ast_node_t *newRangeRef(char *id, ast_node_t *expression1, ast_node_t *expressio return new_node; } + +/*--------------------------------------------------------------------------------------------- + * (function: newPartSelectRangeRef) + *-------------------------------------------------------------------------------------------*/ +ast_node_t *newPartSelectRangeRef(char *id, ast_node_t *expression1, ast_node_t *expression2, char direction, + int line_number) +{ + + long sc_spot; + + oassert(expression1 != NULL && expression1->type == NUMBERS && expression2 != NULL && expression2->type == NUMBERS); + + /* Try to find the original array to check low/high indices */ + if ((sc_spot = sc_lookup_string(modules_inputs_sc, id)) == -1 && + (sc_spot = sc_lookup_string(modules_outputs_sc, id)) == -1){ + error_message(PARSE_ERROR, line_number, current_parse_file, "Could not find variable %s", id); + return nullptr; + } + ast_node_t *original_range = (ast_node_t *) modules_inputs_sc->data[sc_spot];; + long upper_limit = original_range->children[1]->types.number.value; + long bottom_limit = original_range->children[2]->types.number.value; + if (expression1->types.number.value < 0 || expression2->types.number.value < 0){ + + /* Negetive numbers are not supported */ + error_message(PARSE_ERROR, line_number, current_parse_file, + "Odin doesn't support negative number in index : %s[%d%s%d].", id, + expression1->types.number.value, direction == 1 ? "+:" : "-:", + expression2->types.number.value); + } + + if (direction == 1){ + expression1->types.number.value = expression1->types.number.value + expression2->types.number.value - 1; + expression2->types.number.value = expression1->types.number.value - expression2->types.number.value + 1; + } + else{ + expression2->types.number.value = expression1->types.number.value - expression2->types.number.value + 1; + } + if (expression1->types.number.value > upper_limit || expression2->types.number.value < bottom_limit) { + /* out of original range */ + error_message(PARSE_ERROR, line_number,current_parse_file, + "This part-select range %s:[%d%s%d] is out of range. It should be in the %s:[%d:%d] range.", + id,expression1->types.number.value, direction ==1 ? "+:" : "-:",expression2->types.number.value, + id,upper_limit,bottom_limit ); + } + + return newRangeRef(id, expression1, expression2, line_number); +} + /*--------------------------------------------------------------------------------------------- * (function: newBinaryOperation) *-------------------------------------------------------------------------------------------*/ diff --git a/ODIN_II/SRC/verilog_bison.y b/ODIN_II/SRC/verilog_bison.y index 37aca290805..4ae437febf9 100644 --- a/ODIN_II/SRC/verilog_bison.y +++ b/ODIN_II/SRC/verilog_bison.y @@ -65,7 +65,8 @@ int yylex(void); %token vOUTPUT vPARAMETER vPOSEDGE vREG vWIRE vXNOR vXOR vDEFPARAM voANDAND %token voOROR voLTE voGTE voPAL voSLEFT voSRIGHT vo ASRIGHT voEQUAL voNOTEQUAL voCASEEQUAL %token voCASENOTEQUAL voXNOR voNAND voNOR vWHILE vINTEGER -%token vNOT_SUPPORT +%token vNOT_SUPPORT +%token vPLUS_COLON vMINUS_COLON %token '?' ':' '|' '^' '&' '<' '>' '+' '-' '*' '/' '%' '(' ')' '{' '}' '[' ']' %right '?' ':' @@ -510,6 +511,8 @@ primary: | vSYMBOL_ID {$$ = newSymbolNode($1, yylineno);} | vSYMBOL_ID '[' expression ']' {$$ = newArrayRef($1, $3, yylineno);} | vSYMBOL_ID '[' expression ']' '[' expression ']' {$$ = newArrayRef2D($1, $3, $6, yylineno);} + | vSYMBOL_ID '[' expression vPLUS_COLON expression ']' {$$ = newPartSelectRangeRef($1, $3, $5, 1, yylineno);} + | vSYMBOL_ID '[' expression vMINUS_COLON expression ']' {$$ = newPartSelectRangeRef($1, $3, $5, -1, yylineno);} | vSYMBOL_ID '[' expression ':' expression ']' {$$ = newRangeRef($1, $3, $5, yylineno);} | vSYMBOL_ID '[' expression ':' expression ']' '[' expression ':' expression ']' {$$ = newRangeRef2D($1, $3, $5, $8, $10, yylineno);} | '{' probable_expression_list '}' {$$ = $2; ($2)->types.concat.num_bit_strings = -1;} diff --git a/ODIN_II/SRC/verilog_flex.l b/ODIN_II/SRC/verilog_flex.l index b1979a38d9c..74215b64c21 100644 --- a/ODIN_II/SRC/verilog_flex.l +++ b/ODIN_II/SRC/verilog_flex.l @@ -175,11 +175,12 @@ char* standardize_number(const char* input); "~^" { MP; return voXNOR;} "~&" { MP; return voNAND;} "~|" { MP; return voNOR;} +"+:" { MP; return vPLUS_COLON;} +"-:" { MP; return vMINUS_COLON;} /* unsupported Operators */ "&&&" { MP; return vNOT_SUPPORT;} -"+:" { MP; return vNOT_SUPPORT;} -"-:" { MP; return vNOT_SUPPORT;} + /* operands */ diff --git a/ODIN_II/regression_test/benchmark/operators/minuscolon_6_bit.v b/ODIN_II/regression_test/benchmark/operators/minuscolon_6_bit.v new file mode 100644 index 00000000000..d6a3196eee9 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/operators/minuscolon_6_bit.v @@ -0,0 +1,11 @@ +module OR2in (A,B,C1,C2); + +input [5:0] A ; +input [5:0] B ; +output [2:0] C1 ; +output [2:0] C2 ; + +assign C1=A[2-:3] | B[2-:3] ; +assign C2=A[5-:3] | B[5-:3] ; + +endmodule diff --git a/ODIN_II/regression_test/benchmark/operators/minuscolon_6_bit_input b/ODIN_II/regression_test/benchmark/operators/minuscolon_6_bit_input new file mode 100644 index 00000000000..4f386527d78 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/operators/minuscolon_6_bit_input @@ -0,0 +1,12 @@ +GLOBAL_SIM_BASE_CLK A B +0 0X20 0X26 +0 0X2C 0X16 +0 0X3C 0X36 +0 0X22 0X06 +0 0X24 0X20 +0 0X01 0X06 +0 0X0C 0X07 +0 0X01 0X26 +0 0X21 0X06 +0 0X0C 0X26 + diff --git a/ODIN_II/regression_test/benchmark/operators/minuscolon_6_bit_output b/ODIN_II/regression_test/benchmark/operators/minuscolon_6_bit_output new file mode 100644 index 00000000000..e9d2c31982b --- /dev/null +++ b/ODIN_II/regression_test/benchmark/operators/minuscolon_6_bit_output @@ -0,0 +1,11 @@ +C1 C2 +0X06 0X04 +0X06 0X07 +0X06 0X07 +0X06 0X04 +0x04 0x04 +0x07 0x00 +0x07 0x01 +0x07 0x04 +0x07 0x04 +0x06 0x05 diff --git a/ODIN_II/regression_test/benchmark/operators/pluscolon_6_bit.v b/ODIN_II/regression_test/benchmark/operators/pluscolon_6_bit.v new file mode 100644 index 00000000000..c994efec261 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/operators/pluscolon_6_bit.v @@ -0,0 +1,11 @@ +module And2in (A,B,C1,C2); + +input [5:0] A ; +input [5:0] B ; +output [2:0] C1 ; +output [2:0] C2 ; + +assign C1 = A[0+:3] & B[0+:3] ; +assign C2 = A[-3+:3] & B[3+:3] ; + +endmodule diff --git a/ODIN_II/regression_test/benchmark/operators/pluscolon_6_bit_input b/ODIN_II/regression_test/benchmark/operators/pluscolon_6_bit_input new file mode 100644 index 00000000000..2ed46340d53 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/operators/pluscolon_6_bit_input @@ -0,0 +1,5 @@ +GLOBAL_SIM_BASE_CLK A B +0 0X27 0X1A +0 0X28 0X32 +0 0X10 0X3F +0 0X1D 0X3F diff --git a/ODIN_II/regression_test/benchmark/operators/pluscolon_6_bit_output b/ODIN_II/regression_test/benchmark/operators/pluscolon_6_bit_output new file mode 100644 index 00000000000..e9d674d9e37 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/operators/pluscolon_6_bit_output @@ -0,0 +1,7 @@ +C1 C2 +0X2 0X0 +0X0 0X4 +0X0 0X2 +0X5 0X3 + + diff --git a/ODIN_II/regression_test/benchmark/operators/pluscolon_8_bit.v b/ODIN_II/regression_test/benchmark/operators/pluscolon_8_bit.v new file mode 100644 index 00000000000..da2869ff99c --- /dev/null +++ b/ODIN_II/regression_test/benchmark/operators/pluscolon_8_bit.v @@ -0,0 +1,11 @@ +module And2in (A,B,C1,C2); + +input [7:0] A ; +input [7:0] B ; +output [3:0] C1 ; +output [3:0] C2 ; + +assign C1=A[0+:4] & B[0+:4] ; +assign C2=A[3+:5] & B[3+:5] ; + +endmodule diff --git a/ODIN_II/regression_test/benchmark/operators/pluscolon_8_bit_input b/ODIN_II/regression_test/benchmark/operators/pluscolon_8_bit_input new file mode 100644 index 00000000000..296b68a0660 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/operators/pluscolon_8_bit_input @@ -0,0 +1,11 @@ +GLOBAL_SIM_BASE_CLK A B +0 0X60 0XA6 +0 0XEC 0X16 +0 0XBC 0XB6 +0 0X62 0X46 +0 0XE4 0X20 +0 0X01 0X86 +0 0XCC 0X47 +0 0X41 0XE6 +0 0XE1 0X06 +0 0XCC 0XE6 \ No newline at end of file diff --git a/ODIN_II/regression_test/benchmark/operators/pluscolon_8_bit_output b/ODIN_II/regression_test/benchmark/operators/pluscolon_8_bit_output new file mode 100644 index 00000000000..7b24334b3fc --- /dev/null +++ b/ODIN_II/regression_test/benchmark/operators/pluscolon_8_bit_output @@ -0,0 +1,12 @@ +C1 C2 +0X0 0X4 +0X4 0X0 +0X4 0X6 +0X2 0X8 +0X0 0X4 +0X0 0X0 +0X4 0X8 +0X0 0X8 +0X0 0X0 +0X4 0X8 + diff --git a/doc/src/odin/index.rst b/doc/src/odin/index.rst index 22b4f83c5a1..a34ace03420 100644 --- a/doc/src/odin/index.rst +++ b/doc/src/odin/index.rst @@ -309,6 +309,11 @@ Verilog Synthesizable Keyword Support: +-------------------+------------------+---------------------+--------------------+ | macromodule | | | | +-------------------+------------------+---------------------+--------------------+ +| +: | | | | ++-------------------+------------------+---------------------+--------------------+ +| -: | | | | ++-------------------+------------------+---------------------+--------------------+ + Verilog NON-Synthesizable Keyword Support: