aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/ast/ast.cc
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/ast/ast.cc')
-rw-r--r--frontends/ast/ast.cc82
1 files changed, 65 insertions, 17 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index d35ea4171..2c552ea22 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -46,11 +46,12 @@ namespace AST {
// instanciate global variables (private API)
namespace AST_INTERNAL {
- bool flag_dump_ast, flag_dump_ast_diff, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg;
+ bool flag_dump_ast, flag_dump_ast_diff, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib;
AstNode *current_ast, *current_ast_mod;
std::map<std::string, AstNode*> current_scope;
RTLIL::SigSpec *genRTLIL_subst_from = NULL;
RTLIL::SigSpec *genRTLIL_subst_to = NULL;
+ RTLIL::SigSpec ignoreThisSignalsInInitial;
AstNode *current_top_block, *current_block, *current_block_child;
AstModule *current_module;
}
@@ -122,6 +123,7 @@ std::string AST::type2str(AstNodeType type)
X(AST_CELL)
X(AST_PRIMITIVE)
X(AST_ALWAYS)
+ X(AST_INITIAL)
X(AST_BLOCK)
X(AST_ASSIGN_EQ)
X(AST_ASSIGN_LE)
@@ -417,6 +419,14 @@ void AstNode::dumpVlog(FILE *f, std::string indent)
}
break;
+ case AST_INITIAL:
+ fprintf(f, "%s" "initial\n", indent.c_str());
+ for (auto child : children) {
+ if (child->type != AST_POSEDGE && child->type != AST_NEGEDGE && child->type != AST_EDGE)
+ child->dumpVlog(f, indent + " ");
+ }
+ break;
+
case AST_POSEDGE:
case AST_NEGEDGE:
case AST_EDGE:
@@ -679,10 +689,25 @@ static AstModule* process_module(AstNode *ast)
log("--- END OF AST DUMP ---\n");
}
+ if (flag_lib) {
+ std::vector<AstNode*> new_children;
+ for (auto child : ast->children) {
+ if (child->type == AST_WIRE && (child->is_input || child->is_output))
+ new_children.push_back(child);
+ else
+ delete child;
+ }
+ ast->children.swap(new_children);
+ ast->attributes["\\placeholder"] = AstNode::mkconst_int(0, false, 0);
+ }
+
current_module = new AstModule;
current_module->ast = NULL;
current_module->name = ast->str;
current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum);
+
+ ignoreThisSignalsInInitial = RTLIL::SigSpec();
+
for (auto &attr : ast->attributes) {
if (attr.second->type != AST_CONSTANT)
log_error("Attribute `%s' with non-constant value at %s:%d!\n",
@@ -697,19 +722,30 @@ static AstModule* process_module(AstNode *ast)
}
for (size_t i = 0; i < ast->children.size(); i++) {
AstNode *node = ast->children[i];
- if (node->type != AST_WIRE && node->type != AST_MEMORY)
+ if (node->type != AST_WIRE && node->type != AST_MEMORY && node->type != AST_INITIAL)
node->genRTLIL();
}
+ ignoreThisSignalsInInitial.sort_and_unify();
+
+ for (size_t i = 0; i < ast->children.size(); i++) {
+ AstNode *node = ast->children[i];
+ if (node->type == AST_INITIAL)
+ node->genRTLIL();
+ }
+
+ ignoreThisSignalsInInitial = RTLIL::SigSpec();
+
current_module->ast = ast_before_simplify;
current_module->nolatches = flag_nolatches;
current_module->nomem2reg = flag_nomem2reg;
current_module->mem2reg = flag_mem2reg;
+ current_module->lib = flag_lib;
return current_module;
}
// create AstModule instances for all modules in the AST tree and add them to 'design'
-void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast, bool dump_ast_diff, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg)
+void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast, bool dump_ast_diff, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib)
{
current_ast = ast;
flag_dump_ast = dump_ast;
@@ -718,6 +754,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast, bool dump_
flag_nolatches = nolatches;
flag_nomem2reg = nomem2reg;
flag_mem2reg = mem2reg;
+ flag_lib = lib;
assert(current_ast->type == AST_DESIGN);
for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) {
@@ -747,8 +784,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map<RTLIL::IdStrin
flag_nolatches = nolatches;
flag_nomem2reg = nomem2reg;
flag_mem2reg = mem2reg;
+ flag_lib = lib;
use_internal_line_num();
+ std::string para_info;
std::vector<unsigned char> hash_data;
hash_data.insert(hash_data.end(), name.begin(), name.end());
hash_data.push_back(0);
@@ -762,9 +801,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map<RTLIL::IdStrin
continue;
para_counter++;
std::string para_id = child->str;
- if (parameters.count(child->str) > 0) {
+ if (parameters.count(para_id) > 0) {
log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
rewrite_parameter:
+ para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
child->delete_children();
child->children.push_back(AstNode::mkconst_bits(parameters[para_id].bits, false));
hash_data.insert(hash_data.end(), child->str.begin(), child->str.end());
@@ -774,10 +814,8 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map<RTLIL::IdStrin
parameters.erase(para_id);
continue;
}
- char buf[100];
- snprintf(buf, 100, "$%d", para_counter);
- if (parameters.count(buf) > 0) {
- para_id = buf;
+ 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])));
goto rewrite_parameter;
}
@@ -785,17 +823,26 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map<RTLIL::IdStrin
if (parameters.size() > 0)
log_error("Requested parameter `%s' does not exist in module `%s'!\n", parameters.begin()->first.c_str(), name.c_str());
- unsigned char hash[20];
- unsigned char *hash_data2 = new unsigned char[hash_data.size()];
- for (size_t i = 0; i < hash_data.size(); i++)
- hash_data2[i] = hash_data[i];
- sha1::calc(hash_data2, hash_data.size(), hash);
- delete[] hash_data2;
+ std::string modname;
+
+ if (para_info.size() > 60)
+ {
+ unsigned char hash[20];
+ unsigned char *hash_data2 = new unsigned char[hash_data.size()];
+ for (size_t i = 0; i < hash_data.size(); i++)
+ hash_data2[i] = hash_data[i];
+ sha1::calc(hash_data2, hash_data.size(), hash);
+ delete[] hash_data2;
- char hexstring[41];
- sha1::toHexString(hash, hexstring);
+ char hexstring[41];
+ sha1::toHexString(hash, hexstring);
- std::string modname = "$paramod$" + std::string(hexstring) + "$" + name;
+ modname = "$paramod$" + std::string(hexstring) + name;
+ }
+ else
+ {
+ modname = "$paramod" + name + para_info;
+ }
if (design->modules.count(modname) == 0) {
new_ast->str = modname;
@@ -821,6 +868,7 @@ void AstModule::update_auto_wires(std::map<RTLIL::IdString, int> auto_sizes)
flag_nolatches = nolatches;
flag_nomem2reg = nomem2reg;
flag_mem2reg = mem2reg;
+ flag_lib = lib;
use_internal_line_num();
for (auto it = auto_sizes.begin(); it != auto_sizes.end(); it++) {