mirror of https://github.com/YosysHQ/yosys.git
sv: support remaining assignment operators
- Add support for: *=, /=, %=, <<=, >>=, <<<=, >>>= - Unify existing support for: +=, -=, &=, |=, ^=
This commit is contained in:
parent
3514c92dc4
commit
15f35d6754
|
@ -544,11 +544,18 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ {
|
||||||
|
|
||||||
".*" { return TOK_WILDCARD_CONNECT; }
|
".*" { return TOK_WILDCARD_CONNECT; }
|
||||||
|
|
||||||
"|=" { SV_KEYWORD(TOK_OR_ASSIGN); }
|
"|=" { SV_KEYWORD(TOK_BIT_OR_ASSIGN); }
|
||||||
"&=" { SV_KEYWORD(TOK_AND_ASSIGN); }
|
"&=" { SV_KEYWORD(TOK_BIT_AND_ASSIGN); }
|
||||||
"+=" { SV_KEYWORD(TOK_PLUS_ASSIGN); }
|
"+=" { SV_KEYWORD(TOK_ADD_ASSIGN); }
|
||||||
"-=" { SV_KEYWORD(TOK_SUB_ASSIGN); }
|
"-=" { SV_KEYWORD(TOK_SUB_ASSIGN); }
|
||||||
"^=" { SV_KEYWORD(TOK_XOR_ASSIGN); }
|
"^=" { SV_KEYWORD(TOK_BIT_XOR_ASSIGN); }
|
||||||
|
"/=" { SV_KEYWORD(TOK_DIV_ASSIGN); }
|
||||||
|
"%=" { SV_KEYWORD(TOK_MOD_ASSIGN); }
|
||||||
|
"*=" { SV_KEYWORD(TOK_MUL_ASSIGN); }
|
||||||
|
"<<=" { SV_KEYWORD(TOK_SHL_ASSIGN); }
|
||||||
|
">>=" { SV_KEYWORD(TOK_SHR_ASSIGN); }
|
||||||
|
"<<<=" { SV_KEYWORD(TOK_SSHL_ASSIGN); }
|
||||||
|
">>>=" { SV_KEYWORD(TOK_SSHR_ASSIGN); }
|
||||||
|
|
||||||
[-+]?[=*]> {
|
[-+]?[=*]> {
|
||||||
if (!specify_mode) REJECT;
|
if (!specify_mode) REJECT;
|
||||||
|
|
|
@ -260,6 +260,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
|
||||||
bool boolean;
|
bool boolean;
|
||||||
char ch;
|
char ch;
|
||||||
int integer;
|
int integer;
|
||||||
|
YOSYS_NAMESPACE_PREFIX AST::AstNodeType ast_node_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
%token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE
|
%token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE
|
||||||
|
@ -272,7 +273,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
|
||||||
%token TOK_PACKAGE TOK_ENDPACKAGE TOK_PACKAGESEP
|
%token TOK_PACKAGE TOK_ENDPACKAGE TOK_PACKAGESEP
|
||||||
%token TOK_INTERFACE TOK_ENDINTERFACE TOK_MODPORT TOK_VAR TOK_WILDCARD_CONNECT
|
%token TOK_INTERFACE TOK_ENDINTERFACE TOK_MODPORT TOK_VAR TOK_WILDCARD_CONNECT
|
||||||
%token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_WAND TOK_WOR TOK_REG TOK_LOGIC
|
%token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_WAND TOK_WOR TOK_REG TOK_LOGIC
|
||||||
%token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_PLUS_ASSIGN TOK_ALWAYS TOK_INITIAL
|
%token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL
|
||||||
%token TOK_ALWAYS_FF TOK_ALWAYS_COMB TOK_ALWAYS_LATCH
|
%token TOK_ALWAYS_FF TOK_ALWAYS_COMB TOK_ALWAYS_LATCH
|
||||||
%token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT
|
%token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT
|
||||||
%token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR TOK_AUTOMATIC
|
%token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR TOK_AUTOMATIC
|
||||||
|
@ -286,7 +287,9 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
|
||||||
%token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY
|
%token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY
|
||||||
%token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_UNIQUE0 TOK_PRIORITY
|
%token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_UNIQUE0 TOK_PRIORITY
|
||||||
%token TOK_STRUCT TOK_PACKED TOK_UNSIGNED TOK_INT TOK_BYTE TOK_SHORTINT TOK_LONGINT TOK_UNION
|
%token TOK_STRUCT TOK_PACKED TOK_UNSIGNED TOK_INT TOK_BYTE TOK_SHORTINT TOK_LONGINT TOK_UNION
|
||||||
%token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN
|
%token TOK_BIT_OR_ASSIGN TOK_BIT_AND_ASSIGN TOK_BIT_XOR_ASSIGN TOK_ADD_ASSIGN
|
||||||
|
%token TOK_SUB_ASSIGN TOK_DIV_ASSIGN TOK_MOD_ASSIGN TOK_MUL_ASSIGN
|
||||||
|
%token TOK_SHL_ASSIGN TOK_SHR_ASSIGN TOK_SSHL_ASSIGN TOK_SSHR_ASSIGN
|
||||||
|
|
||||||
%type <ast> range range_or_multirange non_opt_range non_opt_multirange
|
%type <ast> range range_or_multirange non_opt_range non_opt_multirange
|
||||||
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type
|
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type
|
||||||
|
@ -298,6 +301,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
|
||||||
%type <integer> integer_atom_type
|
%type <integer> integer_atom_type
|
||||||
%type <al> attr case_attr
|
%type <al> attr case_attr
|
||||||
%type <ast> struct_union
|
%type <ast> struct_union
|
||||||
|
%type <ast_node_type> asgn_binop
|
||||||
|
|
||||||
%type <specify_target_ptr> specify_target
|
%type <specify_target_ptr> specify_target
|
||||||
%type <specify_triple_ptr> specify_triple specify_opt_triple
|
%type <specify_triple_ptr> specify_triple specify_opt_triple
|
||||||
|
@ -2449,47 +2453,35 @@ simple_behavioral_stmt:
|
||||||
SET_AST_NODE_LOC(node, @2, @5);
|
SET_AST_NODE_LOC(node, @2, @5);
|
||||||
append_attr(node, $1);
|
append_attr(node, $1);
|
||||||
} |
|
} |
|
||||||
attr lvalue TOK_XOR_ASSIGN delay expr {
|
attr lvalue asgn_binop delay expr {
|
||||||
AstNode *xor_node = new AstNode(AST_BIT_XOR, $2->clone(), $5);
|
AstNode *expr_node = $5;
|
||||||
AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, xor_node);
|
if ($3 == AST_SHIFT_LEFT || $3 == AST_SHIFT_RIGHT ||
|
||||||
SET_AST_NODE_LOC(xor_node, @2, @5);
|
$3 == AST_SHIFT_SLEFT || $3 == AST_SHIFT_SRIGHT) {
|
||||||
|
expr_node = new AstNode(AST_TO_UNSIGNED, expr_node);
|
||||||
|
SET_AST_NODE_LOC(expr_node, @5, @5);
|
||||||
|
}
|
||||||
|
AstNode *op_node = new AstNode($3, $2->clone(), expr_node);
|
||||||
|
AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, op_node);
|
||||||
|
SET_AST_NODE_LOC(op_node, @2, @5);
|
||||||
SET_AST_NODE_LOC(node, @2, @5);
|
SET_AST_NODE_LOC(node, @2, @5);
|
||||||
ast_stack.back()->children.push_back(node);
|
ast_stack.back()->children.push_back(node);
|
||||||
append_attr(node, $1);
|
append_attr(node, $1);
|
||||||
} |
|
|
||||||
attr lvalue TOK_OR_ASSIGN delay expr {
|
|
||||||
AstNode *or_node = new AstNode(AST_BIT_OR, $2->clone(), $5);
|
|
||||||
SET_AST_NODE_LOC(or_node, @2, @5);
|
|
||||||
AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, or_node);
|
|
||||||
SET_AST_NODE_LOC(node, @2, @5);
|
|
||||||
ast_stack.back()->children.push_back(node);
|
|
||||||
append_attr(node, $1);
|
|
||||||
} |
|
|
||||||
attr lvalue TOK_PLUS_ASSIGN delay expr {
|
|
||||||
AstNode *add_node = new AstNode(AST_ADD, $2->clone(), $5);
|
|
||||||
AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, add_node);
|
|
||||||
SET_AST_NODE_LOC(node, @2, @5);
|
|
||||||
SET_AST_NODE_LOC(add_node, @2, @5);
|
|
||||||
ast_stack.back()->children.push_back(node);
|
|
||||||
append_attr(node, $1);
|
|
||||||
} |
|
|
||||||
attr lvalue TOK_SUB_ASSIGN delay expr {
|
|
||||||
AstNode *sub_node = new AstNode(AST_SUB, $2->clone(), $5);
|
|
||||||
AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, sub_node);
|
|
||||||
SET_AST_NODE_LOC(node, @2, @5);
|
|
||||||
SET_AST_NODE_LOC(sub_node, @2, @5);
|
|
||||||
ast_stack.back()->children.push_back(node);
|
|
||||||
append_attr(node, $1);
|
|
||||||
} |
|
|
||||||
attr lvalue TOK_AND_ASSIGN delay expr {
|
|
||||||
AstNode *and_node = new AstNode(AST_BIT_AND, $2->clone(), $5);
|
|
||||||
AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, and_node);
|
|
||||||
SET_AST_NODE_LOC(node, @2, @5);
|
|
||||||
SET_AST_NODE_LOC(and_node, @2, @5);
|
|
||||||
ast_stack.back()->children.push_back(node);
|
|
||||||
append_attr(node, $1);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
asgn_binop:
|
||||||
|
TOK_BIT_OR_ASSIGN { $$ = AST_BIT_OR; } |
|
||||||
|
TOK_BIT_AND_ASSIGN { $$ = AST_BIT_AND; } |
|
||||||
|
TOK_BIT_XOR_ASSIGN { $$ = AST_BIT_XOR; } |
|
||||||
|
TOK_ADD_ASSIGN { $$ = AST_ADD; } |
|
||||||
|
TOK_SUB_ASSIGN { $$ = AST_SUB; } |
|
||||||
|
TOK_DIV_ASSIGN { $$ = AST_DIV; } |
|
||||||
|
TOK_MOD_ASSIGN { $$ = AST_MOD; } |
|
||||||
|
TOK_MUL_ASSIGN { $$ = AST_MUL; } |
|
||||||
|
TOK_SHL_ASSIGN { $$ = AST_SHIFT_LEFT; } |
|
||||||
|
TOK_SHR_ASSIGN { $$ = AST_SHIFT_RIGHT; } |
|
||||||
|
TOK_SSHL_ASSIGN { $$ = AST_SHIFT_SLEFT; } |
|
||||||
|
TOK_SSHR_ASSIGN { $$ = AST_SHIFT_SRIGHT; } ;
|
||||||
|
|
||||||
// this production creates the obligatory if-else shift/reduce conflict
|
// this production creates the obligatory if-else shift/reduce conflict
|
||||||
behavioral_stmt:
|
behavioral_stmt:
|
||||||
defattr | assert | wire_decl | param_decl | localparam_decl | typedef_decl |
|
defattr | assert | wire_decl | param_decl | localparam_decl | typedef_decl |
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
`define TEST(name, asgnop)\
|
||||||
|
module test_``name ( \
|
||||||
|
input logic [3:0] a, b, \
|
||||||
|
output logic [3:0] c \
|
||||||
|
); \
|
||||||
|
always @* begin \
|
||||||
|
c = a; \
|
||||||
|
c asgnop b; \
|
||||||
|
end \
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`TEST(add, +=)
|
||||||
|
`TEST(sub, -=)
|
||||||
|
`TEST(mul, *=)
|
||||||
|
`TEST(div, /=)
|
||||||
|
`TEST(mod, %=)
|
||||||
|
`TEST(bit_and, &=)
|
||||||
|
`TEST(bit_or , |=)
|
||||||
|
`TEST(bit_xor, ^=)
|
||||||
|
`TEST(shl, <<=)
|
||||||
|
`TEST(shr, >>=)
|
||||||
|
`TEST(sshl, <<<=)
|
||||||
|
`TEST(sshr, >>>=)
|
Loading…
Reference in New Issue