From b065e090455fde5cb99d8008390b3947b5151755 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 17 Oct 2020 15:49:36 +0200 Subject: [PATCH] sim: Use Mem helper. --- passes/sat/sim.cc | 193 +++++++++++++++++++++------------------------- 1 file changed, 90 insertions(+), 103 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index fb496ff87..b7085369a 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -20,6 +20,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -62,6 +63,7 @@ struct SimInstance pool dirty_bits; pool dirty_cells; + pool dirty_memories; pool dirty_children; struct ff_state_t @@ -72,16 +74,20 @@ struct SimInstance struct mem_state_t { - Const past_wr_clk; - Const past_wr_en; - Const past_wr_addr; - Const past_wr_data; + Mem *mem; + std::vector past_wr_clk; + std::vector past_wr_en; + std::vector past_wr_addr; + std::vector past_wr_data; Const data; }; dict ff_database; - dict mem_database; + dict mem_database; pool formal_database; + dict mem_cells; + + std::vector memories; dict> vcd_database; @@ -118,6 +124,19 @@ struct SimInstance } } + memories = Mem::get_all_memories(module); + for (auto &mem : memories) { + auto &mdb = mem_database[mem.memid]; + mdb.mem = &mem; + for (auto &port : mem.wr_ports) { + mdb.past_wr_clk.push_back(Const(State::Sx)); + mdb.past_wr_en.push_back(Const(State::Sx, GetSize(port.en))); + mdb.past_wr_addr.push_back(Const(State::Sx, GetSize(port.addr))); + mdb.past_wr_data.push_back(Const(State::Sx, GetSize(port.data))); + } + mdb.data = mem.get_init_data(); + } + for (auto cell : module->cells()) { Module *mod = module->design->module(cell->type); @@ -143,29 +162,9 @@ struct SimInstance ff_database[cell] = ff; } - if (cell->type == ID($mem)) + if (cell->type.in(ID($mem), ID($meminit), ID($memwr), ID($memrd))) { - mem_state_t mem; - - mem.past_wr_clk = Const(State::Sx, GetSize(cell->getPort(ID::WR_CLK))); - mem.past_wr_en = Const(State::Sx, GetSize(cell->getPort(ID::WR_EN))); - mem.past_wr_addr = Const(State::Sx, GetSize(cell->getPort(ID::WR_ADDR))); - mem.past_wr_data = Const(State::Sx, GetSize(cell->getPort(ID::WR_DATA))); - - mem.data = cell->getParam(ID::INIT); - int sz = cell->getParam(ID::SIZE).as_int() * cell->getParam(ID::WIDTH).as_int(); - - if (GetSize(mem.data) > sz) - mem.data.bits.resize(sz); - - while (GetSize(mem.data) < sz) - mem.data.bits.push_back(State::Sx); - - mem_database[cell] = mem; - } - if (cell->type.in(ID($memwr),ID($memrd))) - { - log_error("$memrd and $memwr cells have to be merged to stand-alone $mem cells (execute memory_collect pass)\n"); + mem_cells[cell] = cell->parameters.at(ID::MEMID).decode_string(); } if (cell->type.in(ID($assert), ID($cover), ID($assume))) { formal_database.insert(cell); @@ -188,7 +187,8 @@ struct SimInstance for (auto &it : mem_database) { mem_state_t &mem = it.second; - zinit(mem.past_wr_en); + for (auto &val : mem.past_wr_en) + zinit(val); zinit(mem.data); } } @@ -259,37 +259,9 @@ struct SimInstance if (formal_database.count(cell)) return; - if (mem_database.count(cell)) + if (mem_cells.count(cell)) { - mem_state_t &mem = mem_database.at(cell); - - int num_rd_ports = cell->getParam(ID::RD_PORTS).as_int(); - - int size = cell->getParam(ID::SIZE).as_int(); - int offset = cell->getParam(ID::OFFSET).as_int(); - int abits = cell->getParam(ID::ABITS).as_int(); - int width = cell->getParam(ID::WIDTH).as_int(); - - if (cell->getParam(ID::RD_CLK_ENABLE).as_bool()) - log_error("Memory %s.%s has clocked read ports. Run 'memory' with -nordff.\n", log_id(module), log_id(cell)); - - SigSpec rd_addr_sig = cell->getPort(ID::RD_ADDR); - SigSpec rd_data_sig = cell->getPort(ID::RD_DATA); - - for (int port_idx = 0; port_idx < num_rd_ports; port_idx++) - { - Const addr = get_state(rd_addr_sig.extract(port_idx*abits, abits)); - Const data = Const(State::Sx, width); - - if (addr.is_fully_def()) { - int index = addr.as_int() - offset; - if (index >= 0 && index < size) - data = mem.data.extract(index*width, width); - } - - set_state(rd_data_sig.extract(port_idx*width, width), data); - } - + dirty_memories.insert(mem_cells[cell]); return; } @@ -352,6 +324,29 @@ struct SimInstance log_error("Unsupported cell type: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); } + void update_memory(IdString id) { + auto &mdb = mem_database[id]; + auto &mem = *mdb.mem; + + for (int port_idx = 0; port_idx < GetSize(mem.rd_ports); port_idx++) + { + auto &port = mem.rd_ports[port_idx]; + Const addr = get_state(port.addr); + Const data = Const(State::Sx, mem.width); + + if (port.clk_enable) + log_error("Memory %s.%s has clocked read ports. Run 'memory' with -nordff.\n", log_id(module), log_id(mem.memid)); + + if (addr.is_fully_def()) { + int index = addr.as_int() - mem.start_offset; + if (index >= 0 && index < mem.size) + data = mdb.data.extract(index*mem.width, mem.width); + } + + set_state(port.data, data); + } + } + void update_ph1() { pool queue_cells; @@ -383,6 +378,10 @@ struct SimInstance continue; } + for (auto &memid : dirty_memories) + update_memory(memid); + dirty_memories.clear(); + for (auto wire : queue_outports) if (instance->hasPort(wire->name)) { Const value = get_state(wire); @@ -426,50 +425,40 @@ struct SimInstance for (auto &it : mem_database) { - Cell *cell = it.first; - mem_state_t &mem = it.second; - - int num_wr_ports = cell->getParam(ID::WR_PORTS).as_int(); - - int size = cell->getParam(ID::SIZE).as_int(); - int offset = cell->getParam(ID::OFFSET).as_int(); - int abits = cell->getParam(ID::ABITS).as_int(); - int width = cell->getParam(ID::WIDTH).as_int(); + mem_state_t &mdb = it.second; + auto &mem = *mdb.mem; - Const wr_clk_enable = cell->getParam(ID::WR_CLK_ENABLE); - Const wr_clk_polarity = cell->getParam(ID::WR_CLK_POLARITY); - Const current_wr_clk = get_state(cell->getPort(ID::WR_CLK)); - - for (int port_idx = 0; port_idx < num_wr_ports; port_idx++) + for (int port_idx = 0; port_idx < GetSize(mem.wr_ports); port_idx++) { + auto &port = mem.wr_ports[port_idx]; Const addr, data, enable; - if (wr_clk_enable[port_idx] == State::S0) + if (!port.clk_enable) { - addr = get_state(cell->getPort(ID::WR_ADDR).extract(port_idx*abits, abits)); - data = get_state(cell->getPort(ID::WR_DATA).extract(port_idx*width, width)); - enable = get_state(cell->getPort(ID::WR_EN).extract(port_idx*width, width)); + addr = get_state(port.addr); + data = get_state(port.data); + enable = get_state(port.en); } else { - if (wr_clk_polarity[port_idx] == State::S1 ? - (mem.past_wr_clk[port_idx] == State::S1 || current_wr_clk[port_idx] != State::S1) : - (mem.past_wr_clk[port_idx] == State::S0 || current_wr_clk[port_idx] != State::S0)) + if (port.clk_polarity ? + (mdb.past_wr_clk[port_idx] == State::S1 || get_state(port.clk) != State::S1) : + (mdb.past_wr_clk[port_idx] == State::S0 || get_state(port.clk) != State::S0)) continue; - addr = mem.past_wr_addr.extract(port_idx*abits, abits); - data = mem.past_wr_data.extract(port_idx*width, width); - enable = mem.past_wr_en.extract(port_idx*width, width); + addr = mdb.past_wr_addr[port_idx]; + data = mdb.past_wr_data[port_idx]; + enable = mdb.past_wr_en[port_idx]; } if (addr.is_fully_def()) { - int index = addr.as_int() - offset; - if (index >= 0 && index < size) - for (int i = 0; i < width; i++) - if (enable[i] == State::S1 && mem.data.bits.at(index*width+i) != data[i]) { - mem.data.bits.at(index*width+i) = data[i]; - dirty_cells.insert(cell); + int index = addr.as_int() - mem.start_offset; + if (index >= 0 && index < mem.size) + for (int i = 0; i < mem.width; i++) + if (enable[i] == State::S1 && mdb.data.bits.at(index*mem.width+i) != data[i]) { + mdb.data.bits.at(index*mem.width+i) = data[i]; + dirty_memories.insert(mem.memid); did_something = true; } } @@ -500,13 +489,15 @@ struct SimInstance for (auto &it : mem_database) { - Cell *cell = it.first; mem_state_t &mem = it.second; - mem.past_wr_clk = get_state(cell->getPort(ID::WR_CLK)); - mem.past_wr_en = get_state(cell->getPort(ID::WR_EN)); - mem.past_wr_addr = get_state(cell->getPort(ID::WR_ADDR)); - mem.past_wr_data = get_state(cell->getPort(ID::WR_DATA)); + for (int i = 0; i < GetSize(mem.mem->wr_ports); i++) { + auto &port = mem.mem->wr_ports[i]; + mem.past_wr_clk[i] = get_state(port.clk); + mem.past_wr_en[i] = get_state(port.en); + mem.past_wr_addr[i] = get_state(port.addr); + mem.past_wr_data[i] = get_state(port.data); + } } for (auto cell : formal_database) @@ -561,17 +552,13 @@ struct SimInstance for (auto &it : mem_database) { - Cell *cell = it.first; mem_state_t &mem = it.second; - Const initval = mem.data; - - while (GetSize(initval) >= 2) { - if (initval[GetSize(initval)-1] != State::Sx) break; - if (initval[GetSize(initval)-2] != State::Sx) break; - initval.bits.pop_back(); - } - - cell->setParam(ID::INIT, initval); + mem.mem->clear_inits(); + MemInit minit; + minit.addr = mem.mem->start_offset; + minit.data = mem.data; + mem.mem->inits.push_back(minit); + mem.mem->emit(); } for (auto it : children) -- 2.30.2