aboutsummaryrefslogtreecommitdiffstats
path: root/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'frontends')
-rw-r--r--frontends/ast/ast.cc30
-rw-r--r--frontends/ast/ast.h2
-rw-r--r--frontends/ast/genrtlil.cc31
-rw-r--r--frontends/ast/simplify.cc30
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;
- }
}
}