diff options
Diffstat (limited to 'frontends/verilog')
-rw-r--r-- | frontends/verilog/preproc.cc | 2 | ||||
-rw-r--r-- | frontends/verilog/verilog_lexer.l | 8 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 49 |
3 files changed, 47 insertions, 12 deletions
diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 7e107dc26..161253a99 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -28,7 +28,7 @@ * * Ad-hoc implementation of a Verilog preprocessor. The directives `define, * `include, `ifdef, `ifndef, `else and `endif are handled here. All other - * directives are handled by the lexer (see lexer.l). + * directives are handled by the lexer (see verilog_lexer.l). * */ diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 4acfb414d..ca23df3e8 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -28,7 +28,7 @@ * * A simple lexer for Verilog code. Non-preprocessor compiler directives are * handled here. The preprocessor stuff is handled in preproc.cc. Everything - * else is left to the bison parser (see parser.y). + * else is left to the bison parser (see verilog_parser.y). * */ @@ -188,9 +188,9 @@ YOSYS_NAMESPACE_END "unique0" { SV_KEYWORD(TOK_UNIQUE); } "priority" { SV_KEYWORD(TOK_PRIORITY); } -"always_comb" { SV_KEYWORD(TOK_ALWAYS); } -"always_ff" { SV_KEYWORD(TOK_ALWAYS); } -"always_latch" { SV_KEYWORD(TOK_ALWAYS); } +"always_comb" { SV_KEYWORD(TOK_ALWAYS_COMB); } +"always_ff" { SV_KEYWORD(TOK_ALWAYS_FF); } +"always_latch" { SV_KEYWORD(TOK_ALWAYS_LATCH); } /* use special token for labels on assert, assume, cover, and restrict because it's insanley complex to fix parsing of cells otherwise. (the current cell parser forces a reduce very early to update some diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 77f6d2051..a30935e0a 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -141,6 +141,7 @@ struct specify_rise_fall { %token TOK_INTERFACE TOK_ENDINTERFACE TOK_MODPORT TOK_VAR %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_ALWAYS TOK_INITIAL +%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_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR TOK_AUTOMATIC %token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT @@ -156,7 +157,7 @@ struct specify_rise_fall { %type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int %type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id -%type <boolean> opt_signed opt_property unique_case_attr +%type <boolean> opt_signed opt_property unique_case_attr always_comb_or_latch always_or_always_ff %type <al> attr case_attr %type <specify_target_ptr> specify_target @@ -1581,10 +1582,28 @@ cell_port: free_attr($1); }; +always_comb_or_latch: + TOK_ALWAYS_COMB { + $$ = false; + } | + TOK_ALWAYS_LATCH { + $$ = true; + }; + +always_or_always_ff: + TOK_ALWAYS { + $$ = false; + } | + TOK_ALWAYS_FF { + $$ = true; + }; + always_stmt: - attr TOK_ALWAYS { + attr always_or_always_ff { AstNode *node = new AstNode(AST_ALWAYS); append_attr(node, $1); + if ($2) + node->attributes[ID(always_ff)] = AstNode::mkconst_int(1, false); ast_stack.back()->children.push_back(node); ast_stack.push_back(node); } always_cond { @@ -1595,6 +1614,22 @@ always_stmt: ast_stack.pop_back(); ast_stack.pop_back(); } | + attr always_comb_or_latch { + AstNode *node = new AstNode(AST_ALWAYS); + append_attr(node, $1); + if ($2) + node->attributes[ID(always_latch)] = AstNode::mkconst_int(1, false); + else + node->attributes[ID(always_comb)] = AstNode::mkconst_int(1, false); + ast_stack.back()->children.push_back(node); + ast_stack.push_back(node); + AstNode *block = new AstNode(AST_BLOCK); + ast_stack.back()->children.push_back(block); + ast_stack.push_back(block); + } behavioral_stmt { + ast_stack.pop_back(); + ast_stack.pop_back(); + } | attr TOK_INITIAL { AstNode *node = new AstNode(AST_INITIAL); append_attr(node, $1); @@ -2207,7 +2242,7 @@ gen_stmt: ast_stack.back()->children.push_back(node); ast_stack.push_back(node); } opt_arg_list ';'{ - ast_stack.pop_back(); + ast_stack.pop_back(); }; gen_stmt_block: @@ -2378,19 +2413,19 @@ basic_expr: append_attr($$, $2); } | basic_expr OP_SHL attr basic_expr { - $$ = new AstNode(AST_SHIFT_LEFT, $1, $4); + $$ = new AstNode(AST_SHIFT_LEFT, $1, new AstNode(AST_TO_UNSIGNED, $4)); append_attr($$, $3); } | basic_expr OP_SHR attr basic_expr { - $$ = new AstNode(AST_SHIFT_RIGHT, $1, $4); + $$ = new AstNode(AST_SHIFT_RIGHT, $1, new AstNode(AST_TO_UNSIGNED, $4)); append_attr($$, $3); } | basic_expr OP_SSHL attr basic_expr { - $$ = new AstNode(AST_SHIFT_SLEFT, $1, $4); + $$ = new AstNode(AST_SHIFT_SLEFT, $1, new AstNode(AST_TO_UNSIGNED, $4)); append_attr($$, $3); } | basic_expr OP_SSHR attr basic_expr { - $$ = new AstNode(AST_SHIFT_SRIGHT, $1, $4); + $$ = new AstNode(AST_SHIFT_SRIGHT, $1, new AstNode(AST_TO_UNSIGNED, $4)); append_attr($$, $3); } | basic_expr '<' attr basic_expr { |