diff options
Diffstat (limited to 'frontends')
-rw-r--r-- | frontends/aiger/aigerparse.cc | 41 | ||||
-rw-r--r-- | frontends/ast/ast.cc | 54 | ||||
-rw-r--r-- | frontends/ast/ast.h | 1 | ||||
-rw-r--r-- | frontends/ast/simplify.cc | 36 | ||||
-rw-r--r-- | frontends/verilog/const2ast.cc | 10 | ||||
-rw-r--r-- | frontends/verilog/verilog_lexer.l | 2 |
6 files changed, 94 insertions, 50 deletions
diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 2e1fb8fad..e8ee487e5 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -430,6 +430,7 @@ void AigerReader::parse_xaiger(const dict<int,IdString> &box_lookup) else if (c == 'r') { uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); flopNum = parse_xaiger_literal(f); + log_debug("flopNum: %u\n", flopNum); log_assert(dataSize == (flopNum+1) * sizeof(uint32_t)); f.ignore(flopNum * sizeof(uint32_t)); } @@ -496,8 +497,7 @@ void AigerReader::parse_aiger_ascii() // Parse latches RTLIL::Wire *clk_wire = nullptr; - if (L > 0) { - log_assert(clk_name != ""); + if (L > 0 && !clk_name.empty()) { clk_wire = module->wire(clk_name); log_assert(!clk_wire); log_debug2("Creating %s\n", clk_name.c_str()); @@ -513,7 +513,10 @@ void AigerReader::parse_aiger_ascii() RTLIL::Wire *q_wire = createWireIfNotExists(module, l1); RTLIL::Wire *d_wire = createWireIfNotExists(module, l2); - module->addDffGate(NEW_ID, clk_wire, d_wire, q_wire); + if (clk_wire) + module->addDffGate(NEW_ID, clk_wire, d_wire, q_wire); + else + module->addFfGate(NEW_ID, d_wire, q_wire); // Reset logic is optional in AIGER 1.9 if (f.peek() == ' ') { @@ -621,8 +624,7 @@ void AigerReader::parse_aiger_binary() // Parse latches RTLIL::Wire *clk_wire = nullptr; - if (L > 0) { - log_assert(clk_name != ""); + if (L > 0 && !clk_name.empty()) { clk_wire = module->wire(clk_name); log_assert(!clk_wire); log_debug2("Creating %s\n", clk_name.c_str()); @@ -638,7 +640,10 @@ void AigerReader::parse_aiger_binary() RTLIL::Wire *q_wire = createWireIfNotExists(module, l1); RTLIL::Wire *d_wire = createWireIfNotExists(module, l2); - module->addDff(NEW_ID, clk_wire, d_wire, q_wire); + if (clk_wire) + module->addDff(NEW_ID, clk_wire, d_wire, q_wire); + else + module->addFf(NEW_ID, d_wire, q_wire); // Reset logic is optional in AIGER 1.9 if (f.peek() == ' ') { @@ -776,19 +781,19 @@ void AigerReader::post_process() // NB: Assume box_module->ports are sorted alphabetically // (as RTLIL::Module::fixup_ports() would do) for (auto port_name : box_module->ports) { - RTLIL::Wire* w = box_module->wire(port_name); - log_assert(w); + RTLIL::Wire* port = box_module->wire(port_name); + log_assert(port); RTLIL::SigSpec rhs; - RTLIL::Wire* wire = nullptr; - for (int i = 0; i < GetSize(w); i++) { - if (w->port_input) { + for (int i = 0; i < GetSize(port); i++) { + RTLIL::Wire* wire = nullptr; + if (port->port_input) { log_assert(co_count < outputs.size()); wire = outputs[co_count++]; log_assert(wire); log_assert(wire->port_output); wire->port_output = false; } - if (w->port_output) { + if (port->port_output) { log_assert((piNum + ci_count) < inputs.size()); wire = inputs[piNum + ci_count++]; log_assert(wire); @@ -797,6 +802,7 @@ void AigerReader::post_process() } rhs.append(wire); } + cell->setPort(port_name, rhs); } } @@ -814,6 +820,7 @@ void AigerReader::post_process() RTLIL::Wire* wire = inputs[variable]; log_assert(wire); log_assert(wire->port_input); + log_debug("Renaming input %s", log_id(wire)); if (index == 0) { // Cope with the fact that a CI might be identical @@ -840,6 +847,7 @@ void AigerReader::post_process() wire->port_input = false; } } + log_debug(" -> %s\n", log_id(wire)); } else if (type == "output") { log_assert(static_cast<unsigned>(variable + co_count) < outputs.size()); @@ -850,6 +858,7 @@ void AigerReader::post_process() wire->port_output = false; continue; } + log_debug("Renaming output %s", log_id(wire)); if (index == 0) { // Cope with the fact that a CO might be identical @@ -871,6 +880,7 @@ void AigerReader::post_process() else { wire->port_output = false; module->connect(wire, existing); + wire = existing; } } else if (index > 0) { @@ -896,6 +906,7 @@ void AigerReader::post_process() wire->port_output = false; } } + log_debug(" -> %s\n", log_id(wire)); } else if (type == "box") { RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable)); @@ -974,7 +985,7 @@ void AigerReader::post_process() // operate (and run checks on) this one module RTLIL::Design *mapped_design = new RTLIL::Design; mapped_design->add(module); - Pass::call(mapped_design, "clean -purge"); + Pass::call(mapped_design, "clean"); mapped_design->modules_.erase(module->name); delete mapped_design; @@ -1004,8 +1015,8 @@ struct AigerFrontend : public Frontend { log(" Name of module to be created (default: <filename>)\n"); log("\n"); log(" -clk_name <wire_name>\n"); - log(" AIGER latches to be transformed into posedge DFFs clocked by wire of"); - log(" this name (default: clk)\n"); + log(" If specified, AIGER latches to be transformed into $_DFF_P_ cells\n"); + log(" clocked by wire of this name. Otherwise, $_FF_ cells will be used.\n"); log("\n"); log(" -map <filename>\n"); log(" read file with port and latch symbols\n"); diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 82283fb5b..21279cbfa 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -158,6 +158,11 @@ std::string AST::type2str(AstNodeType type) X(AST_POSEDGE) X(AST_NEGEDGE) X(AST_EDGE) + X(AST_INTERFACE) + X(AST_INTERFACEPORT) + X(AST_INTERFACEPORTTYPE) + X(AST_MODPORT) + X(AST_MODPORTMEMBER) X(AST_PACKAGE) #undef X default: @@ -1099,6 +1104,13 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast ignoreThisSignalsInInitial = RTLIL::SigSpec(); } + else { + for (auto &attr : ast->attributes) { + if (attr.second->type != AST_CONSTANT) + continue; + current_module->attributes[attr.first] = attr.second->asAttrConst(); + } + } if (ast->type == AST_INTERFACE) current_module->set_bool_attribute("\\is_interface"); @@ -1284,6 +1296,8 @@ void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule // from AST. The interface members are copied into the AST module with the prefix of the interface. void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module*> local_interfaces) { + loadconfig(); + bool is_top = false; AstNode *new_ast = ast->clone(); for (auto &intf : local_interfaces) { @@ -1467,24 +1481,7 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString stripped_name = stripped_name.substr(9); log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); - - current_ast = NULL; - flag_dump_ast1 = false; - flag_dump_ast2 = false; - flag_dump_vlog1 = false; - flag_dump_vlog2 = false; - flag_nolatches = nolatches; - flag_nomeminit = nomeminit; - flag_nomem2reg = nomem2reg; - flag_mem2reg = mem2reg; - flag_noblackbox = noblackbox; - flag_lib = lib; - flag_nowb = nowb; - flag_noopt = noopt; - flag_icells = icells; - flag_pwires = pwires; - flag_autowire = autowire; - use_internal_line_num(); + loadconfig(); std::string para_info; AstNode *new_ast = ast->clone(); @@ -1565,6 +1562,27 @@ RTLIL::Module *AstModule::clone() const return new_mod; } +void AstModule::loadconfig() const +{ + current_ast = NULL; + flag_dump_ast1 = false; + flag_dump_ast2 = false; + flag_dump_vlog1 = false; + flag_dump_vlog2 = false; + flag_nolatches = nolatches; + flag_nomeminit = nomeminit; + flag_nomem2reg = nomem2reg; + flag_mem2reg = mem2reg; + flag_noblackbox = noblackbox; + flag_lib = lib; + flag_nowb = nowb; + flag_noopt = noopt; + flag_icells = icells; + flag_pwires = pwires; + flag_autowire = autowire; + use_internal_line_num(); +} + // internal dummy line number callbacks namespace { int internal_line_num; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 54b2fb319..93fee913e 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -299,6 +299,7 @@ namespace AST std::string derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool mayfail); void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces) YS_OVERRIDE; RTLIL::Module *clone() const YS_OVERRIDE; + void loadconfig() const; }; // this must be set by the language frontend before parsing the sources diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 86dd80c65..b1ee22f42 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1530,10 +1530,16 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire_en->str] = wire_en; while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } - std::vector<RTLIL::State> x_bit; - x_bit.push_back(RTLIL::State::Sx); + AstNode *check_defval; + if (type == AST_LIVE || type == AST_FAIR) { + check_defval = new AstNode(AST_REDUCE_BOOL, children[0]->clone()); + } else { + std::vector<RTLIL::State> x_bit; + x_bit.push_back(RTLIL::State::Sx); + check_defval = mkconst_bits(x_bit, false); + } - AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bit, false)); + AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), check_defval); assign_check->children[0]->str = id_check; assign_check->children[0]->was_checked = true; @@ -1546,9 +1552,13 @@ skip_dynamic_range_lvalue_expansion:; default_signals->children.push_back(assign_en); current_top_block->children.insert(current_top_block->children.begin(), default_signals); - assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone())); - assign_check->children[0]->str = id_check; - assign_check->children[0]->was_checked = true; + if (type == AST_LIVE || type == AST_FAIR) { + assign_check = nullptr; + } else { + assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone())); + assign_check->children[0]->str = id_check; + assign_check->children[0]->was_checked = true; + } if (current_always == nullptr || current_always->type != AST_INITIAL) { assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(1, false, 1)); @@ -1560,7 +1570,8 @@ skip_dynamic_range_lvalue_expansion:; assign_en->children[0]->was_checked = true; newNode = new AstNode(AST_BLOCK); - newNode->children.push_back(assign_check); + if (assign_check != nullptr) + newNode->children.push_back(assign_check); newNode->children.push_back(assign_en); AstNode *assertnode = new AstNode(type); @@ -2884,8 +2895,15 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m void AstNode::expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map) { if (!index_var.empty() && type == AST_IDENTIFIER && str == index_var) { - current_scope[index_var]->children[0]->cloneInto(this); - return; + if (children.empty()) { + current_scope[index_var]->children[0]->cloneInto(this); + } else { + AstNode *p = new AstNode(AST_LOCALPARAM, current_scope[index_var]->children[0]->clone()); + p->str = stringf("$genval$%d", autoidx++); + current_ast_mod->children.push_back(p); + str = p->str; + id2ast = p; + } } if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL) && name_map.count(str) > 0) diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index 4bf5b1cf5..49281f7e7 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -85,10 +85,8 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le digits.push_back(10 + *str - 'A'); else if (*str == 'x' || *str == 'X') digits.push_back(0xf0); - else if (*str == 'z' || *str == 'Z') + else if (*str == 'z' || *str == 'Z' || *str == '?') digits.push_back(0xf1); - else if (*str == '?') - digits.push_back(0xf2); str++; } @@ -112,8 +110,6 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le 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) ? State::S1 : State::S0); } @@ -199,13 +195,13 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn if (str == endptr) len_in_bits = -1; - // The "<bits>'s?[bodhBODH]<digits>" syntax + // The "<bits>'[sS]?[bodhBODH]<digits>" syntax if (*endptr == '\'') { std::vector<RTLIL::State> data; bool is_signed = false; bool is_unsized = len_in_bits < 0; - if (*(endptr+1) == 's') { + if (*(endptr+1) == 's' || *(endptr+1) == 'S') { is_signed = true; endptr++; } diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 57e55b1f4..4acfb414d 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -239,7 +239,7 @@ YOSYS_NAMESPACE_END return TOK_CONSTVAL; } -[0-9]*[ \t]*\'s?[bodhBODH]*[ \t\r\n]*[0-9a-fA-FzxZX?_]+ { +[0-9]*[ \t]*\'[sS]?[bodhBODH]?[ \t\r\n]*[0-9a-fA-FzxZX?_]+ { frontend_verilog_yylval.string = new std::string(yytext); return TOK_CONSTVAL; } |