aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2016-08-19 18:38:25 +0200
committerClifford Wolf <clifford@clifford.at>2016-08-19 18:38:25 +0200
commitf6629b9c29838879cec6a94d6cb47afc6fbd2db4 (patch)
treea75ca899efb7a6d8889fada7a35e298521174457 /passes
parent9b8e06bee177f53c34a9dd6dd907a822f21659be (diff)
downloadyosys-f6629b9c29838879cec6a94d6cb47afc6fbd2db4.tar.gz
yosys-f6629b9c29838879cec6a94d6cb47afc6fbd2db4.tar.bz2
yosys-f6629b9c29838879cec6a94d6cb47afc6fbd2db4.zip
Optimize memory address port width in wreduce and memory_collect, not verilog front-end
Diffstat (limited to 'passes')
-rw-r--r--passes/memory/memory_collect.cc16
-rw-r--r--passes/opt/wreduce.cc18
2 files changed, 31 insertions, 3 deletions
diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc
index e068ef905..ab66e3fb8 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;
diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc
index 333541eab..b2f1bea7a 100644
--- a/passes/opt/wreduce.cc
+++ b/passes/opt/wreduce.cc
@@ -385,6 +385,7 @@ struct WreducePass : public Pass {
continue;
for (auto c : module->selected_cells())
+ {
if (c->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool",
"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
"$logic_not", "$logic_and", "$logic_or") && GetSize(c->getPort("\\Y")) > 1) {
@@ -396,6 +397,23 @@ struct WreducePass : public Pass {
module->connect(sig, Const(0, GetSize(sig)));
}
}
+ if (c->type.in("$memrd", "$memwr", "$meminit")) {
+ IdString memid = c->getParam("\\MEMID").decode_string();
+ RTLIL::Memory *mem = module->memories.at(memid);
+ if (mem->start_offset == 0) {
+ int cur_addrbits = c->getParam("\\ABITS").as_int();
+ int max_addrbits = ceil_log2(mem->size);
+ if (cur_addrbits > max_addrbits) {
+ log("Removed top %d address bits (of %d) from memory %s port %s.%s (%s).\n",
+ cur_addrbits-max_addrbits, cur_addrbits,
+ c->type == "$memrd" ? "read" : c->type == "$memwr" ? "write" : "init",
+ log_id(module), log_id(c), log_id(memid));
+ c->setParam("\\ABITS", max_addrbits);
+ c->setPort("\\ADDR", c->getPort("\\ADDR").extract(0, max_addrbits));
+ }
+ }
+ }
+ }
WreduceWorker worker(&config, module);
worker.run();