aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/verilog
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/verilog')
-rw-r--r--frontends/verilog/verilog_frontend.cc2
-rw-r--r--frontends/verilog/verilog_frontend.h2
-rw-r--r--frontends/verilog/verilog_lexer.l15
-rw-r--r--frontends/verilog/verilog_parser.y156
4 files changed, 101 insertions, 74 deletions
diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc
index 6879e0943..26abe49b5 100644
--- a/frontends/verilog/verilog_frontend.cc
+++ b/frontends/verilog/verilog_frontend.cc
@@ -48,7 +48,7 @@ static void error_on_dpi_function(AST::AstNode *node)
error_on_dpi_function(child);
}
-static void add_package_types(std::map<std::string, AST::AstNode *> &user_types, std::vector<AST::AstNode *> &package_list)
+static void add_package_types(dict<std::string, AST::AstNode *> &user_types, std::vector<AST::AstNode *> &package_list)
{
// prime the parser's user type lookup table with the package qualified names
// of typedefed names in the packages seen so far.
diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h
index 444cc7297..aa7881038 100644
--- a/frontends/verilog/verilog_frontend.h
+++ b/frontends/verilog/verilog_frontend.h
@@ -50,7 +50,7 @@ namespace VERILOG_FRONTEND
extern std::vector<UserTypeMap *> user_type_stack;
// names of package typedef'ed types
- extern std::map<std::string, AST::AstNode*> pkg_user_types;
+ extern dict<std::string, AST::AstNode*> pkg_user_types;
// state of `default_nettype
extern bool default_nettype_wire;
diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l
index f6a3ac4db..02fa0031b 100644
--- a/frontends/verilog/verilog_lexer.l
+++ b/frontends/verilog/verilog_lexer.l
@@ -48,16 +48,18 @@ USING_YOSYS_NAMESPACE
using namespace AST;
using namespace VERILOG_FRONTEND;
+#define YYSTYPE FRONTEND_VERILOG_YYSTYPE
+#define YYLTYPE FRONTEND_VERILOG_YYLTYPE
+
YOSYS_NAMESPACE_BEGIN
namespace VERILOG_FRONTEND {
std::vector<std::string> fn_stack;
std::vector<int> ln_stack;
+ YYLTYPE real_location;
+ YYLTYPE old_location;
}
YOSYS_NAMESPACE_END
-#define YYSTYPE FRONTEND_VERILOG_YYSTYPE
-#define YYLTYPE FRONTEND_VERILOG_YYLTYPE
-
#define SV_KEYWORD(_tok) \
if (sv_mode) return _tok; \
log("Lexer warning: The SystemVerilog keyword `%s' (at %s:%d) is not "\
@@ -73,9 +75,6 @@ YOSYS_NAMESPACE_END
#define YY_INPUT(buf,result,max_size) \
result = readsome(*VERILOG_FRONTEND::lexin, buf, max_size)
-YYLTYPE real_location;
-YYLTYPE old_location;
-
#define YY_USER_ACTION \
old_location = real_location; \
real_location.first_line = real_location.last_line; \
@@ -128,7 +127,9 @@ static bool isUserType(std::string &s)
%x BASED_CONST
%%
- int comment_caller;
+ // Initialise comment_caller to something to avoid a "maybe undefined"
+ // warning from GCC.
+ int comment_caller = INITIAL;
<INITIAL,SYNOPSYS_TRANSLATE_OFF>"`file_push "[^\n]* {
fn_stack.push_back(current_filename);
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 4a5aba79e..c8223f41d 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -50,12 +50,12 @@ using namespace VERILOG_FRONTEND;
YOSYS_NAMESPACE_BEGIN
namespace VERILOG_FRONTEND {
int port_counter;
- std::map<std::string, int> port_stubs;
- std::map<std::string, AstNode*> *attr_list, default_attr_list;
- std::stack<std::map<std::string, AstNode*> *> attr_list_stack;
- std::map<std::string, AstNode*> *albuf;
+ dict<std::string, int> port_stubs;
+ dict<IdString, AstNode*> *attr_list, default_attr_list;
+ std::stack<dict<IdString, AstNode*> *> attr_list_stack;
+ dict<IdString, AstNode*> *albuf;
std::vector<UserTypeMap*> user_type_stack;
- std::map<std::string, AstNode*> pkg_user_types;
+ dict<std::string, AstNode*> pkg_user_types;
std::vector<AstNode*> ast_stack;
struct AstNode *astbuf1, *astbuf2, *astbuf3;
struct AstNode *current_function_or_task;
@@ -87,7 +87,7 @@ YOSYS_NAMESPACE_END
int frontend_verilog_yylex(YYSTYPE *yylval_param, YYLTYPE *yyloc_param);
-static void append_attr(AstNode *ast, std::map<std::string, AstNode*> *al)
+static void append_attr(AstNode *ast, dict<IdString, AstNode*> *al)
{
for (auto &it : *al) {
if (ast->attributes.count(it.first) > 0)
@@ -97,7 +97,7 @@ static void append_attr(AstNode *ast, std::map<std::string, AstNode*> *al)
delete al;
}
-static void append_attr_clone(AstNode *ast, std::map<std::string, AstNode*> *al)
+static void append_attr_clone(AstNode *ast, dict<IdString, AstNode*> *al)
{
for (auto &it : *al) {
if (ast->attributes.count(it.first) > 0)
@@ -106,7 +106,7 @@ static void append_attr_clone(AstNode *ast, std::map<std::string, AstNode*> *al)
}
}
-static void free_attr(std::map<std::string, AstNode*> *al)
+static void free_attr(dict<IdString, AstNode*> *al)
{
for (auto &it : *al)
delete it.second;
@@ -192,7 +192,7 @@ static void addRange(AstNode *parent, int msb = 31, int lsb = 0, bool isSigned =
%union {
std::string *string;
struct YOSYS_NAMESPACE_PREFIX AST::AstNode *ast;
- std::map<std::string, YOSYS_NAMESPACE_PREFIX AST::AstNode*> *al;
+ YOSYS_NAMESPACE_PREFIX dict<YOSYS_NAMESPACE_PREFIX RTLIL::IdString, YOSYS_NAMESPACE_PREFIX AST::AstNode*> *al;
struct specify_target *specify_target_ptr;
struct specify_triple *specify_triple_ptr;
struct specify_rise_fall *specify_rise_fall_ptr;
@@ -289,7 +289,7 @@ attr:
{
if (attr_list != nullptr)
attr_list_stack.push(attr_list);
- attr_list = new std::map<std::string, AstNode*>;
+ attr_list = new dict<IdString, AstNode*>;
for (auto &it : default_attr_list)
(*attr_list)[it.first] = it.second->clone();
} attr_opt {
@@ -311,7 +311,7 @@ defattr:
DEFATTR_BEGIN {
if (attr_list != nullptr)
attr_list_stack.push(attr_list);
- attr_list = new std::map<std::string, AstNode*>;
+ attr_list = new dict<IdString, AstNode*>;
for (auto &it : default_attr_list)
delete it.second;
default_attr_list.clear();
@@ -645,13 +645,13 @@ non_opt_range:
} |
'[' expr TOK_POS_INDEXED expr ']' {
$$ = new AstNode(AST_RANGE);
- AstNode *expr = new AstNode(AST_CONCAT, $2);
+ AstNode *expr = new AstNode(AST_SELFSZ, $2);
$$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, expr->clone(), $4), AstNode::mkconst_int(1, true)));
$$->children.push_back(new AstNode(AST_ADD, expr, AstNode::mkconst_int(0, true)));
} |
'[' expr TOK_NEG_INDEXED expr ']' {
$$ = new AstNode(AST_RANGE);
- AstNode *expr = new AstNode(AST_CONCAT, $2);
+ AstNode *expr = new AstNode(AST_SELFSZ, $2);
$$->children.push_back(new AstNode(AST_ADD, expr, AstNode::mkconst_int(0, true)));
$$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, expr->clone(), AstNode::mkconst_int(1, true)), $4));
} |
@@ -853,7 +853,19 @@ task_func_port:
}
if (astbuf2 && astbuf2->children.size() != 2)
frontend_verilog_yyerror("task/function argument range must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]");
- } wire_name | wire_name;
+ } wire_name |
+ {
+ if (!astbuf1) {
+ if (!sv_mode)
+ frontend_verilog_yyerror("task/function argument direction missing");
+ albuf = new dict<IdString, AstNode*>;
+ astbuf1 = new AstNode(AST_WIRE);
+ current_wire_rand = false;
+ current_wire_const = false;
+ astbuf1->is_input = true;
+ astbuf2 = NULL;
+ }
+ } wire_name;
task_func_body:
task_func_body behavioral_stmt |
@@ -885,6 +897,7 @@ specify_item:
cell->str = stringf("$specify$%d", autoidx++);
cell->children.push_back(new AstNode(AST_CELLTYPE));
cell->children.back()->str = target->dat ? "$specify3" : "$specify2";
+ SET_AST_NODE_LOC(cell, en_expr ? @1 : @2, @10);
char oper_polarity = 0;
char oper_type = oper->at(0);
@@ -973,6 +986,7 @@ specify_item:
cell->str = stringf("$specify$%d", autoidx++);
cell->children.push_back(new AstNode(AST_CELLTYPE));
cell->children.back()->str = "$specrule";
+ SET_AST_NODE_LOC(cell, @1, @14);
cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_str(*$1)));
cell->children.back()->str = "\\TYPE";
@@ -1099,8 +1113,8 @@ specify_rise_fall:
$$->fall = *$4;
delete $2;
delete $4;
- delete $6;
- log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
+ delete $6;
+ log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
} |
'(' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ')' {
$$ = new specify_rise_fall;
@@ -1108,11 +1122,11 @@ specify_rise_fall:
$$->fall = *$4;
delete $2;
delete $4;
- delete $6;
- delete $8;
- delete $10;
- delete $12;
- log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
+ delete $6;
+ delete $8;
+ delete $10;
+ delete $12;
+ log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
} |
'(' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ')' {
$$ = new specify_rise_fall;
@@ -1120,17 +1134,17 @@ specify_rise_fall:
$$->fall = *$4;
delete $2;
delete $4;
- delete $6;
- delete $8;
- delete $10;
- delete $12;
- delete $14;
- delete $16;
- delete $18;
- delete $20;
- delete $22;
- delete $24;
- log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
+ delete $6;
+ delete $8;
+ delete $10;
+ delete $12;
+ delete $14;
+ delete $16;
+ delete $18;
+ delete $20;
+ delete $22;
+ delete $24;
+ log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
}
specify_triple:
@@ -1388,7 +1402,7 @@ enum_type: TOK_ENUM {
delete astbuf1;
astbuf1 = tnode;
tnode->type = AST_WIRE;
- tnode->attributes["\\enum_type"] = AstNode::mkconst_str(astbuf2->str);
+ tnode->attributes[ID::enum_type] = AstNode::mkconst_str(astbuf2->str);
// drop constant but keep any range
delete tnode->children[0];
tnode->children.erase(tnode->children.begin()); }
@@ -1747,7 +1761,9 @@ single_prim:
/* no name */ {
astbuf2 = astbuf1->clone();
ast_stack.back()->children.push_back(astbuf2);
- } '(' cell_port_list ')';
+ } '(' cell_port_list ')' {
+ SET_AST_NODE_LOC(astbuf2, @1, @$);
+ }
cell_parameter_list_opt:
'#' '(' cell_parameter_list ')' | /* empty */;
@@ -2187,49 +2203,56 @@ assert_property:
};
simple_behavioral_stmt:
- lvalue '=' delay expr {
- AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, $4);
+ attr lvalue '=' delay expr {
+ AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, $5);
ast_stack.back()->children.push_back(node);
- SET_AST_NODE_LOC(node, @1, @4);
+ SET_AST_NODE_LOC(node, @2, @5);
+ append_attr(node, $1);
} |
- lvalue TOK_INCREMENT {
- AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, new AstNode(AST_ADD, $1->clone(), AstNode::mkconst_int(1, true)));
+ attr lvalue TOK_INCREMENT {
+ AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, new AstNode(AST_ADD, $2->clone(), AstNode::mkconst_int(1, true)));
ast_stack.back()->children.push_back(node);
- SET_AST_NODE_LOC(node, @1, @2);
+ SET_AST_NODE_LOC(node, @2, @3);
+ append_attr(node, $1);
} |
- lvalue TOK_DECREMENT {
- AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, new AstNode(AST_SUB, $1->clone(), AstNode::mkconst_int(1, true)));
+ attr lvalue TOK_DECREMENT {
+ AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, new AstNode(AST_SUB, $2->clone(), AstNode::mkconst_int(1, true)));
ast_stack.back()->children.push_back(node);
- SET_AST_NODE_LOC(node, @1, @2);
+ SET_AST_NODE_LOC(node, @2, @3);
+ append_attr(node, $1);
} |
- lvalue OP_LE delay expr {
- AstNode *node = new AstNode(AST_ASSIGN_LE, $1, $4);
+ attr lvalue OP_LE delay expr {
+ AstNode *node = new AstNode(AST_ASSIGN_LE, $2, $5);
ast_stack.back()->children.push_back(node);
- SET_AST_NODE_LOC(node, @1, @4);
+ SET_AST_NODE_LOC(node, @2, @5);
+ append_attr(node, $1);
};
// this production creates the obligatory if-else shift/reduce conflict
behavioral_stmt:
defattr | assert | wire_decl | param_decl | localparam_decl | typedef_decl |
non_opt_delay behavioral_stmt |
- simple_behavioral_stmt ';' | ';' |
- hierarchical_id attr {
+ simple_behavioral_stmt ';' |
+ attr ';' {
+ free_attr($1);
+ } |
+ attr hierarchical_id {
AstNode *node = new AstNode(AST_TCALL);
- node->str = *$1;
- delete $1;
+ node->str = *$2;
+ delete $2;
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
- append_attr(node, $2);
+ append_attr(node, $1);
} opt_arg_list ';'{
ast_stack.pop_back();
} |
- TOK_MSG_TASKS attr {
+ attr TOK_MSG_TASKS {
AstNode *node = new AstNode(AST_TCALL);
- node->str = *$1;
- delete $1;
+ node->str = *$2;
+ delete $2;
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
- append_attr(node, $2);
+ append_attr(node, $1);
} opt_arg_list ';'{
ast_stack.pop_back();
} |
@@ -2326,8 +2349,6 @@ behavioral_stmt:
ast_stack.pop_back();
};
- ;
-
unique_case_attr:
/* empty */ {
$$ = false;
@@ -2341,7 +2362,7 @@ unique_case_attr:
case_attr:
attr unique_case_attr {
- if ($2) (*$1)["\\parallel_case"] = AstNode::mkconst_int(1, false);
+ if ($2) (*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false);
$$ = $1;
};
@@ -2422,7 +2443,7 @@ gen_case_item:
} case_select {
case_type_stack.push_back(0);
SET_AST_NODE_LOC(ast_stack.back(), @2, @2);
- } gen_stmt_or_null {
+ } gen_stmt_block {
case_type_stack.pop_back();
ast_stack.pop_back();
};
@@ -2514,7 +2535,10 @@ module_gen_body:
/* empty */;
gen_stmt_or_module_body_stmt:
- gen_stmt | module_body_stmt;
+ gen_stmt | module_body_stmt |
+ attr ';' {
+ free_attr($1);
+ };
// this production creates the obligatory if-else shift/reduce conflict
gen_stmt:
@@ -2533,7 +2557,12 @@ gen_stmt:
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
ast_stack.back()->children.push_back($3);
- } gen_stmt_block opt_gen_else {
+ AstNode *block = new AstNode(AST_GENBLOCK);
+ ast_stack.back()->children.push_back(block);
+ ast_stack.push_back(block);
+ } gen_stmt_block {
+ ast_stack.pop_back();
+ } opt_gen_else {
SET_AST_NODE_LOC(ast_stack.back(), @1, @7);
ast_stack.pop_back();
} |
@@ -2581,11 +2610,8 @@ gen_stmt_block:
ast_stack.pop_back();
};
-gen_stmt_or_null:
- gen_stmt_block | ';';
-
opt_gen_else:
- TOK_ELSE gen_stmt_or_null | /* empty */ %prec FAKE_THEN;
+ TOK_ELSE gen_stmt_block | /* empty */ %prec FAKE_THEN;
expr:
basic_expr {