mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-22 13:53:40 +00:00
neater errors, lost in the sauce of source
This commit is contained in:
parent
242853f1f2
commit
6ac9f79de6
13 changed files with 196 additions and 245 deletions
|
@ -13,6 +13,7 @@ frontends/verilog/verilog_parser.tab.cc: frontends/verilog/verilog_parser.y
|
|||
|
||||
frontends/verilog/verilog_parser.tab.hh: frontends/verilog/verilog_parser.tab.cc
|
||||
frontends/verilog/verilog_frontend.h: frontends/verilog/verilog_parser.tab.hh
|
||||
frontends/verilog/verilog_error.h: frontends/verilog/verilog_parser.tab.hh
|
||||
|
||||
frontends/verilog/verilog_lexer.cc: frontends/verilog/verilog_lexer.l frontends/verilog/verilog_parser.tab.cc
|
||||
$(Q) mkdir -p $(dir $@)
|
||||
|
@ -24,5 +25,6 @@ OBJS += frontends/verilog/verilog_parser.tab.o
|
|||
OBJS += frontends/verilog/verilog_lexer.o
|
||||
OBJS += frontends/verilog/preproc.o
|
||||
OBJS += frontends/verilog/verilog_frontend.o
|
||||
OBJS += frontends/verilog/verilog_error.o
|
||||
OBJS += frontends/verilog/const2ast.o
|
||||
|
||||
|
|
|
@ -46,11 +46,8 @@ using namespace VERILOG_FRONTEND;
|
|||
|
||||
std::string ConstParser::fmt_maybe_loc(std::string msg) {
|
||||
std::string s;
|
||||
s += filename.value_or("INTERNAL");
|
||||
|
||||
if (loc)
|
||||
s += stringf("%d", loc->first_line);
|
||||
s += ": ";
|
||||
s += stringf("%s:%d:", loc.filename, loc.first_line);
|
||||
|
||||
s += msg;
|
||||
return s;
|
||||
|
@ -191,7 +188,7 @@ std::unique_ptr<AstNode> ConstParser::const2ast(std::string code, char case_type
|
|||
ch = ch >> 1;
|
||||
}
|
||||
}
|
||||
auto ast = AstNode::mkconst_bits(data, false);
|
||||
auto ast = AstNode::mkconst_bits(loc, data, false);
|
||||
ast->str = code;
|
||||
return ast;
|
||||
}
|
||||
|
@ -210,7 +207,7 @@ std::unique_ptr<AstNode> ConstParser::const2ast(std::string code, char case_type
|
|||
my_strtobin(data, str, -1, 10, case_type, false);
|
||||
if (data.back() == State::S1)
|
||||
data.push_back(State::S0);
|
||||
return AstNode::mkconst_bits(data, true);
|
||||
return AstNode::mkconst_bits(loc, data, true);
|
||||
}
|
||||
|
||||
// unsized constant
|
||||
|
@ -258,7 +255,7 @@ std::unique_ptr<AstNode> ConstParser::const2ast(std::string code, char case_type
|
|||
if (is_signed && data.back() == State::S1)
|
||||
data.push_back(State::S0);
|
||||
}
|
||||
return AstNode::mkconst_bits(data, is_signed, is_unsized);
|
||||
return AstNode::mkconst_bits(loc, data, is_signed, is_unsized);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -32,10 +32,12 @@
|
|||
|
||||
#include "verilog_frontend.h"
|
||||
#include "verilog_lexer.h"
|
||||
#include "verilog_error.h"
|
||||
#include "preproc.h"
|
||||
#include "kernel/yosys.h"
|
||||
#include "libs/sha1/sha1.h"
|
||||
#include <stdarg.h>
|
||||
#include <list>
|
||||
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
using namespace VERILOG_FRONTEND;
|
||||
|
@ -47,10 +49,10 @@ static std::list<std::vector<std::string>> verilog_defaults_stack;
|
|||
|
||||
static void error_on_dpi_function(AST::AstNode *node)
|
||||
{
|
||||
if (node->type == AST::AST_DPI_FUNCTION)
|
||||
log_file_error(node->filename, node->location.first_line, "Found DPI function %s.\n", node->str.c_str());
|
||||
for (auto& child : node->children)
|
||||
error_on_dpi_function(child.get());
|
||||
if (node->type == AST::AST_DPI_FUNCTION)
|
||||
err_at_ast(node->location, "Found DPI function %s.\n", node->str.c_str());
|
||||
for (auto& child : node->children)
|
||||
error_on_dpi_function(child.get());
|
||||
}
|
||||
|
||||
static void add_package_types(dict<std::string, AST::AstNode *> &user_types, std::vector<std::unique_ptr<AST::AstNode>> &package_list)
|
||||
|
@ -69,15 +71,7 @@ static void add_package_types(dict<std::string, AST::AstNode *> &user_types, std
|
|||
}
|
||||
|
||||
struct VerilogFrontend : public Frontend {
|
||||
ParseMode parse_mode;
|
||||
ParseState parse_state;
|
||||
VerilogLexer lexer;
|
||||
frontend_verilog_yy::parser parser;
|
||||
VerilogFrontend() : Frontend("verilog", "read modules from Verilog file"),
|
||||
parse_mode(),
|
||||
parse_state(),
|
||||
lexer(&parse_state, &parse_mode),
|
||||
parser(&lexer, &parse_state, &parse_mode) { }
|
||||
VerilogFrontend() : Frontend("verilog", "read modules from Verilog file") { }
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
|
@ -259,6 +253,8 @@ struct VerilogFrontend : public Frontend {
|
|||
bool flag_dump_vlog1 = false;
|
||||
bool flag_dump_vlog2 = false;
|
||||
bool flag_dump_rtlil = false;
|
||||
bool flag_debug_lexer = false;
|
||||
bool flag_debug_parser = false;
|
||||
bool flag_nolatches = false;
|
||||
bool flag_nomeminit = false;
|
||||
bool flag_nomem2reg = false;
|
||||
|
@ -281,8 +277,8 @@ struct VerilogFrontend : public Frontend {
|
|||
std::list<std::string> include_dirs;
|
||||
std::list<std::string> attributes;
|
||||
|
||||
lexer.set_debug(false);
|
||||
parser.set_debug_level(0);
|
||||
ParseMode parse_mode;
|
||||
ParseState parse_state;
|
||||
parse_mode.sv = false;
|
||||
parse_mode.formal = false;
|
||||
parse_mode.noassert = false;
|
||||
|
@ -340,8 +336,8 @@ struct VerilogFrontend : public Frontend {
|
|||
flag_dump_ast2 = true;
|
||||
flag_dump_vlog1 = true;
|
||||
flag_dump_vlog2 = true;
|
||||
lexer.set_debug(true);
|
||||
parser.set_debug_level(1);
|
||||
flag_debug_lexer = true;
|
||||
flag_debug_parser = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-dump_ast1") {
|
||||
|
@ -370,6 +366,8 @@ struct VerilogFrontend : public Frontend {
|
|||
}
|
||||
if (arg == "-yydebug") {
|
||||
flag_yydebug = true;
|
||||
flag_debug_lexer = true;
|
||||
flag_debug_parser = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-nolatches") {
|
||||
|
@ -481,6 +479,11 @@ struct VerilogFrontend : public Frontend {
|
|||
break;
|
||||
}
|
||||
|
||||
VerilogLexer lexer(&parse_state, &parse_mode, &filename);
|
||||
frontend_verilog_yy::parser parser(&lexer, &parse_state, &parse_mode);
|
||||
lexer.set_debug(flag_debug_lexer);
|
||||
parser.set_debug_level(flag_debug_parser ? 1 : 0);
|
||||
|
||||
if (parse_mode.formal || !flag_nosynthesis)
|
||||
defines_map.add(parse_mode.formal ? "FORMAL" : "SYNTHESIS", "1");
|
||||
|
||||
|
@ -491,10 +494,10 @@ struct VerilogFrontend : public Frontend {
|
|||
log("Parsing %s%s input from `%s' to AST representation.\n",
|
||||
parse_mode.formal ? "formal " : "", parse_mode.sv ? "SystemVerilog" : "Verilog", filename.c_str());
|
||||
|
||||
AST::current_filename = filename;
|
||||
AST::sv_mode = parse_mode.sv;
|
||||
AST::sv_mode_but_global_and_used_for_literally_one_condition = parse_mode.sv;
|
||||
|
||||
parse_state.current_ast = new AST::AstNode(AST::AST_DESIGN);
|
||||
AstSrcLocType top_loc = AstSrcLocType ( "read_verilog", 0, 0, 0, 0);
|
||||
parse_state.current_ast = new AST::AstNode(top_loc, AST::AST_DESIGN);
|
||||
|
||||
parse_state.lexin = f;
|
||||
std::string code_after_preproc;
|
||||
|
@ -522,10 +525,6 @@ struct VerilogFrontend : public Frontend {
|
|||
// add a new empty type map to allow overriding existing global definitions
|
||||
parse_state.user_type_stack.push_back(UserTypeMap());
|
||||
|
||||
parser.~parser();
|
||||
lexer.~VerilogLexer();
|
||||
new (&lexer) VerilogLexer(&parse_state, &parse_mode);
|
||||
new (&parser) frontend_verilog_yy::parser(&lexer, &parse_state, &parse_mode);
|
||||
if (flag_yydebug) {
|
||||
lexer.set_debug(true);
|
||||
parser.set_debug_level(1);
|
||||
|
@ -537,7 +536,7 @@ struct VerilogFrontend : public Frontend {
|
|||
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);
|
||||
child->attributes[attr] = AST::AstNode::mkconst_int(top_loc, 1, false);
|
||||
}
|
||||
|
||||
if (flag_nodpi)
|
||||
|
@ -776,24 +775,4 @@ struct VerilogFileList : public Pass {
|
|||
|
||||
#endif
|
||||
|
||||
[[noreturn]]
|
||||
void VERILOG_FRONTEND::verr_at(std::string filename, int begin_line, char const *fmt, va_list ap)
|
||||
{
|
||||
char buffer[1024];
|
||||
char *p = buffer;
|
||||
p += vsnprintf(p, buffer + sizeof(buffer) - p, fmt, ap);
|
||||
p += snprintf(p, buffer + sizeof(buffer) - p, "\n");
|
||||
YOSYS_NAMESPACE_PREFIX log_file_error(filename, begin_line, "%s", buffer);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
[[noreturn]]
|
||||
void VERILOG_FRONTEND::err_at_ast(AstSrcLocType loc, char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
verr_at(AST::current_filename, loc.first_line, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
YOSYS_NAMESPACE_END
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <list>
|
||||
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -47,8 +46,7 @@ namespace VERILOG_FRONTEND
|
|||
{
|
||||
/* Ephemeral context class */
|
||||
struct ConstParser {
|
||||
std::optional<std::string> filename;
|
||||
std::optional<AST::AstSrcLocType> loc;
|
||||
AST::AstSrcLocType loc;
|
||||
private:
|
||||
std::string fmt_maybe_loc(std::string msg);
|
||||
void log_maybe_loc_error(std::string msg);
|
||||
|
@ -64,8 +62,6 @@ namespace VERILOG_FRONTEND
|
|||
std::unique_ptr<AST::AstNode> const2ast(std::string code, char case_type = 0, bool warn_z = false);
|
||||
|
||||
};
|
||||
[[noreturn]]
|
||||
extern void err_at_ast(AST::AstSrcLocType loc, char const *fmt, ...);
|
||||
};
|
||||
|
||||
YOSYS_NAMESPACE_END
|
||||
|
|
|
@ -4,18 +4,20 @@
|
|||
#include "kernel/yosys.h"
|
||||
#include "frontends/ast/ast.h"
|
||||
#include "frontends/verilog/verilog_parser.tab.hh"
|
||||
#include <string>
|
||||
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
namespace VERILOG_FRONTEND {
|
||||
[[noreturn]]
|
||||
extern void verr_at(std::string filename, int begin_line, char const *fmt, va_list ap);
|
||||
using parser = frontend_verilog_yy::parser;
|
||||
class VerilogLexer : public frontend_verilog_yyFlexLexer {
|
||||
ParseState* extra;
|
||||
ParseMode* mode;
|
||||
public:
|
||||
VerilogLexer(ParseState* e, ParseMode* m) : frontend_verilog_yyFlexLexer(e->lexin), extra(e), mode(m) {}
|
||||
parser::location_type out_loc; // TODO private?
|
||||
VerilogLexer(ParseState* e, ParseMode* m, std::string* filename) : frontend_verilog_yyFlexLexer(e->lexin), extra(e), mode(m) {
|
||||
out_loc.begin.filename = filename;
|
||||
}
|
||||
~VerilogLexer() override {}
|
||||
// autogenerated body due to YY_DECL
|
||||
parser::symbol_type nextToken();
|
||||
|
@ -24,19 +26,9 @@ namespace VERILOG_FRONTEND {
|
|||
parser::symbol_type terminate() {
|
||||
return parser::make_FRONTEND_VERILOG_YYEOF(out_loc);
|
||||
}
|
||||
parser::location_type out_loc;
|
||||
[[noreturn]]
|
||||
void err(char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
verr_at(AST::current_filename, yylineno, fmt, args);
|
||||
}
|
||||
private:
|
||||
std::vector<std::string> fn_stack;
|
||||
std::vector<int> ln_stack;
|
||||
parser::location_type real_loc;
|
||||
parser::location_type old_loc;
|
||||
int LexerInput(char* buf, int max_size) override {
|
||||
return readsome(*extra->lexin, buf, max_size);
|
||||
}
|
||||
|
|
|
@ -85,17 +85,16 @@ YOSYS_NAMESPACE_END
|
|||
// result = readsome(*extra->lexin, buf, max_size)
|
||||
|
||||
#define YY_USER_ACTION \
|
||||
real_loc.begin = real_loc.end; \
|
||||
out_loc.begin = out_loc.end; \
|
||||
for(int i = 0; YYText()[i] != '\0'; ++i){ \
|
||||
if(YYText()[i] == '\n') { \
|
||||
real_loc.end.line++; \
|
||||
real_loc.end.column = 1; \
|
||||
out_loc.end.line++; \
|
||||
out_loc.end.column = 1; \
|
||||
} \
|
||||
else { \
|
||||
real_loc.end.column++; \
|
||||
out_loc.end.column++; \
|
||||
} \
|
||||
} \
|
||||
out_loc = real_loc;
|
||||
}
|
||||
|
||||
#define YY_BREAK \
|
||||
break;
|
||||
|
@ -183,7 +182,6 @@ TIME_SCALE_SUFFIX [munpf]?s
|
|||
current_filename = current_filename.substr(0, current_filename.size()-1);
|
||||
yylineno = (0);
|
||||
out_loc.begin.line = out_loc.end.line = 0;
|
||||
real_loc.begin.line = real_loc.end.line = 0;
|
||||
}
|
||||
|
||||
<INITIAL,SYNOPSYS_TRANSLATE_OFF>"`file_pop"[^\n]*\n {
|
||||
|
@ -191,7 +189,6 @@ TIME_SCALE_SUFFIX [munpf]?s
|
|||
fn_stack.pop_back();
|
||||
yylineno = (ln_stack.back());
|
||||
out_loc.begin.line = out_loc.end.line = ln_stack.back();
|
||||
real_loc.begin.line = real_loc.end.line = ln_stack.back();
|
||||
ln_stack.pop_back();
|
||||
}
|
||||
|
||||
|
@ -200,7 +197,6 @@ TIME_SCALE_SUFFIX [munpf]?s
|
|||
while (*p == ' ' || *p == '\t') p++;
|
||||
yylineno = (atoi(p));
|
||||
out_loc.begin.line = out_loc.end.line = atoi(p);
|
||||
real_loc.begin.line = real_loc.end.line = atoi(p);
|
||||
while (*p && *p != ' ' && *p != '\t') p++;
|
||||
while (*p == ' ' || *p == '\t') p++;
|
||||
const char *q = *p ? p + 1 : p;
|
||||
|
@ -226,14 +222,14 @@ TIME_SCALE_SUFFIX [munpf]?s
|
|||
else if (!strcmp(p, "wire"))
|
||||
extra->default_nettype_wire = true;
|
||||
else
|
||||
err("Unsupported default nettype: %s", p);
|
||||
err_at_loc(out_loc, "Unsupported default nettype: %s", p);
|
||||
}
|
||||
|
||||
"`protect"[^\n]* /* ignore `protect*/
|
||||
"`endprotect"[^\n]* /* ignore `endprotect*/
|
||||
|
||||
"`"[a-zA-Z_$][a-zA-Z0-9_$]* {
|
||||
err("Unimplemented compiler directive or undefined macro %s.", YYText());
|
||||
err_at_loc(out_loc, "Unimplemented compiler directive or undefined macro %s.", YYText());
|
||||
}
|
||||
|
||||
"module" { return parser::make_TOK_MODULE(out_loc); }
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
%code requires {
|
||||
#include "kernel/yosys_common.h"
|
||||
// #include "frontends/verilog/verilog_lexer.h"
|
||||
#include "frontends/verilog/verilog_error.h"
|
||||
// start requires
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
namespace VERILOG_FRONTEND {
|
||||
|
@ -157,8 +157,7 @@
|
|||
static ConstParser make_ConstParser_here(parser::location_type flex_loc) {
|
||||
AstSrcLocType loc;
|
||||
SET_LOC(loc, flex_loc, flex_loc);
|
||||
std::optional<std::string> filename = flex_loc.begin.filename ? std::make_optional(*(flex_loc.begin.filename)) : std::nullopt;
|
||||
ConstParser p{filename, loc};
|
||||
ConstParser p{loc};
|
||||
return p;
|
||||
}
|
||||
static void append_attr(AstNode *ast, dict<IdString, std::unique_ptr<AstNode>> *al)
|
||||
|
@ -244,17 +243,6 @@
|
|||
node->children.push_back(std::move(rangeNode));
|
||||
}
|
||||
|
||||
[[noreturn]]
|
||||
extern void verr_at(std::string filename, int begin_line, char const *fmt, va_list ap);
|
||||
[[noreturn]]
|
||||
static void err_at_loc(frontend_verilog_yy::parser::location_type loc, char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
verr_at(AST::current_filename, loc.begin.line, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void checkLabelsMatch(const frontend_verilog_yy::parser::location_type& loc, const char *element, const std::string* before, const std::string *after)
|
||||
{
|
||||
if (!before && after)
|
||||
|
@ -731,7 +719,7 @@ module:
|
|||
append_attr(mod, $1);
|
||||
} module_para_opt module_args_opt TOK_SEMICOL module_body TOK_ENDMODULE opt_label {
|
||||
if (extra->port_stubs.size() != 0)
|
||||
lexer->err("Missing details for module port `%s'.",
|
||||
err_at_loc(@7, "Missing details for module port `%s'.",
|
||||
extra->port_stubs.begin()->first.c_str());
|
||||
SET_AST_NODE_LOC(extra->ast_stack.back(), @2, @$);
|
||||
extra->ast_stack.pop_back();
|
||||
|
@ -785,7 +773,7 @@ module_arg_opt_assignment:
|
|||
extra->ast_stack.back()->children.push_back(std::make_unique<AstNode>(AST_ASSIGN, std::move(wire), std::move($2)));
|
||||
}
|
||||
} else
|
||||
lexer->err("SystemVerilog interface in module port list cannot have a default value.");
|
||||
err_at_loc(@2, "SystemVerilog interface in module port list cannot have a default value.");
|
||||
} |
|
||||
%empty;
|
||||
|
||||
|
@ -799,7 +787,7 @@ module_arg:
|
|||
extra->ast_stack.back()->children.push_back(std::move(node));
|
||||
} else {
|
||||
if (extra->port_stubs.count(*$1) != 0)
|
||||
lexer->err("Duplicate module port `%s'.", $1->c_str());
|
||||
err_at_loc(@1, "Duplicate module port `%s'.", $1->c_str());
|
||||
extra->port_stubs[*$1] = ++extra->port_counter;
|
||||
}
|
||||
} module_arg_opt_assignment |
|
||||
|
@ -809,7 +797,7 @@ module_arg:
|
|||
extra->astbuf1->children[0]->str = *$1;
|
||||
} TOK_ID { /* SV interfaces */
|
||||
if (!mode->sv)
|
||||
lexer->err("Interface found in port list (%s). This is not supported unless read_verilog is called with -sv!", $3->c_str());
|
||||
err_at_loc(@3, "Interface found in port list (%s). This is not supported unless read_verilog is called with -sv!", $3->c_str());
|
||||
extra->astbuf2 = extra->astbuf1->clone(); // really only needed if multiple instances of same type.
|
||||
extra->astbuf2->str = *$3;
|
||||
extra->astbuf2->port_id = ++extra->port_counter;
|
||||
|
@ -824,9 +812,9 @@ module_arg:
|
|||
if (range != nullptr)
|
||||
node->children.push_back(std::move(range));
|
||||
if (!node->is_input && !node->is_output)
|
||||
lexer->err("Module port `%s' is neither input nor output.", $4->c_str());
|
||||
err_at_loc(@4, "Module port `%s' is neither input nor output.", $4->c_str());
|
||||
if (node->is_reg && node->is_input && !node->is_output && !mode->sv)
|
||||
lexer->err("Input port `%s' is declared as register.", $4->c_str());
|
||||
err_at_loc(@4, "Input port `%s' is declared as register.", $4->c_str());
|
||||
append_attr(node.get(), $1);
|
||||
extra->ast_stack.back()->children.push_back(std::move(node));
|
||||
} module_arg_opt_assignment |
|
||||
|
@ -867,7 +855,7 @@ interface:
|
|||
intf->str = *$3;
|
||||
} module_para_opt module_args_opt TOK_SEMICOL interface_body TOK_ENDINTERFACE {
|
||||
if (extra->port_stubs.size() != 0)
|
||||
lexer->err("Missing details for module port `%s'.",
|
||||
err_at_loc(@6, "Missing details for module port `%s'.",
|
||||
extra->port_stubs.begin()->first.c_str());
|
||||
extra->ast_stack.pop_back();
|
||||
log_assert(extra->ast_stack.size() == 1);
|
||||
|
@ -1284,7 +1272,7 @@ task_func_port:
|
|||
extra->astbuf2 = checkRange(extra->astbuf1.get(), std::move($3));
|
||||
if (!extra->astbuf1->is_input && !extra->astbuf1->is_output) {
|
||||
if (!mode->sv)
|
||||
lexer->err("task/function argument direction missing");
|
||||
err_at_loc(@2, "task/function argument direction missing");
|
||||
extra->astbuf1->is_input = prev_was_input;
|
||||
extra->astbuf1->is_output = prev_was_output;
|
||||
}
|
||||
|
@ -1292,7 +1280,7 @@ task_func_port:
|
|||
{
|
||||
if (!extra->astbuf1) {
|
||||
if (!mode->sv)
|
||||
lexer->err("task/function argument direction missing");
|
||||
err_at_loc(@$, "task/function argument direction missing");
|
||||
extra->albuf = new dict<IdString, std::unique_ptr<AstNode>>;
|
||||
extra->astbuf1 = std::make_unique<AstNode>(AST_WIRE);
|
||||
extra->current_wire_rand = false;
|
||||
|
@ -1325,7 +1313,7 @@ specify_item:
|
|||
specify_rise_fall_ptr_t timing = std::move($9);
|
||||
|
||||
if (specify_edge != 0 && target->dat == nullptr)
|
||||
lexer->err("Found specify edge but no data spec.\n");
|
||||
err_at_loc(@3, "Found specify edge but no data spec.\n");
|
||||
|
||||
auto cell_owned = std::make_unique<AstNode>(AST_CELL);
|
||||
auto cell = cell_owned.get();
|
||||
|
@ -1400,7 +1388,7 @@ specify_item:
|
|||
TOK_ID TOK_LPAREN specify_edge expr specify_condition TOK_COMMA specify_edge expr specify_condition TOK_COMMA specify_triple specify_opt_triple TOK_RPAREN TOK_SEMICOL {
|
||||
if (*$1 != "$setup" && *$1 != "$hold" && *$1 != "$setuphold" && *$1 != "$removal" && *$1 != "$recovery" &&
|
||||
*$1 != "$recrem" && *$1 != "$skew" && *$1 != "$timeskew" && *$1 != "$fullskew" && *$1 != "$nochange")
|
||||
lexer->err("Unsupported specify rule type: %s\n", $1->c_str());
|
||||
err_at_loc(@1, "Unsupported specify rule type: %s\n", $1->c_str());
|
||||
|
||||
auto src_pen = AstNode::mkconst_int($3 != 0, false, 1);
|
||||
auto src_pol = AstNode::mkconst_int($3 == 'p', false, 1);
|
||||
|
@ -1766,10 +1754,10 @@ single_param_decl:
|
|||
AstNode *decl = extra->ast_stack.back()->children.back().get();
|
||||
if (decl->type != AST_PARAMETER) {
|
||||
log_assert(decl->type == AST_LOCALPARAM);
|
||||
lexer->err("localparam initialization is missing!");
|
||||
err_at_loc(@1, "localparam initialization is missing!");
|
||||
}
|
||||
if (!mode->sv)
|
||||
lexer->err("Parameter defaults can only be omitted in SystemVerilog mode!");
|
||||
err_at_loc(@1, "Parameter defaults can only be omitted in SystemVerilog mode!");
|
||||
decl->children.erase(decl->children.begin());
|
||||
};
|
||||
|
||||
|
@ -1778,7 +1766,7 @@ single_param_decl_ident:
|
|||
std::unique_ptr<AstNode> node_owned;
|
||||
if (extra->astbuf1 == nullptr) {
|
||||
if (!mode->sv)
|
||||
lexer->err("In pure Verilog (not SystemVerilog), parameter/localparam with an initializer must use the parameter/localparam keyword");
|
||||
err_at_loc(@1, "In pure Verilog (not SystemVerilog), parameter/localparam with an initializer must use the parameter/localparam keyword");
|
||||
node_owned = std::make_unique<AstNode>(AST_PARAMETER);
|
||||
node_owned->children.push_back(AstNode::mkconst_int(0, true));
|
||||
} else {
|
||||
|
@ -1929,7 +1917,7 @@ struct_body: opt_packed TOK_LCURL struct_member_list TOK_RCURL
|
|||
|
||||
opt_packed:
|
||||
TOK_PACKED opt_signed_struct |
|
||||
%empty { lexer->err("Only PACKED supported at this time"); };
|
||||
%empty { err_at_loc(@$, "Only PACKED supported at this time"); };
|
||||
|
||||
opt_signed_struct:
|
||||
TOK_SIGNED { extra->astbuf2->is_signed = true; }
|
||||
|
@ -2114,7 +2102,7 @@ wire_name_and_opt_assign:
|
|||
wire_name:
|
||||
TOK_ID range_or_multirange {
|
||||
if (extra->astbuf1 == nullptr)
|
||||
lexer->err("Internal error - should not happen - no AST_WIRE node.");
|
||||
err_at_loc(@1, "Internal error - should not happen - no AST_WIRE node.");
|
||||
auto node = extra->astbuf1->clone();
|
||||
node->str = *$1;
|
||||
append_attr_clone(node.get(), extra->albuf);
|
||||
|
@ -2122,7 +2110,7 @@ wire_name:
|
|||
node->children.push_back(extra->astbuf2->clone());
|
||||
if ($2 != nullptr) {
|
||||
if (node->is_input || node->is_output)
|
||||
lexer->err("input/output/inout ports cannot have unpacked dimensions.");
|
||||
err_at_loc(@2, "input/output/inout ports cannot have unpacked dimensions.");
|
||||
if (!extra->astbuf2 && !node->is_custom_type) {
|
||||
addRange(node.get(), 0, 0, false);
|
||||
}
|
||||
|
@ -2133,21 +2121,21 @@ wire_name:
|
|||
node->port_id = extra->current_function_or_task_port_id++;
|
||||
} else if (extra->ast_stack.back()->type == AST_GENBLOCK) {
|
||||
if (node->is_input || node->is_output)
|
||||
lexer->err("Cannot declare module port `%s' within a generate block.", $1->c_str());
|
||||
err_at_loc(@1, "Cannot declare module port `%s' within a generate block.", $1->c_str());
|
||||
} else {
|
||||
if (extra->do_not_require_port_stubs && (node->is_input || node->is_output) && extra->port_stubs.count(*$1) == 0) {
|
||||
extra->port_stubs[*$1] = ++extra->port_counter;
|
||||
}
|
||||
if (extra->port_stubs.count(*$1) != 0) {
|
||||
if (!node->is_input && !node->is_output)
|
||||
lexer->err("Module port `%s' is neither input nor output.", $1->c_str());
|
||||
err_at_loc(@1, "Module port `%s' is neither input nor output.", $1->c_str());
|
||||
if (node->is_reg && node->is_input && !node->is_output && !mode->sv)
|
||||
lexer->err("Input port `%s' is declared as register.", $1->c_str());
|
||||
err_at_loc(@1, "Input port `%s' is declared as register.", $1->c_str());
|
||||
node->port_id = extra->port_stubs[*$1];
|
||||
extra->port_stubs.erase(*$1);
|
||||
} else {
|
||||
if (node->is_input || node->is_output)
|
||||
lexer->err("Module port `%s' is not declared in module header.", $1->c_str());
|
||||
err_at_loc(@1, "Module port `%s' is not declared in module header.", $1->c_str());
|
||||
}
|
||||
}
|
||||
//FIXME: for some reason, TOK_ID has a location which always points to one column *after* the real last column...
|
||||
|
@ -2169,7 +2157,7 @@ assign_expr:
|
|||
};
|
||||
|
||||
type_name: TOK_ID { $$ = std::move($1); } // first time seen
|
||||
| TOK_USER_TYPE { if (extra->isInLocalScope($1.get())) lexer->err("Duplicate declaration of TYPEDEF '%s'", $1->c_str()+1); $$ = std::move($1); }
|
||||
| TOK_USER_TYPE { if (extra->isInLocalScope($1.get())) err_at_loc(@1, "Duplicate declaration of TYPEDEF '%s'", $1->c_str()+1); $$ = std::move($1); }
|
||||
;
|
||||
|
||||
typedef_decl:
|
||||
|
@ -2347,7 +2335,7 @@ cell_port_list:
|
|||
}
|
||||
|
||||
if (has_positional_args && has_named_args)
|
||||
lexer->err("Mix of positional and named cell ports.");
|
||||
err_at_loc(@1, "Mix of positional and named cell ports.");
|
||||
};
|
||||
|
||||
cell_port_list_rules:
|
||||
|
@ -2388,7 +2376,7 @@ cell_port:
|
|||
} |
|
||||
attr TOK_WILDCARD_CONNECT {
|
||||
if (!mode->sv)
|
||||
lexer->err("Wildcard port connections are only supported in SystemVerilog mode.");
|
||||
err_at_loc(@2, "Wildcard port connections are only supported in SystemVerilog mode.");
|
||||
extra->cell_hack->attributes[ID::wildcard_port_conns] = AstNode::mkconst_int(1, false);
|
||||
free_attr($1);
|
||||
};
|
||||
|
@ -2727,11 +2715,11 @@ for_initialization:
|
|||
extra->ast_stack.back()->children.push_back(std::move(node));
|
||||
} |
|
||||
non_io_wire_type range TOK_ID {
|
||||
lexer->err("For loop variable declaration is missing initialization!");
|
||||
err_at_loc(@3, "For loop variable declaration is missing initialization!");
|
||||
} |
|
||||
non_io_wire_type range TOK_ID TOK_EQ expr {
|
||||
if (!mode->sv)
|
||||
lexer->err("For loop inline variable declaration is only supported in SystemVerilog mode!");
|
||||
err_at_loc(@4, "For loop inline variable declaration is only supported in SystemVerilog mode!");
|
||||
|
||||
// loop variable declaration
|
||||
auto wire = std::move($1);
|
||||
|
@ -2915,21 +2903,21 @@ if_attr:
|
|||
attr TOK_UNIQUE0 {
|
||||
AstNode *context = extra->ast_stack.back();
|
||||
if (context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if))
|
||||
lexer->err("unique0 keyword cannot be used for 'else if' branch.");
|
||||
err_at_loc(@2, "unique0 keyword cannot be used for 'else if' branch.");
|
||||
(*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false);
|
||||
$$ = $1;
|
||||
} |
|
||||
attr TOK_PRIORITY {
|
||||
AstNode *context = extra->ast_stack.back();
|
||||
if (context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if))
|
||||
lexer->err("priority keyword cannot be used for 'else if' branch.");
|
||||
err_at_loc(@2, "priority keyword cannot be used for 'else if' branch.");
|
||||
(*$1)[ID::full_case] = AstNode::mkconst_int(1, false);
|
||||
$$ = $1;
|
||||
} |
|
||||
attr TOK_UNIQUE {
|
||||
AstNode *context = extra->ast_stack.back();
|
||||
if (context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if))
|
||||
lexer->err("unique keyword cannot be used for 'else if' branch.");
|
||||
err_at_loc(@2, "unique keyword cannot be used for 'else if' branch.");
|
||||
(*$1)[ID::full_case] = AstNode::mkconst_int(1, false);
|
||||
(*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false);
|
||||
$$ = $1;
|
||||
|
@ -3127,11 +3115,11 @@ genvar_identifier:
|
|||
|
||||
genvar_initialization:
|
||||
TOK_GENVAR genvar_identifier {
|
||||
lexer->err("Generate for loop variable declaration is missing initialization!");
|
||||
err_at_loc(@2, "Generate for loop variable declaration is missing initialization!");
|
||||
} |
|
||||
TOK_GENVAR genvar_identifier TOK_EQ expr {
|
||||
if (!mode->sv)
|
||||
lexer->err("Generate for loop inline variable declaration is only supported in SystemVerilog mode!");
|
||||
err_at_loc(@3, "Generate for loop inline variable declaration is only supported in SystemVerilog mode!");
|
||||
AstNode* node = extra->saveChild(std::make_unique<AstNode>(AST_GENVAR));
|
||||
node->is_reg = true;
|
||||
node->is_signed = true;
|
||||
|
@ -3233,7 +3221,7 @@ basic_expr:
|
|||
} |
|
||||
TOK_LPAREN expr TOK_RPAREN integral_number {
|
||||
if ($4->compare(0, 1, "'") != 0)
|
||||
lexer->err("Cast operation must be applied on sized constants e.g. (<expr>)<constval> , while %s is not a sized constant.", $4->c_str());
|
||||
err_at_loc(@4, "Cast operation must be applied on sized constants e.g. (<expr>)<constval> , while %s is not a sized constant.", $4->c_str());
|
||||
auto p = make_ConstParser_here(@4);
|
||||
auto val = p.const2ast(*$4, extra->case_type_stack.size() == 0 ? 0 : extra->case_type_stack.back(), !mode->lib);
|
||||
if (val == nullptr)
|
||||
|
@ -3242,7 +3230,7 @@ basic_expr:
|
|||
} |
|
||||
hierarchical_id integral_number {
|
||||
if ($2->compare(0, 1, "'") != 0)
|
||||
lexer->err("Cast operation must be applied on sized constants, e.g. <ID>\'d0, while %s is not a sized constant.", $2->c_str());
|
||||
err_at_loc(@2, "Cast operation must be applied on sized constants, e.g. <ID>\'d0, while %s is not a sized constant.", $2->c_str());
|
||||
auto bits = std::make_unique<AstNode>(AST_IDENTIFIER);
|
||||
bits->str = *$1;
|
||||
SET_AST_NODE_LOC(bits.get(), @1, @1);
|
||||
|
@ -3491,25 +3479,25 @@ basic_expr:
|
|||
} |
|
||||
TOK_SIGNED OP_CAST TOK_LPAREN expr TOK_RPAREN {
|
||||
if (!mode->sv)
|
||||
lexer->err("Static cast is only supported in SystemVerilog mode.");
|
||||
err_at_loc(@2, "Static cast is only supported in SystemVerilog mode.");
|
||||
$$ = std::make_unique<AstNode>(AST_TO_SIGNED, std::move($4));
|
||||
SET_AST_NODE_LOC($$.get(), @1, @4);
|
||||
} |
|
||||
TOK_UNSIGNED OP_CAST TOK_LPAREN expr TOK_RPAREN {
|
||||
if (!mode->sv)
|
||||
lexer->err("Static cast is only supported in SystemVerilog mode.");
|
||||
err_at_loc(@2, "Static cast is only supported in SystemVerilog mode.");
|
||||
$$ = std::make_unique<AstNode>(AST_TO_UNSIGNED, std::move($4));
|
||||
SET_AST_NODE_LOC($$.get(), @1, @4);
|
||||
} |
|
||||
basic_expr OP_CAST TOK_LPAREN expr TOK_RPAREN {
|
||||
if (!mode->sv)
|
||||
lexer->err("Static cast is only supported in SystemVerilog mode.");
|
||||
err_at_loc(@2, "Static cast is only supported in SystemVerilog mode.");
|
||||
$$ = std::make_unique<AstNode>(AST_CAST_SIZE, std::move($1), std::move($4));
|
||||
SET_AST_NODE_LOC($$.get(), @1, @4);
|
||||
} |
|
||||
typedef_base_type OP_CAST TOK_LPAREN expr TOK_RPAREN {
|
||||
if (!mode->sv)
|
||||
lexer->err("Static cast is only supported in SystemVerilog mode.");
|
||||
err_at_loc(@2, "Static cast is only supported in SystemVerilog mode.");
|
||||
$$ = std::make_unique<AstNode>(AST_CAST_SIZE, std::move($1), std::move($4));
|
||||
SET_AST_NODE_LOC($$.get(), @1, @4);
|
||||
} |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue