Add SV "rand" and "const rand" support
authorClifford Wolf <clifford@clifford.at>
Wed, 8 Feb 2017 13:38:15 +0000 (14:38 +0100)
committerClifford Wolf <clifford@clifford.at>
Wed, 8 Feb 2017 13:38:15 +0000 (14:38 +0100)
README.md
frontends/verilog/verilog_lexer.l
frontends/verilog/verilog_parser.y

index 221bb0ce1b5f150de6870d303b686b2374e70069..396189d5fff56ac57233d49201d82c597cc23368 100644 (file)
--- a/README.md
+++ b/README.md
@@ -378,10 +378,11 @@ Non-standard or SystemVerilog features for formal verification
 - The system task ``$initstate`` evaluates to 1 in the initial state and
   to 0 otherwise.
 
-- The system task ``$anyconst`` evaluates to any constant value.
+- The system task ``$anyconst`` evaluates to any constant value. This is
+  equivalent to declaring a reg as ``const rand``.
 
 - The system task ``$anyseq`` evaluates to any value, possibly a different
-  value in each cycle.
+  value in each cycle. This is equivalent to declaring a reg as ``rand``.
 
 - The SystemVerilog tasks ``$past``, ``$stable``, ``$rose`` and ``$fell`` are
   supported in any clocked block.
@@ -406,6 +407,8 @@ from SystemVerilog:
 - The keywords ``always_comb``, ``always_ff`` and ``always_latch``, ``logic``
   and ``bit`` are supported.
 
+- Declaring free variables with ``rand`` and ``const rand`` is supported.
+
 - SystemVerilog packages are supported. Once a SystemVerilog file is read
   into a design with ``read_verilog``, all its packages are available to
   SystemVerilog files being read into the same design afterwards.
index 4d040e3d1efcd9b6849e2aa73dd4bc1af182ee38..97af0ae2dd7998dcd409b230a11d4516862c1cb4 100644 (file)
@@ -180,6 +180,8 @@ YOSYS_NAMESPACE_END
 "cover"    { if (formal_mode) return TOK_COVER; SV_KEYWORD(TOK_COVER); }
 "restrict" { if (formal_mode) return TOK_RESTRICT; SV_KEYWORD(TOK_RESTRICT); }
 "property" { if (formal_mode) return TOK_PROPERTY; SV_KEYWORD(TOK_PROPERTY); }
+"rand"     { if (formal_mode) return TOK_RAND; SV_KEYWORD(TOK_RAND); }
+"const"    { if (formal_mode) return TOK_CONST; SV_KEYWORD(TOK_CONST); }
 "logic"    { SV_KEYWORD(TOK_REG); }
 "bit"      { SV_KEYWORD(TOK_REG); }
 
@@ -198,12 +200,12 @@ YOSYS_NAMESPACE_END
 
 [0-9][0-9_]* {
        frontend_verilog_yylval.string = new std::string(yytext);
-       return TOK_CONST;
+       return TOK_CONSTVAL;
 }
 
 [0-9]*[ \t]*\'s?[bodhBODH][ \t\r\n]*[0-9a-fA-FzxZX?_]+ {
        frontend_verilog_yylval.string = new std::string(yytext);
-       return TOK_CONST;
+       return TOK_CONSTVAL;
 }
 
 [0-9][0-9_]*\.[0-9][0-9_]*([eE][-+]?[0-9_]+)? {
index 4fedff5cf2bd2fb729d68190965643377f7d4bd8..3eb03dfd83d7541fc6b2521b076f04291421b595 100644 (file)
@@ -59,6 +59,7 @@ namespace VERILOG_FRONTEND {
        bool default_nettype_wire;
        bool sv_mode, formal_mode, lib_mode;
        bool norestrict_mode, assume_asserts_mode;
+       bool current_wire_rand, current_wire_const;
        std::istream *lexin;
 }
 YOSYS_NAMESPACE_END
@@ -100,7 +101,7 @@ static void free_attr(std::map<std::string, AstNode*> *al)
        bool boolean;
 }
 
-%token <string> TOK_STRING TOK_ID TOK_CONST TOK_REALVAL TOK_PRIMITIVE
+%token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE
 %token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END
 %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM
 %token TOK_PACKAGE TOK_ENDPACKAGE TOK_PACKAGESEP
@@ -115,6 +116,7 @@ static void free_attr(std::map<std::string, AstNode*> *al)
 %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED
 %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_ASSUME
 %token TOK_RESTRICT TOK_COVER TOK_PROPERTY TOK_ENUM TOK_TYPEDEF
+%token TOK_RAND TOK_CONST
 
 %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
@@ -355,6 +357,8 @@ delay:
 wire_type:
        {
                astbuf3 = new AstNode(AST_WIRE);
+               current_wire_rand = false;
+               current_wire_const = false;
        } wire_type_token_list delay {
                $$ = astbuf3;
        };
@@ -392,6 +396,12 @@ wire_type_token:
        } |
        TOK_SIGNED {
                astbuf3->is_signed = true;
+       } |
+       TOK_RAND {
+               current_wire_rand = true;
+       } |
+       TOK_CONST {
+               current_wire_const = true;
        };
 
 non_opt_range:
@@ -730,7 +740,15 @@ wire_name_list:
        wire_name_and_opt_assign | wire_name_list ',' wire_name_and_opt_assign;
 
 wire_name_and_opt_assign:
-       wire_name |
+       wire_name {
+               if (current_wire_rand) {
+                       AstNode *wire = new AstNode(AST_IDENTIFIER);
+                       AstNode *fcall = new AstNode(AST_FCALL);
+                       wire->str = ast_stack.back()->children.back()->str;
+                       fcall->str = current_wire_const ? "\\$anyconst" : "\\$anyseq";
+                       ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, fcall));
+               }
+       } |
        wire_name '=' expr {
                AstNode *wire = new AstNode(AST_IDENTIFIER);
                wire->str = ast_stack.back()->children.back()->str;
@@ -1362,7 +1380,7 @@ basic_expr:
        rvalue {
                $$ = $1;
        } |
-       '(' expr ')' TOK_CONST {
+       '(' expr ')' TOK_CONSTVAL {
                if ($4->substr(0, 1) != "'")
                        frontend_verilog_yyerror("Syntax error.");
                AstNode *bits = $2;
@@ -1372,7 +1390,7 @@ basic_expr:
                $$ = new AstNode(AST_TO_BITS, bits, val);
                delete $4;
        } |
-       hierarchical_id TOK_CONST {
+       hierarchical_id TOK_CONSTVAL {
                if ($2->substr(0, 1) != "'")
                        frontend_verilog_yyerror("Syntax error.");
                AstNode *bits = new AstNode(AST_IDENTIFIER);
@@ -1384,14 +1402,14 @@ basic_expr:
                delete $1;
                delete $2;
        } |
-       TOK_CONST TOK_CONST {
+       TOK_CONSTVAL TOK_CONSTVAL {
                $$ = const2ast(*$1 + *$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
                if ($$ == NULL || (*$2)[0] != '\'')
                        log_error("Value conversion failed: `%s%s'\n", $1->c_str(), $2->c_str());
                delete $1;
                delete $2;
        } |
-       TOK_CONST {
+       TOK_CONSTVAL {
                $$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
                if ($$ == NULL)
                        log_error("Value conversion failed: `%s'\n", $1->c_str());