aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/verilog
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/verilog')
-rw-r--r--frontends/verilog/const2ast.cc78
-rw-r--r--frontends/verilog/preproc.cc3
-rw-r--r--frontends/verilog/verilog_frontend.cc23
-rw-r--r--frontends/verilog/verilog_lexer.l4
-rw-r--r--frontends/verilog/verilog_parser.y8
5 files changed, 74 insertions, 42 deletions
diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc
index ebecb92f2..4a58357bf 100644
--- a/frontends/verilog/const2ast.cc
+++ b/frontends/verilog/const2ast.cc
@@ -96,44 +96,54 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le
if (base == 10 && GetSize(digits) == 1 && digits.front() >= 0xf0)
base = 2;
+ data.clear();
+
if (base == 10) {
- data.clear();
- if (len_in_bits < 0) {
- while (!digits.empty())
- data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0);
- while (data.size() < 32)
- data.push_back(RTLIL::S0);
- } else {
- for (int i = 0; i < len_in_bits; i++)
- data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0);
+ while (!digits.empty())
+ data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0);
+ } else {
+ int bits_per_digit = my_ilog2(base-1);
+ for (auto it = digits.rbegin(), e = digits.rend(); it != e; it++) {
+ if (*it > (base-1) && *it < 0xf0)
+ log_error("Digit larger than %d used in in base-%d constant at %s:%d.\n",
+ base-1, base, current_filename.c_str(), get_line_num());
+ for (int i = 0; i < bits_per_digit; i++) {
+ int bitmask = 1 << i;
+ if (*it == 0xf0)
+ data.push_back(case_type == 'x' ? RTLIL::Sa : RTLIL::Sx);
+ else if (*it == 0xf1)
+ data.push_back(case_type == 'x' || case_type == 'z' ? RTLIL::Sa : RTLIL::Sz);
+ else if (*it == 0xf2)
+ data.push_back(RTLIL::Sa);
+ else
+ data.push_back((*it & bitmask) ? RTLIL::S1 : RTLIL::S0);
+ }
}
- return;
}
- int bits_per_digit = my_ilog2(base-1);
- if (len_in_bits < 0)
- len_in_bits = std::max<int>(digits.size() * bits_per_digit, 32);
+ int len = GetSize(data);
+ RTLIL::State msb = data.empty() ? RTLIL::S0 : data.back();
- data.clear();
- data.resize(len_in_bits);
-
- for (int i = 0; i < len_in_bits; i++) {
- int bitmask = 1 << (i % bits_per_digit);
- int digitidx = digits.size() - (i / bits_per_digit) - 1;
- if (digitidx < 0) {
- if (i > 0 && (data[i-1] == RTLIL::Sz || data[i-1] == RTLIL::Sx || data[i-1] == RTLIL::Sa))
- data[i] = data[i-1];
- else
- data[i] = RTLIL::S0;
- } else if (digits[digitidx] == 0xf0)
- data[i] = case_type == 'x' ? RTLIL::Sa : RTLIL::Sx;
- else if (digits[digitidx] == 0xf1)
- data[i] = case_type == 'x' || case_type == 'z' ? RTLIL::Sa : RTLIL::Sz;
- else if (digits[digitidx] == 0xf2)
- data[i] = RTLIL::Sa;
- else
- data[i] = (digits[digitidx] & bitmask) ? RTLIL::S1 : RTLIL::S0;
+ if (len_in_bits < 0) {
+ if (len < 32)
+ data.resize(32, msb == RTLIL::S0 || msb == RTLIL::S1 ? RTLIL::S0 : msb);
+ return;
+ }
+
+ for (len = len - 1; len >= 0; len--)
+ if (data[len] == RTLIL::S1)
+ break;
+ if (msb == RTLIL::S0 || msb == RTLIL::S1) {
+ len += 1;
+ data.resize(len_in_bits, RTLIL::S0);
+ } else {
+ len += 2;
+ data.resize(len_in_bits, msb);
}
+
+ if (len > len_in_bits)
+ log_warning("Literal has a width of %d bit, but value requires %d bit. (%s:%d)\n",
+ len_in_bits, len, current_filename.c_str(), get_line_num());
}
// convert the Verilog code for a constant to an AST node
@@ -142,7 +152,7 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn
if (warn_z) {
AstNode *ret = const2ast(code, case_type);
if (std::find(ret->bits.begin(), ret->bits.end(), RTLIL::State::Sz) != ret->bits.end())
- log_warning("Yosys does not support tri-state logic at the moment. (%s:%d)\n",
+ log_warning("Yosys has only limited support for tri-state logic at the moment. (%s:%d)\n",
current_filename.c_str(), get_line_num());
return ret;
}
@@ -220,8 +230,6 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn
if (len_in_bits < 0) {
if (is_signed && data.back() == RTLIL::S1)
data.push_back(RTLIL::S0);
- while (data.size() < 32)
- data.push_back(RTLIL::S0);
}
return AstNode::mkconst_bits(data, is_signed);
}
diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc
index fb8a7b95f..997920b89 100644
--- a/frontends/verilog/preproc.cc
+++ b/frontends/verilog/preproc.cc
@@ -39,6 +39,7 @@
#include <string.h>
YOSYS_NAMESPACE_BEGIN
+using namespace VERILOG_FRONTEND;
static std::list<std::string> output_code;
static std::list<std::string> input_buffer;
@@ -222,7 +223,7 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
input_file(f, filename);
defines_map["YOSYS"] = "1";
- defines_map["SYNTHESIS"] = "1";
+ defines_map[formal_mode ? "FORMAL" : "SYNTHESIS"] = "1";
while (!input_buffer.empty())
{
diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc
index 727ee3d1c..cd8b586c4 100644
--- a/frontends/verilog/verilog_frontend.cc
+++ b/frontends/verilog/verilog_frontend.cc
@@ -39,6 +39,14 @@ using namespace VERILOG_FRONTEND;
static std::vector<std::string> verilog_defaults;
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_error("Found DPI function %s at %s:%d.\n", node->str.c_str(), node->filename.c_str(), node->linenum);
+ for (auto child : node->children)
+ error_on_dpi_function(child);
+}
+
struct VerilogFrontend : public Frontend {
VerilogFrontend() : Frontend("verilog", "read modules from Verilog file") { }
virtual void help()
@@ -55,8 +63,8 @@ struct VerilogFrontend : public Frontend {
log(" of SystemVerilog is supported)\n");
log("\n");
log(" -formal\n");
- log(" enable support for assert() and assume() statements\n");
- log(" (assert support is also enabled with -sv)\n");
+ log(" enable support for assert() and assume() from SystemVerilog\n");
+ log(" replace the implicit -D SYNTHESIS with -D FORMAL\n");
log("\n");
log(" -dump_ast1\n");
log(" dump abstract syntax tree (before simplification)\n");
@@ -107,6 +115,9 @@ struct VerilogFrontend : public Frontend {
log(" -nopp\n");
log(" do not run the pre-processor\n");
log("\n");
+ log(" -nodpi\n");
+ log(" disable DPI-C support\n");
+ log("\n");
log(" -lib\n");
log(" only create empty blackbox modules. This implies -DBLACKBOX.\n");
log("\n");
@@ -160,6 +171,7 @@ struct VerilogFrontend : public Frontend {
bool flag_mem2reg = false;
bool flag_ppdump = false;
bool flag_nopp = false;
+ bool flag_nodpi = false;
bool flag_lib = false;
bool flag_noopt = false;
bool flag_icells = false;
@@ -229,6 +241,10 @@ struct VerilogFrontend : public Frontend {
flag_nopp = true;
continue;
}
+ if (arg == "-nodpi") {
+ flag_nodpi = true;
+ continue;
+ }
if (arg == "-lib") {
flag_lib = true;
defines_map["BLACKBOX"] = string();
@@ -320,6 +336,9 @@ struct VerilogFrontend : public Frontend {
child->attributes[attr] = AST::AstNode::mkconst_int(1, false);
}
+ if (flag_nodpi)
+ error_on_dpi_function(current_ast);
+
AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer, default_nettype_wire);
if (!flag_nopp)
diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l
index a72593583..69a8ddaad 100644
--- a/frontends/verilog/verilog_lexer.l
+++ b/frontends/verilog/verilog_lexer.l
@@ -170,7 +170,7 @@ YOSYS_NAMESPACE_END
"always_latch" { SV_KEYWORD(TOK_ALWAYS); }
"assert" { if (formal_mode) return TOK_ASSERT; SV_KEYWORD(TOK_ASSERT); }
-"assume" { if (formal_mode) return TOK_ASSUME; return TOK_ID; }
+"assume" { if (formal_mode) return TOK_ASSUME; SV_KEYWORD(TOK_ASSUME); }
"property" { if (formal_mode) return TOK_PROPERTY; SV_KEYWORD(TOK_PROPERTY); }
"logic" { SV_KEYWORD(TOK_REG); }
"bit" { SV_KEYWORD(TOK_REG); }
@@ -248,7 +248,7 @@ and|nand|or|nor|xor|xnor|not|buf|bufif0|bufif1|notif0|notif1 {
supply0 { return TOK_SUPPLY0; }
supply1 { return TOK_SUPPLY1; }
-"$"(display|strobe|monitor|time|stop|finish|dumpfile|dumpvars|dumpon|dumpoff|dumpall) {
+"$"(display|write|strobe|monitor|time|stop|finish|dumpfile|dumpvars|dumpon|dumpoff|dumpall) {
frontend_verilog_yylval.string = new std::string(yytext);
return TOK_ID;
}
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 708ac7627..863fee599 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -153,6 +153,8 @@ design:
module design |
defattr design |
task_func_decl design |
+ param_decl design |
+ localparam_decl design |
/* empty */;
attr:
@@ -708,6 +710,8 @@ wire_name_and_opt_assign:
wire_name:
TOK_ID range_or_multirange {
+ if (astbuf1 == nullptr)
+ frontend_verilog_yyerror("Syntax error.");
AstNode *node = astbuf1->clone();
node->str = *$1;
append_attr_clone(node, albuf);
@@ -755,7 +759,7 @@ assign_expr_list:
assign_expr | assign_expr_list ',' assign_expr;
assign_expr:
- expr '=' expr {
+ lvalue '=' expr {
ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, $1, $3));
};
@@ -959,7 +963,7 @@ simple_behavioral_stmt:
// this production creates the obligatory if-else shift/reduce conflict
behavioral_stmt:
- defattr | assert | wire_decl |
+ defattr | assert | wire_decl | param_decl | localparam_decl |
non_opt_delay behavioral_stmt |
simple_behavioral_stmt ';' | ';' |
hierarchical_id attr {