summaryrefslogtreecommitdiff
path: root/frontends
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2015-07-31 10:40:09 +0200
committerClifford Wolf <clifford@clifford.at>2015-07-31 10:40:09 +0200
commit8d6d5c30d9f39ce5b15d1bd3f3a528b38f2f9f9c (patch)
tree8bfd4d9dba657a0c461220838fbf919f45d236b3 /frontends
parent3860c9a9f23104bd54e0000b74624e45c77a8ab3 (diff)
Added WORDS parameter to $meminit
Diffstat (limited to 'frontends')
-rw-r--r--frontends/ast/ast.h2
-rw-r--r--frontends/ast/genrtlil.cc10
-rw-r--r--frontends/ast/simplify.cc62
3 files changed, 67 insertions, 7 deletions
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 28959d5d..44315d49 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -210,7 +210,7 @@ namespace AST
// simplify() creates a simpler AST by unrolling for-loops, expanding generate blocks, etc.
// it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL()
bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param);
- AstNode *readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr);
+ AstNode *readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init);
void expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map);
void replace_ids(const std::string &prefix, const std::map<std::string, std::string> &rules);
void mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg_places,
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index ae538c54..4ed0e2ba 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -1247,8 +1247,16 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
int mem_width, mem_size, addr_bits;
id2ast->meminfo(mem_width, mem_size, addr_bits);
+ int num_words = 1;
+ if (type == AST_MEMINIT) {
+ if (children[2]->type != AST_CONSTANT)
+ log_error("Memory init with non-constant word count at %s:%d!\n", filename.c_str(), linenum);
+ num_words = children[2]->asInt(false);
+ cell->parameters["\\WORDS"] = RTLIL::Const(num_words);
+ }
+
cell->setPort("\\ADDR", children[0]->genWidthRTLIL(addr_bits));
- cell->setPort("\\DATA", children[1]->genWidthRTLIL(current_module->memories[str]->width));
+ cell->setPort("\\DATA", children[1]->genWidthRTLIL(current_module->memories[str]->width * num_words));
cell->parameters["\\MEMID"] = RTLIL::Const(str);
cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits);
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index efa65f30..29935652 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -1425,6 +1425,8 @@ skip_dynamic_range_lvalue_expansion:;
wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
if (current_always->type != AST_INITIAL)
wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
+ else
+ wrnode->children.push_back(AstNode::mkconst_int(1, false));
wrnode->str = children[0]->str;
wrnode->id2ast = children[0]->id2ast;
wrnode->children[0]->str = id_addr;
@@ -1602,7 +1604,17 @@ skip_dynamic_range_lvalue_expansion:;
finish_addr = node_addr->asInt(false);
}
- newNode = readmem(str == "\\$readmemh", node_filename->bitsAsConst().decode_string(), node_memory->id2ast, start_addr, finish_addr);
+ bool unconditional_init = false;
+ if (current_always->type == AST_INITIAL) {
+ log_assert(current_always->children[0]->type == AST_BLOCK);
+ for (auto n : current_always->children[0]->children)
+ if (n == this) {
+ unconditional_init = true;
+ break;
+ }
+ }
+
+ newNode = readmem(str == "\\$readmemh", node_filename->bitsAsConst().decode_string(), node_memory->id2ast, start_addr, finish_addr, unconditional_init);
goto apply_newNode;
}
@@ -2085,10 +2097,15 @@ static void replace_result_wire_name_in_function(AstNode *node, std::string &fro
}
// replace a readmem[bh] TCALL ast node with a block of memory assignments
-AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr)
+AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init)
{
AstNode *block = new AstNode(AST_BLOCK);
+ AstNode *meminit = nullptr;
+ int next_meminit_cursor;
+ vector<State> meminit_bits;
+ int meminit_size;
+
std::ifstream f;
f.open(mem_filename.c_str());
@@ -2145,9 +2162,39 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m
AstNode *value = VERILOG_FRONTEND::const2ast((is_readmemh ? "'h" : "'b") + token);
- block->children.push_back(new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER, new AstNode(AST_RANGE, AstNode::mkconst_int(cursor, false))), value));
- block->children.back()->children[0]->str = memory->str;
- block->children.back()->children[0]->id2ast = memory;
+ if (unconditional_init)
+ {
+ if (meminit == nullptr || cursor != next_meminit_cursor)
+ {
+ if (meminit != nullptr) {
+ meminit->children[1] = AstNode::mkconst_bits(meminit_bits, false);
+ meminit->children[2] = AstNode::mkconst_int(meminit_size, false);
+ }
+
+ meminit = new AstNode(AST_MEMINIT);
+ meminit->children.push_back(AstNode::mkconst_int(cursor, false));
+ meminit->children.push_back(nullptr);
+ meminit->children.push_back(nullptr);
+ meminit->str = memory->str;
+ meminit->id2ast = memory;
+ meminit_bits.clear();
+ meminit_size = 0;
+
+ current_ast_mod->children.push_back(meminit);
+ next_meminit_cursor = cursor;
+ }
+
+ meminit_size++;
+ next_meminit_cursor++;
+ meminit_bits.insert(meminit_bits.end(), value->bits.begin(), value->bits.end());
+ delete value;
+ }
+ else
+ {
+ block->children.push_back(new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER, new AstNode(AST_RANGE, AstNode::mkconst_int(cursor, false))), value));
+ block->children.back()->children[0]->str = memory->str;
+ block->children.back()->children[0]->id2ast = memory;
+ }
if ((cursor == finish_addr) || (increment > 0 && cursor >= range_max) || (increment < 0 && cursor <= range_min))
break;
@@ -2158,6 +2205,11 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m
break;
}
+ if (meminit != nullptr) {
+ meminit->children[1] = AstNode::mkconst_bits(meminit_bits, false);
+ meminit->children[2] = AstNode::mkconst_int(meminit_size, false);
+ }
+
return block;
}