yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
memory_unpack.cc
Go to the documentation of this file.
1 /*
2  * yosys -- Yosys Open SYnthesis Suite
3  *
4  * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  */
19 
20 #include "kernel/register.h"
21 #include "kernel/log.h"
22 #include <sstream>
23 #include <algorithm>
24 #include <stdlib.h>
25 
28 
30 {
31  log("Creating $memrd and $memwr for memory `%s' in module `%s':\n",
32  memory->name.c_str(), module->name.c_str());
33 
34  RTLIL::IdString mem_name = RTLIL::escape_id(memory->parameters.at("\\MEMID").decode_string());
35 
36  while (module->memories.count(mem_name) != 0)
37  mem_name = mem_name.str() + stringf("_%d", autoidx++);
38 
39  RTLIL::Memory *mem = new RTLIL::Memory;
40  mem->name = mem_name;
41  mem->width = memory->parameters.at("\\WIDTH").as_int();
42  mem->start_offset = memory->parameters.at("\\OFFSET").as_int();
43  mem->size = memory->parameters.at("\\SIZE").as_int();
44  module->memories[mem_name] = mem;
45 
46  int abits = memory->parameters.at("\\ABITS").as_int();
47  int num_rd_ports = memory->parameters.at("\\RD_PORTS").as_int();
48  int num_wr_ports = memory->parameters.at("\\WR_PORTS").as_int();
49 
50  for (int i = 0; i < num_rd_ports; i++)
51  {
52  RTLIL::Cell *cell = module->addCell(NEW_ID, "$memrd");
53  cell->parameters["\\MEMID"] = mem_name.str();
54  cell->parameters["\\ABITS"] = memory->parameters.at("\\ABITS");
55  cell->parameters["\\WIDTH"] = memory->parameters.at("\\WIDTH");
56  cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_ENABLE")).extract(i, 1).as_const();
57  cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_POLARITY")).extract(i, 1).as_const();
58  cell->parameters["\\TRANSPARENT"] = RTLIL::SigSpec(memory->parameters.at("\\RD_TRANSPARENT")).extract(i, 1).as_const();
59  cell->setPort("\\CLK", memory->getPort("\\RD_CLK").extract(i, 1));
60  cell->setPort("\\ADDR", memory->getPort("\\RD_ADDR").extract(i*abits, abits));
61  cell->setPort("\\DATA", memory->getPort("\\RD_DATA").extract(i*mem->width, mem->width));
62  }
63 
64  for (int i = 0; i < num_wr_ports; i++)
65  {
66  RTLIL::Cell *cell = module->addCell(NEW_ID, "$memwr");
67  cell->parameters["\\MEMID"] = mem_name.str();
68  cell->parameters["\\ABITS"] = memory->parameters.at("\\ABITS");
69  cell->parameters["\\WIDTH"] = memory->parameters.at("\\WIDTH");
70  cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_ENABLE")).extract(i, 1).as_const();
71  cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_POLARITY")).extract(i, 1).as_const();
72  cell->parameters["\\PRIORITY"] = i;
73  cell->setPort("\\CLK", memory->getPort("\\WR_CLK").extract(i, 1));
74  cell->setPort("\\EN", memory->getPort("\\WR_EN").extract(i*mem->width, mem->width));
75  cell->setPort("\\ADDR", memory->getPort("\\WR_ADDR").extract(i*abits, abits));
76  cell->setPort("\\DATA", memory->getPort("\\WR_DATA").extract(i*mem->width, mem->width));
77  }
78 
79  module->remove(memory);
80 }
81 
83 {
84  std::vector<RTLIL::IdString> memcells;
85  for (auto &cell_it : module->cells_)
86  if (cell_it.second->type == "$mem" && design->selected(module, cell_it.second))
87  memcells.push_back(cell_it.first);
88  for (auto &it : memcells)
89  handle_memory(module, module->cells_.at(it));
90 }
91 
92 struct MemoryUnpackPass : public Pass {
93  MemoryUnpackPass() : Pass("memory_unpack", "unpack multi-port memory cells") { }
94  virtual void help()
95  {
96  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
97  log("\n");
98  log(" memory_unpack [selection]\n");
99  log("\n");
100  log("This pass converts the multi-port $mem memory cells into individual $memrd and\n");
101  log("$memwr cells. It is the counterpart to the memory_collect pass.\n");
102  log("\n");
103  }
104  virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
105  log_header("Executing MEMORY_UNPACK pass (generating $memrd/$memwr cells form $mem cells).\n");
106  extra_args(args, 1, design);
107  for (auto &mod_it : design->modules_)
108  if (design->selected(mod_it.second))
109  handle_module(design, mod_it.second);
110  }
112 
const char * c_str() const
Definition: rtlil.h:178
bool selected(T1 *module) const
Definition: rtlil.h:551
std::string stringf(const char *fmt,...)
Definition: yosys.cc:58
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
Definition: rtlil.cc:1353
void log_header(const char *format,...)
Definition: log.cc:188
RTLIL::Const as_const() const
Definition: rtlil.cc:2857
RTLIL::IdString name
Definition: rtlil.h:853
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
Definition: rtlil.cc:1789
std::map< RTLIL::IdString, RTLIL::Memory * > memories
Definition: rtlil.h:601
RTLIL::Module * module
Definition: abc.cc:94
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856
int size
Definition: rtlil.h:836
void handle_module(RTLIL::Design *design, RTLIL::Module *module)
int start_offset
Definition: rtlil.h:836
static std::string escape_id(std::string str)
Definition: rtlil.h:251
#define PRIVATE_NAMESPACE_BEGIN
Definition: yosys.h:97
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
Definition: rtlil.cc:1809
RTLIL::IdString name
Definition: rtlil.h:835
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory)
RTLIL::IdString name
Definition: rtlil.h:599
#define NEW_ID
Definition: yosys.h:166
#define PRIVATE_NAMESPACE_END
Definition: yosys.h:98
Definition: register.h:27
#define USING_YOSYS_NAMESPACE
Definition: yosys.h:102
std::map< RTLIL::IdString, RTLIL::Module * > modules_
Definition: rtlil.h:507
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
Definition: rtlil.h:596
void remove(const std::set< RTLIL::Wire * > &wires)
Definition: rtlil.cc:1158
MemoryUnpackPass MemoryUnpackPass
void log(const char *format,...)
Definition: log.cc:180
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
Definition: rtlil.cc:2414
virtual void help()
int width
Definition: rtlil.h:836
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
Definition: register.cc:128
YOSYS_NAMESPACE_BEGIN int autoidx
Definition: yosys.cc:51