diff options
author | Marcelina KoĆcielnicka <mwk@0x04.net> | 2021-05-22 20:19:00 +0200 |
---|---|---|
committer | Marcelina KoĆcielnicka <mwk@0x04.net> | 2021-05-22 22:31:07 +0200 |
commit | 039f4f48d55609f254850112a948f26e66550095 (patch) | |
tree | a3ea1d19cb7cf52fe98adcfc5d6049a4f435412c /passes/memory | |
parent | c4cc888b2c51a6507b73fdcde1dc61c37384105d (diff) | |
download | yosys-039f4f48d55609f254850112a948f26e66550095.tar.gz yosys-039f4f48d55609f254850112a948f26e66550095.tar.bz2 yosys-039f4f48d55609f254850112a948f26e66550095.zip |
memory_memx: Use Mem helper.
Diffstat (limited to 'passes/memory')
-rw-r--r-- | passes/memory/memory_memx.cc | 73 |
1 files changed, 31 insertions, 42 deletions
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 <sstream> -#include <set> -#include <stdlib.h> +#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<std::string> 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<Cell*> 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; |