summaryrefslogtreecommitdiff
path: root/passes/memory/memory_collect.cc
diff options
context:
space:
mode:
Diffstat (limited to 'passes/memory/memory_collect.cc')
-rw-r--r--passes/memory/memory_collect.cc18
1 files changed, 14 insertions, 4 deletions
diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc
index 5c0acb3e..ab66e3fb 100644
--- a/passes/memory/memory_collect.cc
+++ b/passes/memory/memory_collect.cc
@@ -37,8 +37,6 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
log("Collecting $memrd, $memwr and $meminit for memory `%s' in module `%s':\n",
memory->name.c_str(), module->name.c_str());
- int addr_bits = 0;
-
Const init_data(State::Sx, memory->size * memory->width);
SigMap sigmap(module);
@@ -59,16 +57,28 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
SigSpec sig_rd_data;
SigSpec sig_rd_en;
+ int addr_bits = 0;
std::vector<Cell*> memcells;
for (auto &cell_it : module->cells_) {
Cell *cell = cell_it.second;
if (cell->type.in("$memrd", "$memwr", "$meminit") && memory->name == cell->parameters["\\MEMID"].decode_string()) {
- addr_bits = max(addr_bits, cell->getParam("\\ABITS").as_int());
+ SigSpec addr = sigmap(cell->getPort("\\ADDR"));
+ for (int i = 0; i < GetSize(addr); i++)
+ if (addr[i] != State::S0)
+ addr_bits = std::max(addr_bits, i+1);
memcells.push_back(cell);
}
}
+ if (memory->start_offset == 0 && addr_bits < 30 && (1 << addr_bits) < memory->size)
+ memory->size = 1 << addr_bits;
+
+ if (memory->start_offset >= 0)
+ addr_bits = std::min(addr_bits, ceil_log2(memory->size + memory->start_offset));
+
+ addr_bits = std::max(addr_bits, 1);
+
if (memcells.empty()) {
log(" no cells found. removing memory.\n");
return nullptr;
@@ -247,7 +257,7 @@ struct MemoryCollectPass : public Pass {
log("\n");
}
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
- log_header("Executing MEMORY_COLLECT pass (generating $mem cells).\n");
+ log_header(design, "Executing MEMORY_COLLECT pass (generating $mem cells).\n");
extra_args(args, 1, design);
for (auto &mod_it : design->modules_)
if (design->selected(mod_it.second))