Add support for SVA "final" keyword
[yosys.git] / frontends / verilog / verilog_lexer.l
index ff2fa5753024e7fb5e73dc602285ee8d8719c802..e9763266390b70a62a2e3f691b2a6f74a137417e 100644 (file)
@@ -42,7 +42,7 @@
 #include "kernel/log.h"
 #include "frontends/verilog/verilog_frontend.h"
 #include "frontends/ast/ast.h"
-#include "verilog_parser.tab.h"
+#include "verilog_parser.tab.hh"
 
 USING_YOSYS_NAMESPACE
 using namespace AST;
@@ -135,6 +135,9 @@ YOSYS_NAMESPACE_END
                frontend_verilog_yyerror("Unsupported default nettype: %s", p);
 }
 
+"`protect"[^\n]* /* ignore `protect*/
+"`endprotect"[^\n]* /* ignore `endprotect*/
+
 "`"[a-zA-Z_$][a-zA-Z0-9_$]* {
        frontend_verilog_yyerror("Unimplemented compiler directive or undefined macro %s.", yytext);
 }
@@ -145,8 +148,14 @@ YOSYS_NAMESPACE_END
 "endfunction"  { return TOK_ENDFUNCTION; }
 "task"         { return TOK_TASK; }
 "endtask"      { return TOK_ENDTASK; }
+"specify"      { return TOK_SPECIFY; }
+"endspecify"   { return TOK_ENDSPECIFY; }
+"specparam"    { return TOK_SPECPARAM; }
 "package"      { SV_KEYWORD(TOK_PACKAGE); }
 "endpackage"   { SV_KEYWORD(TOK_ENDPACKAGE); }
+"interface"    { SV_KEYWORD(TOK_INTERFACE); }
+"endinterface" { SV_KEYWORD(TOK_ENDINTERFACE); }
+"modport"      { SV_KEYWORD(TOK_MODPORT); }
 "parameter"    { return TOK_PARAMETER; }
 "localparam"   { return TOK_LOCALPARAM; }
 "defparam"     { return TOK_DEFPARAM; }
@@ -170,11 +179,24 @@ YOSYS_NAMESPACE_END
 "endgenerate"  { return TOK_ENDGENERATE; }
 "while"        { return TOK_WHILE; }
 "repeat"       { return TOK_REPEAT; }
+"automatic"    { return TOK_AUTOMATIC; }
+
+"unique"       { SV_KEYWORD(TOK_UNIQUE); }
+"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); }
 
+ /* 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
+    global state.. its a mess) */
+[a-zA-Z_$][a-zA-Z0-9_$]*/[ \t\r\n]*:[ \t\r\n]*(assert|assume|cover|restrict)[^a-zA-Z0-9_$\.] {
+       frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext);
+       return TOK_SVA_LABEL;
+}
+
 "assert"     { if (formal_mode) return TOK_ASSERT; SV_KEYWORD(TOK_ASSERT); }
 "assume"     { if (formal_mode) return TOK_ASSUME; SV_KEYWORD(TOK_ASSUME); }
 "cover"      { if (formal_mode) return TOK_COVER; SV_KEYWORD(TOK_COVER); }
@@ -184,9 +206,13 @@ YOSYS_NAMESPACE_END
 "const"      { if (formal_mode) return TOK_CONST; SV_KEYWORD(TOK_CONST); }
 "checker"    { if (formal_mode) return TOK_CHECKER; SV_KEYWORD(TOK_CHECKER); }
 "endchecker" { if (formal_mode) return TOK_ENDCHECKER; SV_KEYWORD(TOK_ENDCHECKER); }
-"logic"      { SV_KEYWORD(TOK_REG); }
+"final"      { SV_KEYWORD(TOK_FINAL); }
+"logic"      { SV_KEYWORD(TOK_LOGIC); }
 "bit"        { SV_KEYWORD(TOK_REG); }
 
+"eventually"   { if (formal_mode) return TOK_EVENTUALLY; SV_KEYWORD(TOK_EVENTUALLY); }
+"s_eventually" { if (formal_mode) return TOK_EVENTUALLY; SV_KEYWORD(TOK_EVENTUALLY); }
+
 "input"   { return TOK_INPUT; }
 "output"  { return TOK_OUTPUT; }
 "inout"   { return TOK_INOUT; }
@@ -230,10 +256,18 @@ YOSYS_NAMESPACE_END
        while (yystr[i]) {
                if (yystr[i] == '\\' && yystr[i + 1]) {
                        i++;
-                       if (yystr[i] == 'n')
+                       if (yystr[i] == 'a')
+                               yystr[i] = '\a';
+                       else if (yystr[i] == 'f')
+                               yystr[i] = '\f';
+                       else if (yystr[i] == 'n')
                                yystr[i] = '\n';
+                       else if (yystr[i] == 'r')
+                               yystr[i] = '\r';
                        else if (yystr[i] == 't')
                                yystr[i] = '\t';
+                       else if (yystr[i] == 'v')
+                               yystr[i] = '\v';
                        else if ('0' <= yystr[i] && yystr[i] <= '7') {
                                yystr[i] = yystr[i] - '0';
                                if ('0' <= yystr[i + 1] && yystr[i + 1] <= '7') {
@@ -249,7 +283,7 @@ YOSYS_NAMESPACE_END
                yystr[j++] = yystr[i++];
        }
        yystr[j] = 0;
-       frontend_verilog_yylval.string = new std::string(yystr);
+       frontend_verilog_yylval.string = new std::string(yystr, j);
        free(yystr);
        return TOK_STRING;
 }
@@ -276,6 +310,11 @@ supply1 { return TOK_SUPPLY1; }
        return TOK_ID;
 }
 
+[a-zA-Z_$][a-zA-Z0-9_$\.]* {
+       frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext);
+       return TOK_ID;
+}
+
 "/*"[ \t]*(synopsys|synthesis)[ \t]*translate_off[ \t]*"*/" {
        static bool printed_warning = false;
        if (!printed_warning) {
@@ -366,7 +405,9 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ {
 "<<<" { return OP_SSHL; }
 ">>>" { return OP_SSHR; }
 
-"::"  { SV_KEYWORD(TOK_PACKAGESEP); }
+"::"  { return TOK_PACKAGESEP; }
+"++"  { return TOK_INCREMENT; }
+"--"  { return TOK_DECREMENT; }
 
 "+:" { return TOK_POS_INDEXED; }
 "-:" { return TOK_NEG_INDEXED; }
@@ -380,10 +421,6 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ {
 \\[\r\n]               /* ignore continuation sequence */
 "//"[^\r\n]*           /* ignore one-line comments */
 
-"#"\ *[0-9][0-9_]*                     /* ignore simulation timings */
-"#"\ *[0-9][0-9_]*\.[0-9][0-9_]*       /* ignore simulation timings */
-"#"\ *[$a-zA-Z_\.][$a-zA-Z_0-9\.]*     /* ignore simulation timings */
-
 . { return *yytext; }
 
 %%