aboutsummaryrefslogtreecommitdiffstats
path: root/frontends
diff options
context:
space:
mode:
authorJannis Harder <me@jix.one>2023-03-20 12:50:14 +0100
committerJannis Harder <me@jix.one>2023-03-20 12:52:46 +0100
commitfb1c2be76ba065a3da04f279b11e1ed2e59c75c5 (patch)
treef452376b633c339d43d7e2e16cc991465ebeef25 /frontends
parent61da330a38812a0a394131f9f434c736cb2239cf (diff)
downloadyosys-fb1c2be76ba065a3da04f279b11e1ed2e59c75c5.tar.gz
yosys-fb1c2be76ba065a3da04f279b11e1ed2e59c75c5.tar.bz2
yosys-fb1c2be76ba065a3da04f279b11e1ed2e59c75c5.zip
verilog: Support void functions
The difference between void functions and tasks is that always_comb's implicit sensitivity list behaves as if functions were inlined, but ignores signals read only in tasks. This only matters for event based simulation, and for synthesis we can treat a void function like a task.
Diffstat (limited to 'frontends')
-rw-r--r--frontends/verilog/verilog_lexer.l1
-rw-r--r--frontends/verilog/verilog_parser.y19
2 files changed, 19 insertions, 1 deletions
diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l
index 958809319..249986668 100644
--- a/frontends/verilog/verilog_lexer.l
+++ b/frontends/verilog/verilog_lexer.l
@@ -276,6 +276,7 @@ TIME_SCALE_SUFFIX [munpf]?s
"byte" { SV_KEYWORD(TOK_BYTE); }
"shortint" { SV_KEYWORD(TOK_SHORTINT); }
"longint" { SV_KEYWORD(TOK_LONGINT); }
+"void" { SV_KEYWORD(TOK_VOID); }
"eventually" { if (formal_mode) return TOK_EVENTUALLY; SV_KEYWORD(TOK_EVENTUALLY); }
"s_eventually" { if (formal_mode) return TOK_EVENTUALLY; SV_KEYWORD(TOK_EVENTUALLY); }
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 87b50438a..96413afb0 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -372,7 +372,7 @@ static void rewriteGenForDeclInit(AstNode *loop)
%token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_PROPERTY TOK_ENUM TOK_TYPEDEF
%token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY
%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_VOID TOK_UNION
%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
@@ -1020,6 +1020,23 @@ task_func_decl:
current_function_or_task = NULL;
ast_stack.pop_back();
} |
+ attr TOK_FUNCTION opt_automatic TOK_VOID TOK_ID {
+ // The difference between void functions and tasks is that
+ // always_comb's implicit sensitivity list behaves as if functions were
+ // inlined, but ignores signals read only in tasks. This only matters
+ // for event based simulation, and for synthesis we can treat a void
+ // function like a task.
+ current_function_or_task = new AstNode(AST_TASK);
+ current_function_or_task->str = *$5;
+ append_attr(current_function_or_task, $1);
+ ast_stack.back()->children.push_back(current_function_or_task);
+ ast_stack.push_back(current_function_or_task);
+ current_function_or_task_port_id = 1;
+ delete $5;
+ } task_func_args_opt ';' task_func_body TOK_ENDFUNCTION {
+ current_function_or_task = NULL;
+ ast_stack.pop_back();
+ } |
attr TOK_FUNCTION opt_automatic func_return_type TOK_ID {
current_function_or_task = new AstNode(AST_FUNCTION);
current_function_or_task->str = *$5;