From 039f4f48d55609f254850112a948f26e66550095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 20:19:00 +0200 Subject: memory_memx: Use Mem helper. --- passes/memory/memory_memx.cc | 73 +++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 42 deletions(-) (limited to 'passes') diff --git a/passes/memory/memory_memx.cc b/passes/memory/memory_memx.cc index 02e00cf30..11bbe75cc 100644 --- a/passes/memory/memory_memx.cc +++ b/passes/memory/memory_memx.cc @@ -17,11 +17,8 @@ * */ -#include "kernel/register.h" -#include "kernel/log.h" -#include -#include -#include +#include "kernel/yosys.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -38,53 +35,45 @@ struct MemoryMemxPass : public Pass { log("behavior for out-of-bounds memory reads and writes.\n"); log("\n"); } + + SigSpec make_addr_check(Mem &mem, SigSpec addr) { + int start_addr = mem.start_offset; + int end_addr = mem.start_offset + mem.size; + + addr.extend_u0(32); + + SigSpec res = mem.module->Nex(NEW_ID, mem.module->ReduceXor(NEW_ID, addr), mem.module->ReduceXor(NEW_ID, {addr, State::S1})); + if (start_addr != 0) + res = mem.module->LogicAnd(NEW_ID, res, mem.module->Ge(NEW_ID, addr, start_addr)); + res = mem.module->LogicAnd(NEW_ID, res, mem.module->Lt(NEW_ID, addr, end_addr)); + return res; + } + void execute(std::vector args, RTLIL::Design *design) override { log_header(design, "Executing MEMORY_MEMX pass (converting $mem cells to logic and flip-flops).\n"); extra_args(args, 1, design); for (auto module : design->selected_modules()) + for (auto &mem : Mem::get_selected_memories(module)) { - vector mem_port_cells; - - for (auto cell : module->selected_cells()) - if (cell->type.in(ID($memrd), ID($memwr))) - mem_port_cells.push_back(cell); - - for (auto cell : mem_port_cells) + for (auto &port : mem.rd_ports) { - IdString memid = cell->getParam(ID::MEMID).decode_string(); - RTLIL::Memory *mem = module->memories.at(memid); + if (port.clk_enable) + log_error("Memory %s.%s has a synchronous read port. Synchronous read ports are not supported by memory_memx!\n", + log_id(module), log_id(mem.memid)); - int lowest_addr = mem->start_offset; - int highest_addr = mem->start_offset + mem->size - 1; - - SigSpec addr = cell->getPort(ID::ADDR); - addr.extend_u0(32); - - SigSpec addr_ok = module->Nex(NEW_ID, module->ReduceXor(NEW_ID, addr), module->ReduceXor(NEW_ID, {addr, State::S1})); - if (lowest_addr != 0) - addr_ok = module->LogicAnd(NEW_ID, addr_ok, module->Ge(NEW_ID, addr, lowest_addr)); - addr_ok = module->LogicAnd(NEW_ID, addr_ok, module->Le(NEW_ID, addr, highest_addr)); - - if (cell->type == ID($memrd)) - { - if (cell->getParam(ID::CLK_ENABLE).as_bool()) - log_error("Cell %s.%s (%s) has an enabled clock. Clocked $memrd cells are not supported by memory_memx!\n", - log_id(module), log_id(cell), log_id(cell->type)); - - SigSpec rdata = cell->getPort(ID::DATA); - Wire *raw_rdata = module->addWire(NEW_ID, GetSize(rdata)); - module->addMux(NEW_ID, SigSpec(State::Sx, GetSize(rdata)), raw_rdata, addr_ok, rdata); - cell->setPort(ID::DATA, raw_rdata); - } + SigSpec addr_ok = make_addr_check(mem, port.addr); + Wire *raw_rdata = module->addWire(NEW_ID, GetSize(port.data)); + module->addMux(NEW_ID, SigSpec(State::Sx, GetSize(port.data)), raw_rdata, addr_ok, port.data); + port.data = raw_rdata; + } - if (cell->type == ID($memwr)) - { - SigSpec en = cell->getPort(ID::EN); - en = module->And(NEW_ID, en, addr_ok.repeat(GetSize(en))); - cell->setPort(ID::EN, en); - } + for (auto &port : mem.wr_ports) { + SigSpec addr_ok = make_addr_check(mem, port.addr); + port.en = module->And(NEW_ID, port.en, addr_ok.repeat(GetSize(port.en))); } + + mem.emit(); } } } MemoryMemxPass; -- cgit v1.2.3