diff options
Diffstat (limited to 'frontends')
-rw-r--r-- | frontends/ast/ast.cc | 30 | ||||
-rw-r--r-- | frontends/ast/ast.h | 2 | ||||
-rw-r--r-- | frontends/ast/genrtlil.cc | 31 | ||||
-rw-r--r-- | frontends/ast/simplify.cc | 30 |
4 files changed, 56 insertions, 37 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index ec1cac779..650c7a937 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -939,14 +939,15 @@ RTLIL::Const AstNode::realAsConst(int width) } // create a new AstModule from an AST_MODULE AST node -static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL) +static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false) { log_assert(ast->type == AST_MODULE || ast->type == AST_INTERFACE); if (defer) log("Storing AST representation for module `%s'.\n", ast->str.c_str()); - else + else if (!quiet) { log("Generating RTLIL representation for module `%s'.\n", ast->str.c_str()); + } current_module = new AstModule; current_module->ast = NULL; @@ -1485,14 +1486,16 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R // create a new parametric module (when needed) and return the name of the generated module - without support for interfaces RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool /*mayfail*/) { + bool quiet = lib || attributes.count(ID(blackbox)) || attributes.count(ID(whitebox)); + AstNode *new_ast = NULL; - std::string modname = derive_common(design, parameters, &new_ast); + std::string modname = derive_common(design, parameters, &new_ast, quiet); if (!design->has(modname)) { new_ast->str = modname; - design->add(process_module(new_ast, false)); + design->add(process_module(new_ast, false, NULL, quiet)); design->module(modname)->check(); - } else { + } else if (!quiet) { log("Found cached RTLIL representation for module `%s'.\n", modname.c_str()); } @@ -1501,7 +1504,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R } // create a new parametric module (when needed) and return the name of the generated module -std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out) +std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool quiet) { std::string stripped_name = name.str(); @@ -1517,13 +1520,15 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString para_counter++; std::string para_id = child->str; if (parameters.count(para_id) > 0) { - log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str]))); + if (!quiet) + log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str]))); para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); continue; } para_id = stringf("$%d", para_counter); if (parameters.count(para_id) > 0) { - log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); + if (!quiet) + log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); continue; } @@ -1540,7 +1545,8 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString if (design->has(modname)) return modname; - log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); + if (!quiet) + log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); loadconfig(); AstNode *new_ast = ast->clone(); @@ -1551,12 +1557,14 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString para_counter++; std::string para_id = child->str; if (parameters.count(para_id) > 0) { - log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str]))); + if (!quiet) + log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str]))); goto rewrite_parameter; } para_id = stringf("$%d", para_counter); if (parameters.count(para_id) > 0) { - log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); + if (!quiet) + log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); goto rewrite_parameter; } continue; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 816de005c..e27ab10c2 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -314,7 +314,7 @@ namespace AST ~AstModule() YS_OVERRIDE; RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail) YS_OVERRIDE; RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) YS_OVERRIDE; - std::string derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out); + std::string derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool quiet = false); void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces) YS_OVERRIDE; RTLIL::Module *clone() const YS_OVERRIDE; void loadconfig() const; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 6e4e837b5..54d8a11fa 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1337,18 +1337,31 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec cond = children[0]->genRTLIL(); - RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint); - RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint); + RTLIL::SigSpec sig; + if (cond.is_fully_const()) { + if (cond.as_bool()) { + sig = children[1]->genRTLIL(width_hint, sign_hint); + widthExtend(this, sig, sig.size(), children[1]->is_signed); + } + else { + sig = children[2]->genRTLIL(width_hint, sign_hint); + widthExtend(this, sig, sig.size(), children[2]->is_signed); + } + } + else { + RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint); + RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint); - if (cond.size() > 1) - cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false); + if (cond.size() > 1) + cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false); - int width = max(val1.size(), val2.size()); - is_signed = children[1]->is_signed && children[2]->is_signed; - widthExtend(this, val1, width, is_signed); - widthExtend(this, val2, width, is_signed); + int width = max(val1.size(), val2.size()); + is_signed = children[1]->is_signed && children[2]->is_signed; + widthExtend(this, val1, width, is_signed); + widthExtend(this, val2, width, is_signed); - RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2); + sig = mux2rtlil(this, cond, val1, val2); + } if (sig.size() < width_hint) sig.extend_u0(width_hint, sign_hint); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 2c61f65f4..04c02d893 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1161,7 +1161,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_DPI_FUNCTION: //log("found child %s, %s\n", type2str(node->type).c_str(), node->str.c_str()); if (str == node->str) { - log("add %s, type %s to scope\n", str.c_str(), type2str(node->type).c_str()); + //log("add %s, type %s to scope\n", str.c_str(), type2str(node->type).c_str()); current_scope[node->str] = node; } break; @@ -1322,17 +1322,23 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (varbuf->type != AST_CONSTANT) log_file_error(filename, location.first_line, "Right hand side of 1st expression of generate for-loop is not constant!\n"); - varbuf = new AstNode(AST_LOCALPARAM, varbuf); - varbuf->str = init_ast->children[0]->str; - auto resolved = current_scope.at(init_ast->children[0]->str); if (resolved->range_valid) { - varbuf->range_left = resolved->range_left; - varbuf->range_right = resolved->range_right; - varbuf->range_swapped = resolved->range_swapped; - varbuf->range_valid = resolved->range_valid; + int const_size = varbuf->range_left - varbuf->range_right; + int resolved_size = resolved->range_left - resolved->range_right; + if (const_size < resolved_size) { + for (int i = const_size; i < resolved_size; i++) + varbuf->bits.push_back(resolved->is_signed ? varbuf->bits.back() : State::S0); + varbuf->range_left = resolved->range_left; + varbuf->range_right = resolved->range_right; + varbuf->range_swapped = resolved->range_swapped; + varbuf->range_valid = resolved->range_valid; + } } + varbuf = new AstNode(AST_LOCALPARAM, varbuf); + varbuf->str = init_ast->children[0]->str; + AstNode *backup_scope_varbuf = current_scope[varbuf->str]; current_scope[varbuf->str] = varbuf; @@ -3157,14 +3163,6 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma current_ast_mod->children.push_back(p); str = p->str; id2ast = p; - - auto resolved = current_scope.at(index_var); - if (resolved->range_valid) { - p->range_left = resolved->range_left; - p->range_right = resolved->range_right; - p->range_swapped = resolved->range_swapped; - p->range_valid = resolved->range_valid; - } } } |