diff options
author | Eddie Hung <eddie@fpgeh.com> | 2019-05-28 09:30:53 -0700 |
---|---|---|
committer | Eddie Hung <eddie@fpgeh.com> | 2019-05-28 09:30:53 -0700 |
commit | ba9513b325433f9232e1c4312a2b526ca7dacdd4 (patch) | |
tree | 995de7437e31e2c383a0185049e4e844df4d27e0 /frontends | |
parent | f745727de5af085412b2e5f8161aa1018cc5e276 (diff) | |
parent | 8e647901ef6ea484bfe41628f258c53590ae4114 (diff) | |
download | yosys-ba9513b325433f9232e1c4312a2b526ca7dacdd4.tar.gz yosys-ba9513b325433f9232e1c4312a2b526ca7dacdd4.tar.bz2 yosys-ba9513b325433f9232e1c4312a2b526ca7dacdd4.zip |
Merge remote-tracking branch 'origin/master' into xc7mux
Diffstat (limited to 'frontends')
-rw-r--r-- | frontends/ast/ast.cc | 19 | ||||
-rw-r--r-- | frontends/ast/ast.h | 4 | ||||
-rw-r--r-- | frontends/ast/genrtlil.cc | 15 | ||||
-rw-r--r-- | frontends/verilog/const2ast.cc | 26 | ||||
-rw-r--r-- | frontends/verilog/verilog_lexer.l | 4 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 8 |
6 files changed, 61 insertions, 15 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 5623541b2..83993eea9 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -194,6 +194,9 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch is_logic = false; is_signed = false; is_string = false; + is_wand = false; + is_wor = false; + is_unsized = false; was_checked = false; range_valid = false; range_swapped = false; @@ -722,7 +725,7 @@ AstNode *AstNode::mkconst_int(uint32_t v, bool is_signed, int width) } // create an AST node for a constant (using a bit vector as value) -AstNode *AstNode::mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed) +AstNode *AstNode::mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed, bool is_unsized) { AstNode *node = new AstNode(AST_CONSTANT); node->is_signed = is_signed; @@ -736,9 +739,15 @@ AstNode *AstNode::mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signe node->range_valid = true; node->range_left = node->bits.size()-1; node->range_right = 0; + node->is_unsized = is_unsized; return node; } +AstNode *AstNode::mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed) +{ + return mkconst_bits(v, is_signed, false); +} + // create an AST node for a constant (using a string in bit vector form as value) AstNode *AstNode::mkconst_str(const std::vector<RTLIL::State> &v) { @@ -775,6 +784,14 @@ bool AstNode::bits_only_01() const return true; } +RTLIL::Const AstNode::bitsAsUnsizedConst(int width) +{ + RTLIL::State extbit = bits.back(); + while (width > int(bits.size())) + bits.push_back(extbit); + return RTLIL::Const(bits); +} + RTLIL::Const AstNode::bitsAsConst(int width, bool is_signed) { std::vector<RTLIL::State> bits = this->bits; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 281cbe086..46d482f1a 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -173,7 +173,7 @@ namespace AST // node content - most of it is unused in most node types std::string str; std::vector<RTLIL::State> bits; - bool is_input, is_output, is_reg, is_logic, is_signed, is_string, range_valid, range_swapped, was_checked; + bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized; int port_id, range_left, range_right; uint32_t integer; double realvalue; @@ -262,6 +262,7 @@ namespace AST // helper functions for creating AST nodes for constants static AstNode *mkconst_int(uint32_t v, bool is_signed, int width = 32); + static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed, bool is_unsized); static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed); static AstNode *mkconst_str(const std::vector<RTLIL::State> &v); static AstNode *mkconst_str(const std::string &str); @@ -269,6 +270,7 @@ namespace AST // helper function for creating sign-extended const objects RTLIL::Const bitsAsConst(int width, bool is_signed); RTLIL::Const bitsAsConst(int width = -1); + RTLIL::Const bitsAsUnsizedConst(int width); RTLIL::Const asAttrConst(); RTLIL::Const asParaConst(); uint64_t asInt(bool is_signed); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 379fed641..d2651c9aa 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -904,7 +904,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (!range_valid) log_file_error(filename, linenum, "Signal `%s' with non-constant width!\n", str.c_str()); - log_assert(range_left >= range_right || (range_left == -1 && range_right == 0)); + if (!(range_left >= range_right || (range_left == -1 && range_right == 0))) + log_file_error(filename, linenum, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1); RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -919,6 +920,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); wire->attributes[attr.first] = attr.second->asAttrConst(); } + + if (is_wand) wire->set_bool_attribute("\\wand"); + if (is_wor) wire->set_bool_attribute("\\wor"); } break; @@ -963,8 +967,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); is_signed = sign_hint; - if (type == AST_CONSTANT) - return RTLIL::SigSpec(bitsAsConst()); + if (type == AST_CONSTANT) { + if (is_unsized) { + return RTLIL::SigSpec(bitsAsUnsizedConst(width_hint)); + } else { + return RTLIL::SigSpec(bitsAsConst()); + } + } RTLIL::SigSpec sig = realAsConst(width_hint); log_file_warning(filename, linenum, "converting real value %e to binary %s.\n", realvalue, log_signal(sig)); diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index 7848c626d..57d366dbf 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -71,7 +71,7 @@ static int my_ilog2(int x) } // parse a binary, decimal, hexadecimal or octal number with support for special bits ('x', 'z' and '?') -static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int len_in_bits, int base, char case_type) +static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int len_in_bits, int base, char case_type, bool is_unsized) { // all digits in string (MSB at index 0) std::vector<uint8_t> digits; @@ -129,6 +129,9 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le return; } + if (is_unsized && (len > len_in_bits)) + log_file_error(current_filename, get_line_num(), "Unsized constant must have width of 1 bit, but have %d bits!\n", len); + for (len = len - 1; len >= 0; len--) if (data[len] == RTLIL::S1) break; @@ -186,7 +189,7 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn // Simple base-10 integer if (*endptr == 0) { std::vector<RTLIL::State> data; - my_strtobin(data, str, -1, 10, case_type); + my_strtobin(data, str, -1, 10, case_type, false); if (data.back() == RTLIL::S1) data.push_back(RTLIL::S0); return AstNode::mkconst_bits(data, true); @@ -201,6 +204,7 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn { std::vector<RTLIL::State> data; bool is_signed = false; + bool is_unsized = false; if (*(endptr+1) == 's') { is_signed = true; endptr++; @@ -209,28 +213,34 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn { case 'b': case 'B': - my_strtobin(data, endptr+2, len_in_bits, 2, case_type); + my_strtobin(data, endptr+2, len_in_bits, 2, case_type, false); break; case 'o': case 'O': - my_strtobin(data, endptr+2, len_in_bits, 8, case_type); + my_strtobin(data, endptr+2, len_in_bits, 8, case_type, false); break; case 'd': case 'D': - my_strtobin(data, endptr+2, len_in_bits, 10, case_type); + my_strtobin(data, endptr+2, len_in_bits, 10, case_type, false); break; case 'h': case 'H': - my_strtobin(data, endptr+2, len_in_bits, 16, case_type); + my_strtobin(data, endptr+2, len_in_bits, 16, case_type, false); break; default: - return NULL; + char next_char = char(tolower(*(endptr+1))); + if (next_char == '0' || next_char == '1' || next_char == 'x' || next_char == 'z') { + my_strtobin(data, endptr+1, 1, 2, case_type, true); + is_unsized = true; + } else { + return NULL; + } } if (len_in_bits < 0) { if (is_signed && data.back() == RTLIL::S1) data.push_back(RTLIL::S0); } - return AstNode::mkconst_bits(data, is_signed); + return AstNode::mkconst_bits(data, is_signed, is_unsized); } return NULL; diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 142d05d45..9558bbfb9 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -218,6 +218,8 @@ YOSYS_NAMESPACE_END "output" { return TOK_OUTPUT; } "inout" { return TOK_INOUT; } "wire" { return TOK_WIRE; } +"wor" { return TOK_WOR; } +"wand" { return TOK_WAND; } "reg" { return TOK_REG; } "integer" { return TOK_INTEGER; } "signed" { return TOK_SIGNED; } @@ -232,7 +234,7 @@ YOSYS_NAMESPACE_END return TOK_CONSTVAL; } -[0-9]*[ \t]*\'s?[bodhBODH][ \t\r\n]*[0-9a-fA-FzxZX?_]+ { +[0-9]*[ \t]*\'s?[bodhBODH]*[ \t\r\n]*[0-9a-fA-FzxZX?_]+ { frontend_verilog_yylval.string = new std::string(yytext); return TOK_CONSTVAL; } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 132468f0c..8244a8f44 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -139,7 +139,7 @@ struct specify_rise_fall { %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM %token TOK_PACKAGE TOK_ENDPACKAGE TOK_PACKAGESEP %token TOK_INTERFACE TOK_ENDINTERFACE TOK_MODPORT TOK_VAR -%token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG TOK_LOGIC +%token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_WAND TOK_WOR TOK_REG TOK_LOGIC %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_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR TOK_AUTOMATIC @@ -485,6 +485,12 @@ wire_type_token_io: wire_type_token: TOK_WIRE { } | + TOK_WOR { + astbuf3->is_wor = true; + } | + TOK_WAND { + astbuf3->is_wand = true; + } | TOK_REG { astbuf3->is_reg = true; } | |