aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/verilog
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/verilog')
-rw-r--r--frontends/verilog/lexer.l22
-rw-r--r--frontends/verilog/parser.y63
-rw-r--r--frontends/verilog/verilog_frontend.cc8
3 files changed, 77 insertions, 16 deletions
diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l
index fdb9bb02c..cf51aac82 100644
--- a/frontends/verilog/lexer.l
+++ b/frontends/verilog/lexer.l
@@ -74,6 +74,7 @@ YOSYS_NAMESPACE_END
%x STRING
%x SYNOPSYS_TRANSLATE_OFF
%x SYNOPSYS_FLAGS
+%x IMPORT_DPI
%%
@@ -274,6 +275,27 @@ supply1 { return TOK_SUPPLY1; }
<SYNOPSYS_FLAGS>. /* ignore everything else */
<SYNOPSYS_FLAGS>"*/" { BEGIN(0); }
+import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ {
+ BEGIN(IMPORT_DPI);
+ return TOK_DPI_FUNCTION;
+}
+
+<IMPORT_DPI>[(),] {
+ return *yytext;
+}
+
+<IMPORT_DPI>[a-zA-Z_$][a-zA-Z0-9_$]* {
+ frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext);
+ return TOK_ID;
+}
+
+<IMPORT_DPI>[ \t\r\n] /* ignore whitespaces */
+
+<IMPORT_DPI>";" {
+ BEGIN(0);
+ return *yytext;
+}
+
"\\"[^ \t\r\n]+ {
frontend_verilog_yylval.string = new std::string(yytext);
return TOK_ID;
diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y
index bf9b21bb6..1d62bc3be 100644
--- a/frontends/verilog/parser.y
+++ b/frontends/verilog/parser.y
@@ -104,7 +104,7 @@ static void free_attr(std::map<std::string, AstNode*> *al)
%token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG
%token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL
%token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT
-%token TOK_POSEDGE TOK_NEGEDGE TOK_OR
+%token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR
%token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT
%token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK
%token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL
@@ -137,14 +137,21 @@ static void free_attr(std::map<std::string, AstNode*> *al)
%%
-input:
- module input |
- defattr input |
- /* empty */ {
- for (auto &it : default_attr_list)
- delete it.second;
- default_attr_list.clear();
- };
+input: {
+ ast_stack.push_back(current_ast);
+} design {
+ ast_stack.pop_back();
+ log_assert(SIZE(ast_stack) == 0);
+ for (auto &it : default_attr_list)
+ delete it.second;
+ default_attr_list.clear();
+};
+
+design:
+ module design |
+ defattr design |
+ task_func_decl design |
+ /* empty */;
attr:
{
@@ -214,9 +221,9 @@ module:
attr TOK_MODULE TOK_ID {
do_not_require_port_stubs = false;
AstNode *mod = new AstNode(AST_MODULE);
- current_ast->children.push_back(mod);
- current_ast_mod = mod;
+ ast_stack.back()->children.push_back(mod);
ast_stack.push_back(mod);
+ current_ast_mod = mod;
port_stubs.clear();
port_counter = 0;
mod->str = *$3;
@@ -227,7 +234,8 @@ module:
frontend_verilog_yyerror("Missing details for module port `%s'.",
port_stubs.begin()->first.c_str());
ast_stack.pop_back();
- log_assert(ast_stack.size() == 0);
+ log_assert(ast_stack.size() == 1);
+ current_ast_mod = NULL;
};
module_para_opt:
@@ -407,6 +415,16 @@ module_body_stmt:
always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property;
task_func_decl:
+ attr TOK_DPI_FUNCTION TOK_ID TOK_ID {
+ current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3));
+ current_function_or_task->str = *$4;
+ append_attr(current_function_or_task, $1);
+ ast_stack.back()->children.push_back(current_function_or_task);
+ delete $3;
+ delete $4;
+ } opt_dpi_function_args ';' {
+ current_function_or_task = NULL;
+ } |
attr TOK_TASK TOK_ID ';' {
current_function_or_task = new AstNode(AST_TASK);
current_function_or_task->str = *$3;
@@ -441,6 +459,27 @@ task_func_decl:
ast_stack.pop_back();
};
+dpi_function_arg:
+ TOK_ID TOK_ID {
+ current_function_or_task->children.push_back(AstNode::mkconst_str(*$1));
+ delete $1;
+ delete $2;
+ } |
+ TOK_ID {
+ current_function_or_task->children.push_back(AstNode::mkconst_str(*$1));
+ delete $1;
+ };
+
+opt_dpi_function_args:
+ '(' dpi_function_args ')' |
+ /* empty */;
+
+dpi_function_args:
+ dpi_function_args ',' dpi_function_arg |
+ dpi_function_args ',' |
+ dpi_function_arg |
+ /* empty */;
+
opt_signed:
TOK_SIGNED {
$$ = true;
diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc
index 4466e1cb6..195789086 100644
--- a/frontends/verilog/verilog_frontend.cc
+++ b/frontends/verilog/verilog_frontend.cc
@@ -285,10 +285,10 @@ struct VerilogFrontend : public Frontend {
frontend_verilog_yylex_destroy();
for (auto &child : current_ast->children) {
- log_assert(child->type == AST::AST_MODULE);
- for (auto &attr : attributes)
- if (child->attributes.count(attr) == 0)
- child->attributes[attr] = AST::AstNode::mkconst_int(1, false);
+ if (child->type == AST::AST_MODULE)
+ for (auto &attr : attributes)
+ if (child->attributes.count(attr) == 0)
+ child->attributes[attr] = AST::AstNode::mkconst_int(1, false);
}
AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer, default_nettype_wire);