yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
memory_collect.cc File Reference
#include "kernel/register.h"
#include "kernel/log.h"
#include <sstream>
#include <algorithm>
#include <stdlib.h>
+ Include dependency graph for memory_collect.cc:

Go to the source code of this file.

Data Structures

struct  MemoryCollectPass
 

Functions

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN bool 
memcells_cmp (RTLIL::Cell *a, RTLIL::Cell *b)
 
void handle_memory (RTLIL::Module *module, RTLIL::Memory *memory)
 
static void handle_module (RTLIL::Design *design, RTLIL::Module *module)
 

Variables

MemoryCollectPass MemoryCollectPass
 

Function Documentation

void handle_memory ( RTLIL::Module module,
RTLIL::Memory memory 
)

Definition at line 38 of file memory_collect.cc.

39 {
40  log("Collecting $memrd and $memwr for memory `%s' in module `%s':\n",
41  memory->name.c_str(), module->name.c_str());
42 
43  int addr_bits = 0;
44  while ((1 << addr_bits) < memory->size)
45  addr_bits++;
46 
47  int wr_ports = 0;
48  RTLIL::SigSpec sig_wr_clk;
49  RTLIL::SigSpec sig_wr_clk_enable;
50  RTLIL::SigSpec sig_wr_clk_polarity;
51  RTLIL::SigSpec sig_wr_addr;
52  RTLIL::SigSpec sig_wr_data;
53  RTLIL::SigSpec sig_wr_en;
54 
55  int rd_ports = 0;
56  RTLIL::SigSpec sig_rd_clk;
57  RTLIL::SigSpec sig_rd_clk_enable;
58  RTLIL::SigSpec sig_rd_clk_polarity;
59  RTLIL::SigSpec sig_rd_transparent;
60  RTLIL::SigSpec sig_rd_addr;
61  RTLIL::SigSpec sig_rd_data;
62 
63  std::vector<RTLIL::Cell*> del_cells;
64  std::vector<RTLIL::Cell*> memcells;
65 
66  for (auto &cell_it : module->cells_) {
67  RTLIL::Cell *cell = cell_it.second;
68  if ((cell->type == "$memwr" || cell->type == "$memrd") && memory->name == cell->parameters["\\MEMID"].decode_string())
69  memcells.push_back(cell);
70  }
71 
72  std::sort(memcells.begin(), memcells.end(), memcells_cmp);
73 
74  for (auto cell : memcells)
75  {
76  if (cell->type == "$memwr" && memory->name == cell->parameters["\\MEMID"].decode_string())
77  {
78  wr_ports++;
79  del_cells.push_back(cell);
80 
81  RTLIL::SigSpec clk = cell->getPort("\\CLK");
82  RTLIL::SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]);
83  RTLIL::SigSpec clk_polarity = RTLIL::SigSpec(cell->parameters["\\CLK_POLARITY"]);
84  RTLIL::SigSpec addr = cell->getPort("\\ADDR");
85  RTLIL::SigSpec data = cell->getPort("\\DATA");
86  RTLIL::SigSpec en = cell->getPort("\\EN");
87 
88  clk.extend(1, false);
89  clk_enable.extend(1, false);
90  clk_polarity.extend(1, false);
91  addr.extend(addr_bits, false);
92  data.extend(memory->width, false);
93  en.extend(memory->width, false);
94 
95  sig_wr_clk.append(clk);
96  sig_wr_clk_enable.append(clk_enable);
97  sig_wr_clk_polarity.append(clk_polarity);
98  sig_wr_addr.append(addr);
99  sig_wr_data.append(data);
100  sig_wr_en.append(en);
101  }
102 
103  if (cell->type == "$memrd" && memory->name == cell->parameters["\\MEMID"].decode_string())
104  {
105  rd_ports++;
106  del_cells.push_back(cell);
107 
108  RTLIL::SigSpec clk = cell->getPort("\\CLK");
109  RTLIL::SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]);
110  RTLIL::SigSpec clk_polarity = RTLIL::SigSpec(cell->parameters["\\CLK_POLARITY"]);
111  RTLIL::SigSpec transparent = RTLIL::SigSpec(cell->parameters["\\TRANSPARENT"]);
112  RTLIL::SigSpec addr = cell->getPort("\\ADDR");
113  RTLIL::SigSpec data = cell->getPort("\\DATA");
114 
115  clk.extend(1, false);
116  clk_enable.extend(1, false);
117  clk_polarity.extend(1, false);
118  transparent.extend(1, false);
119  addr.extend(addr_bits, false);
120  data.extend(memory->width, false);
121 
122  sig_rd_clk.append(clk);
123  sig_rd_clk_enable.append(clk_enable);
124  sig_rd_clk_polarity.append(clk_polarity);
125  sig_rd_transparent.append(transparent);
126  sig_rd_addr.append(addr);
127  sig_rd_data.append(data);
128  }
129  }
130 
131  std::stringstream sstr;
132  sstr << "$mem$" << memory->name.str() << "$" << (autoidx++);
133 
134  RTLIL::Cell *mem = module->addCell(sstr.str(), "$mem");
135  mem->parameters["\\MEMID"] = RTLIL::Const(memory->name.str());
136  mem->parameters["\\WIDTH"] = RTLIL::Const(memory->width);
137  mem->parameters["\\OFFSET"] = RTLIL::Const(memory->start_offset);
138  mem->parameters["\\SIZE"] = RTLIL::Const(memory->size);
139  mem->parameters["\\ABITS"] = RTLIL::Const(addr_bits);
140 
141  log_assert(sig_wr_clk.size() == wr_ports);
142  log_assert(sig_wr_clk_enable.size() == wr_ports && sig_wr_clk_enable.is_fully_const());
143  log_assert(sig_wr_clk_polarity.size() == wr_ports && sig_wr_clk_polarity.is_fully_const());
144  log_assert(sig_wr_addr.size() == wr_ports * addr_bits);
145  log_assert(sig_wr_data.size() == wr_ports * memory->width);
146  log_assert(sig_wr_en.size() == wr_ports * memory->width);
147 
148  mem->parameters["\\WR_PORTS"] = RTLIL::Const(wr_ports);
149  mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : RTLIL::Const(0, 0);
150  mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.as_const() : RTLIL::Const(0, 0);
151 
152  mem->setPort("\\WR_CLK", sig_wr_clk);
153  mem->setPort("\\WR_ADDR", sig_wr_addr);
154  mem->setPort("\\WR_DATA", sig_wr_data);
155  mem->setPort("\\WR_EN", sig_wr_en);
156 
157  log_assert(sig_rd_clk.size() == rd_ports);
158  log_assert(sig_rd_clk_enable.size() == rd_ports && sig_rd_clk_enable.is_fully_const());
159  log_assert(sig_rd_clk_polarity.size() == rd_ports && sig_rd_clk_polarity.is_fully_const());
160  log_assert(sig_rd_addr.size() == rd_ports * addr_bits);
161  log_assert(sig_rd_data.size() == rd_ports * memory->width);
162 
163  mem->parameters["\\RD_PORTS"] = RTLIL::Const(rd_ports);
164  mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.as_const() : RTLIL::Const(0, 0);
165  mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.as_const() : RTLIL::Const(0, 0);
166  mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.as_const() : RTLIL::Const(0, 0);
167 
168  mem->setPort("\\RD_CLK", sig_rd_clk);
169  mem->setPort("\\RD_ADDR", sig_rd_addr);
170  mem->setPort("\\RD_DATA", sig_rd_data);
171 
172  for (auto c : del_cells)
173  module->remove(c);
174 }
const char * c_str() const
Definition: rtlil.h:178
std::string str() const
Definition: rtlil.h:182
void sort(T *array, int size, LessThan lt)
Definition: Sort.h:57
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
Definition: rtlil.cc:1353
bool clk_polarity
Definition: abc.cc:98
RTLIL::Const as_const() const
Definition: rtlil.cc:2857
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
Definition: rtlil.cc:1789
RTLIL::IdString type
Definition: rtlil.h:854
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856
int size
Definition: rtlil.h:836
int size() const
Definition: rtlil.h:1019
int start_offset
Definition: rtlil.h:836
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
Definition: rtlil.cc:1809
RTLIL::IdString name
Definition: rtlil.h:835
#define log_assert(_assert_expr_)
Definition: log.h:85
bool is_fully_const() const
Definition: rtlil.cc:2763
RTLIL::IdString name
Definition: rtlil.h:599
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool memcells_cmp(RTLIL::Cell *a, RTLIL::Cell *b)
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
Definition: rtlil.h:596
void remove(const std::set< RTLIL::Wire * > &wires)
Definition: rtlil.cc:1158
void log(const char *format,...)
Definition: log.cc:180
void append(const RTLIL::SigSpec &signal)
Definition: rtlil.cc:2523
void extend(int width, bool is_signed=false)
Definition: rtlil.cc:2593
int width
Definition: rtlil.h:836
YOSYS_NAMESPACE_BEGIN int autoidx
Definition: yosys.cc:51

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void handle_module ( RTLIL::Design design,
RTLIL::Module module 
)
static

Definition at line 176 of file memory_collect.cc.

177 {
178  std::vector<RTLIL::IdString> delme;
179  for (auto &mem_it : module->memories)
180  if (design->selected(module, mem_it.second)) {
181  handle_memory(module, mem_it.second);
182  delme.push_back(mem_it.first);
183  }
184  for (auto &it : delme) {
185  delete module->memories.at(it);
186  module->memories.erase(it);
187  }
188 }
bool selected(T1 *module) const
Definition: rtlil.h:551
std::map< RTLIL::IdString, RTLIL::Memory * > memories
Definition: rtlil.h:601
void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Definition at line 29 of file memory_collect.cc.

30 {
31  if (a->type == "$memrd" && b->type == "$memrd")
32  return a->name < b->name;
33  if (a->type == "$memrd" || b->type == "$memrd")
34  return (a->type == "$memrd") < (b->type == "$memrd");
35  return a->parameters.at("\\PRIORITY").as_int() < b->parameters.at("\\PRIORITY").as_int();
36 }
RTLIL::IdString name
Definition: rtlil.h:853
RTLIL::IdString type
Definition: rtlil.h:854
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856

+ Here is the caller graph for this function:

Variable Documentation