36 std::string
genid(
RTLIL::IdString name, std::string token1 =
"",
int i = -1, std::string token2 =
"",
int j = -1, std::string token3 =
"",
int k = -1, std::string token4 =
"")
38 std::stringstream sstr;
39 sstr <<
"$memory" << name.
str() << token1;
42 sstr <<
"[" << i <<
"]";
47 sstr <<
"[" << j <<
"]";
52 sstr <<
"[" << k <<
"]";
54 sstr << token4 <<
"$" << (
autoidx++);
60 std::pair<RTLIL::SigSpec, RTLIL::SigSpec> key(addr_sig, addr_val);
67 int split_at =
GetSize(addr_sig) / 2;
81 std::set<int> static_ports;
82 std::map<int, RTLIL::SigSpec> static_cells_map;
83 int mem_size = cell->
parameters[
"\\SIZE"].as_int();
84 int mem_width = cell->
parameters[
"\\WIDTH"].as_int();
85 int mem_offset = cell->
parameters[
"\\OFFSET"].as_int();
86 int mem_abits = cell->
parameters[
"\\ABITS"].as_int();
89 if (cell->
parameters[
"\\RD_PORTS"].as_int() == 0 && cell->
parameters[
"\\WR_PORTS"].as_int() == 0) {
100 for (
int i = 0; i < clocks.
size(); i++) {
103 static_ports.insert(i);
113 static_cells_map[wr_addr.
as_int()] = wr_data;
114 static_ports.insert(i);
117 log(
"Not mapping memory cell %s in module %s (write port %d has no clock).\n",
121 if (refclock.
size() == 0) {
122 refclock = clocks.
extract(i, 1);
123 refclock_pol = clocks_pol.
bits[i];
125 if (clocks.
extract(i, 1) != refclock || clocks_pol.
bits[i] != refclock_pol) {
126 log(
"Not mapping memory cell %s in module %s (write clock %d is incompatible with other clocks).\n",
134 std::vector<RTLIL::SigSpec> data_reg_in;
135 std::vector<RTLIL::SigSpec> data_reg_out;
137 int count_static = 0;
139 for (
int i = 0; i < mem_size; i++)
141 if (static_cells_map.count(i) > 0)
144 data_reg_out.push_back(static_cells_map[i]);
151 if (clocks_pol.
bits.size() > 0) {
161 c->
setPort(
"\\D", data_reg_in.back());
163 std::string w_out_name =
stringf(
"%s[%d]", cell->
parameters[
"\\MEMID"].decode_string().c_str(), i);
165 w_out_name =
genid(cell->
name,
"", i,
"$q");
171 c->
setPort(
"\\Q", data_reg_out.back());
175 log(
" created %d $dff cells and %d static cells of width %d.\n", mem_size-count_static, count_static, mem_width);
177 int count_dff = 0, count_mux = 0, count_wrmux = 0;
179 for (
int i = 0; i < cell->
parameters[
"\\RD_PORTS"].as_int(); i++)
183 std::vector<RTLIL::SigSpec> rd_signals;
184 rd_signals.push_back(cell->
getPort(
"\\RD_DATA").
extract(i*mem_width, mem_width));
208 c->
setPort(
"\\Q", rd_signals.back());
215 c->
setPort(
"\\D", rd_signals.back());
219 for (
int j = 0; j < mem_abits; j++)
221 std::vector<RTLIL::SigSpec> next_rd_signals;
223 for (
size_t k = 0; k < rd_signals.size(); k++)
227 c->
setPort(
"\\Y", rd_signals[k]);
234 next_rd_signals.push_back(c->
getPort(
"\\A"));
235 next_rd_signals.push_back(c->
getPort(
"\\B"));
238 next_rd_signals.swap(rd_signals);
241 for (
int j = 0; j < mem_size; j++)
245 log(
" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux);
247 for (
int i = 0; i < mem_size; i++)
249 if (static_cells_map.count(i) > 0)
254 for (
int j = 0; j < cell->
parameters[
"\\WR_PORTS"].as_int(); j++)
262 while (wr_offset < wr_en.
size())
267 while (wr_offset + wr_width < wr_en.
size()) {
269 if (next_wr_bit != wr_bit)
301 wr_offset += wr_width;
309 log(
" write interface: %d write mux blocks.\n", count_wrmux);
316 std::vector<RTLIL::Cell*> cells;
318 if (cell->type ==
"$mem" && design->
selected(module, cell))
319 cells.push_back(cell);
320 for (
auto cell : cells)
331 log(
" memory_map [selection]\n");
333 log(
"This pass converts multiport memory cells as generated by the memory_collect\n");
334 log(
"pass to word-wide DFFs and address decoders.\n");
338 log_header(
"Executing MEMORY_MAP pass (converting $mem cells to logic and flip-flops).\n");
const char * c_str() const
bool selected(T1 *module) const
std::string stringf(const char *fmt,...)
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
void log_header(const char *format,...)
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
std::map< RTLIL::IdString, RTLIL::Const > parameters
std::map< std::pair< RTLIL::SigSpec, RTLIL::SigSpec >, RTLIL::SigBit > decoder_cache
RTLIL::SigSpec Eq(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed=false)
void connect(const RTLIL::SigSig &conn)
#define PRIVATE_NAMESPACE_BEGIN
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
int GetSize(RTLIL::Wire *wire)
#define log_assert(_assert_expr_)
bool is_fully_const() const
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
std::vector< RTLIL::Cell * > selected_cells() const
#define PRIVATE_NAMESPACE_END
#define USING_YOSYS_NAMESPACE
void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
int as_int(bool is_signed=false) const
void remove(const std::set< RTLIL::Wire * > &wires)
MemoryMapWorker(RTLIL::Design *design, RTLIL::Module *module)
void log(const char *format,...)
void handle_cell(RTLIL::Cell *cell)
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
RTLIL::SigSpec And(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed=false)
std::vector< RTLIL::State > bits
std::vector< RTLIL::Module * > selected_modules() const
RTLIL::Wire * addr_decode(RTLIL::SigSpec addr_sig, RTLIL::SigSpec addr_val)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
std::string genid(RTLIL::IdString name, std::string token1="", int i=-1, std::string token2="", int j=-1, std::string token3="", int k=-1, std::string token4="")
std::pair< SigSpec, SigSpec > SigSig
YOSYS_NAMESPACE_BEGIN int autoidx
MemoryMapPass MemoryMapPass