From: Clifford Wolf Date: Thu, 21 Apr 2016 10:06:07 +0000 (+0200) Subject: Bugfix and improvements in memory_share X-Git-Tag: yosys-0.7~254^2~8 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1761d08dd239bcf1765ebf807fc22514edac387f;p=yosys.git Bugfix and improvements in memory_share --- diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index ab9edb6e7..844f4296f 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -43,7 +43,7 @@ struct MemoryShareWorker CellTypes cone_ct; std::map> sig_to_mux; - std::map>, RTLIL::SigBit> conditions_logic_cache; + std::map>, SigBit>, SigBit> conditions_logic_cache; // ----------------------------------------------------------------- @@ -109,10 +109,12 @@ struct MemoryShareWorker return false; } - RTLIL::SigBit conditions_to_logic(std::set> &conditions, int &created_conditions) + RTLIL::SigBit conditions_to_logic(std::set> &conditions, SigBit olden, int &created_conditions) { - if (conditions_logic_cache.count(conditions)) - return conditions_logic_cache.at(conditions); + auto key = make_pair(conditions, olden); + + if (conditions_logic_cache.count(key)) + return conditions_logic_cache.at(key); RTLIL::SigSpec terms; for (auto &cond : conditions) { @@ -125,13 +127,16 @@ struct MemoryShareWorker created_conditions++; } - if (terms.size() == 0) + if (olden.wire != nullptr || olden != State::S1) + terms.append(olden); + + if (GetSize(terms) == 0) terms = State::S1; - if (terms.size() > 1) + if (GetSize(terms) > 1) terms = module->ReduceAnd(NEW_ID, terms); - return conditions_logic_cache[conditions] = terms; + return conditions_logic_cache[key] = terms; } void translate_rd_feedback_to_en(std::string memid, std::vector &rd_ports, std::vector &wr_ports) @@ -140,15 +145,14 @@ struct MemoryShareWorker std::map> muxtree_upstream_map; std::set non_feedback_nets; - for (auto wire_it : module->wires_) - if (wire_it.second->port_output) { - std::vector bits = RTLIL::SigSpec(wire_it.second); + for (auto wire : module->wires()) + if (wire->port_output) { + std::vector bits = sigmap(wire); non_feedback_nets.insert(bits.begin(), bits.end()); } - for (auto cell_it : module->cells_) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = cell_it.second; bool ignore_data_port = false; if (cell->type == "$mux" || cell->type == "$pmux") @@ -173,7 +177,7 @@ struct MemoryShareWorker cell->parameters.at("\\MEMID").decode_string() == memid) ignore_data_port = true; - for (auto conn : cell_it.second->connections()) + for (auto conn : cell->connections()) { if (ignore_data_port && conn.first == "\\DATA") continue; @@ -240,13 +244,8 @@ struct MemoryShareWorker std::map state; std::set> conditions; - if (cell_en[i].wire != NULL) { - state[cell_en[i]] = false; - conditions.insert(state); - } - find_data_feedback(async_rd_bits.at(sig_addr).at(i), cell_data[i], state, conditions); - cell_en[i] = conditions_to_logic(conditions, created_conditions); + cell_en[i] = conditions_to_logic(conditions, cell_en[i], created_conditions); } if (created_conditions) { @@ -666,10 +665,8 @@ struct MemoryShareWorker std::map, std::vector>> memindex; sigmap_xmux = sigmap; - for (auto &it : module->cells_) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = it.second; - if (cell->type == "$memrd") memindex[cell->parameters.at("\\MEMID").decode_string()].first.push_back(cell); diff --git a/tests/simple/memory.v b/tests/simple/memory.v index d58ed9d1a..9fddce26c 100644 --- a/tests/simple/memory.v +++ b/tests/simple/memory.v @@ -243,3 +243,24 @@ module memtest10(input clk, input [5:0] din, output [5:0] dout); assign dout = queue[3]; endmodule + +// ---------------------------------------------------------- + +module memtest11(clk, wen, waddr, raddr, wdata, rdata); + input clk, wen; + input [1:0] waddr, raddr; + input [7:0] wdata; + output [7:0] rdata; + + reg [7:0] mem [3:0]; + + assign rdata = mem[raddr]; + + always @(posedge clk) begin + if (wen) + mem[waddr] <= wdata; + else + mem[waddr] <= mem[waddr]; + end +endmodule +