sv: Correct parsing of always_comb, always_ff and always_latch
authorDavid Shah <dave@ds0.me>
Thu, 21 Nov 2019 20:27:19 +0000 (20:27 +0000)
committerDavid Shah <dave@ds0.me>
Thu, 21 Nov 2019 20:27:19 +0000 (20:27 +0000)
Signed-off-by: David Shah <dave@ds0.me>
frontends/verilog/verilog_lexer.l
frontends/verilog/verilog_parser.y

index 4acfb414da812b0d85c3a80b7596bcf85ae710a2..c8984c2c41a404f60d9b6555c842addad7ed0bfa 100644 (file)
@@ -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
index 77f6d2051c32294fa82e15161114f4ba7479f946..daea3b43ab99f27cc4c014a7437edb881be438d6 100644 (file)
@@ -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);