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

Go to the source code of this file.

Data Structures

struct  MemoryDffPass
 

Functions

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN void 
normalize_sig (RTLIL::Module *module, RTLIL::SigSpec &sig)
 
bool find_sig_before_dff (RTLIL::Module *module, std::vector< RTLIL::Cell * > &dff_cells, RTLIL::SigSpec &sig, RTLIL::SigSpec &clk, bool &clk_polarity, bool after=false)
 
void handle_wr_cell (RTLIL::Module *module, std::vector< RTLIL::Cell * > &dff_cells, RTLIL::Cell *cell)
 
void disconnect_dff (RTLIL::Module *module, RTLIL::SigSpec sig)
 
void handle_rd_cell (RTLIL::Module *module, std::vector< RTLIL::Cell * > &dff_cells, RTLIL::Cell *cell)
 
void handle_module (RTLIL::Module *module, bool flag_wr_only)
 

Variables

MemoryDffPass MemoryDffPass
 

Function Documentation

void disconnect_dff ( RTLIL::Module module,
RTLIL::SigSpec  sig 
)

Definition at line 111 of file memory_dff.cc.

112 {
113  normalize_sig(module, sig);
114  sig.sort_and_unify();
115 
116  std::stringstream sstr;
117  sstr << "$memory_dff_disconnected$" << (autoidx++);
118 
119  RTLIL::SigSpec new_sig = module->addWire(sstr.str(), sig.size());
120 
121  for (auto cell : module->cells())
122  if (cell->type == "$dff") {
123  RTLIL::SigSpec new_q = cell->getPort("\\Q");
124  new_q.replace(sig, new_sig);
125  cell->setPort("\\Q", new_q);
126  }
127 }
int size() const
Definition: rtlil.h:1019
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
Definition: rtlil.cc:1331
RTLIL::ObjRange< RTLIL::Cell * > cells()
Definition: rtlil.h:641
void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
Definition: rtlil.cc:2297
void sort_and_unify()
Definition: rtlil.cc:2291
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN void normalize_sig(RTLIL::Module *module, RTLIL::SigSpec &sig)
Definition: memory_dff.cc:28
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:

bool find_sig_before_dff ( RTLIL::Module module,
std::vector< RTLIL::Cell * > &  dff_cells,
RTLIL::SigSpec sig,
RTLIL::SigSpec clk,
bool &  clk_polarity,
bool  after = false 
)

Definition at line 34 of file memory_dff.cc.

35 {
36  normalize_sig(module, sig);
37 
38  for (auto &bit : sig)
39  {
40  if (bit.wire == NULL)
41  continue;
42 
43  for (auto cell : dff_cells)
44  {
45  if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) {
46  if (cell->getPort("\\CLK") != clk)
47  continue;
48  if (cell->parameters["\\CLK_POLARITY"].as_bool() != clk_polarity)
49  continue;
50  }
51 
52  RTLIL::SigSpec q_norm = cell->getPort(after ? "\\D" : "\\Q");
53  normalize_sig(module, q_norm);
54 
55  RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(after ? "\\Q" : "\\D"));
56  if (d.size() != 1)
57  continue;
58 
59  bit = d;
60  clk = cell->getPort("\\CLK");
61  clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool();
62  goto replaced_this_bit;
63  }
64 
65  return false;
66  replaced_this_bit:;
67  }
68 
69  return true;
70 }
bool clk_polarity
Definition: abc.cc:98
int size() const
Definition: rtlil.h:1019
#define NULL
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN void normalize_sig(RTLIL::Module *module, RTLIL::SigSpec &sig)
Definition: memory_dff.cc:28
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
Definition: rtlil.cc:2414

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void handle_module ( RTLIL::Module module,
bool  flag_wr_only 
)

Definition at line 167 of file memory_dff.cc.

168 {
169  std::vector<RTLIL::Cell*> dff_cells;
170 
171  for (auto cell : module->cells())
172  if (cell->type == "$dff")
173  dff_cells.push_back(cell);
174 
175  for (auto cell : module->selected_cells())
176  if (cell->type == "$memwr" && !cell->parameters["\\CLK_ENABLE"].as_bool())
177  handle_wr_cell(module, dff_cells, cell);
178 
179  if (!flag_wr_only)
180  for (auto cell : module->selected_cells())
181  if (cell->type == "$memrd" && !cell->parameters["\\CLK_ENABLE"].as_bool())
182  handle_rd_cell(module, dff_cells, cell);
183 }
void handle_wr_cell(RTLIL::Module *module, std::vector< RTLIL::Cell * > &dff_cells, RTLIL::Cell *cell)
Definition: memory_dff.cc:72
void handle_rd_cell(RTLIL::Module *module, std::vector< RTLIL::Cell * > &dff_cells, RTLIL::Cell *cell)
Definition: memory_dff.cc:129
std::vector< RTLIL::Cell * > selected_cells() const
Definition: rtlil.cc:1103
RTLIL::ObjRange< RTLIL::Cell * > cells()
Definition: rtlil.h:641

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void handle_rd_cell ( RTLIL::Module module,
std::vector< RTLIL::Cell * > &  dff_cells,
RTLIL::Cell cell 
)

Definition at line 129 of file memory_dff.cc.

130 {
131  log("Checking cell `%s' in module `%s': ", cell->name.c_str(), module->name.c_str());
132 
133  bool clk_polarity = 0;
134 
136  RTLIL::SigSpec sig_data = cell->getPort("\\DATA");
137  if (find_sig_before_dff(module, dff_cells, sig_data, clk_data, clk_polarity, true) &&
138  clk_data != RTLIL::SigSpec(RTLIL::State::Sx))
139  {
140  disconnect_dff(module, sig_data);
141  cell->setPort("\\CLK", clk_data);
142  cell->setPort("\\DATA", sig_data);
143  cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
144  cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
145  cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0);
146  log("merged data $dff to cell.\n");
147  return;
148  }
149 
151  RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR");
152  if (find_sig_before_dff(module, dff_cells, sig_addr, clk_addr, clk_polarity) &&
153  clk_addr != RTLIL::SigSpec(RTLIL::State::Sx))
154  {
155  cell->setPort("\\CLK", clk_addr);
156  cell->setPort("\\ADDR", sig_addr);
157  cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
158  cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
159  cell->parameters["\\TRANSPARENT"] = RTLIL::Const(1);
160  log("merged address $dff to cell.\n");
161  return;
162  }
163 
164  log("no (compatible) $dff found.\n");
165 }
const char * c_str() const
Definition: rtlil.h:178
bool clk_polarity
Definition: abc.cc:98
RTLIL::IdString name
Definition: rtlil.h:853
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
Definition: rtlil.cc:1789
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
Definition: rtlil.cc:1809
RTLIL::IdString name
Definition: rtlil.h:599
void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig)
Definition: memory_dff.cc:111
void log(const char *format,...)
Definition: log.cc:180
bool find_sig_before_dff(RTLIL::Module *module, std::vector< RTLIL::Cell * > &dff_cells, RTLIL::SigSpec &sig, RTLIL::SigSpec &clk, bool &clk_polarity, bool after=false)
Definition: memory_dff.cc:34

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void handle_wr_cell ( RTLIL::Module module,
std::vector< RTLIL::Cell * > &  dff_cells,
RTLIL::Cell cell 
)

Definition at line 72 of file memory_dff.cc.

73 {
74  log("Checking cell `%s' in module `%s': ", cell->name.c_str(), module->name.c_str());
75 
77  bool clk_polarity = 0;
78 
79  RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR");
80  if (!find_sig_before_dff(module, dff_cells, sig_addr, clk, clk_polarity)) {
81  log("no (compatible) $dff for address input found.\n");
82  return;
83  }
84 
85  RTLIL::SigSpec sig_data = cell->getPort("\\DATA");
86  if (!find_sig_before_dff(module, dff_cells, sig_data, clk, clk_polarity)) {
87  log("no (compatible) $dff for data input found.\n");
88  return;
89  }
90 
91  RTLIL::SigSpec sig_en = cell->getPort("\\EN");
92  if (!find_sig_before_dff(module, dff_cells, sig_en, clk, clk_polarity)) {
93  log("no (compatible) $dff for enable input found.\n");
94  return;
95  }
96 
97  if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) {
98  cell->setPort("\\CLK", clk);
99  cell->setPort("\\ADDR", sig_addr);
100  cell->setPort("\\DATA", sig_data);
101  cell->setPort("\\EN", sig_en);
102  cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
103  cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
104  log("merged $dff to cell.\n");
105  return;
106  }
107 
108  log("no (compatible) $dff found.\n");
109 }
const char * c_str() const
Definition: rtlil.h:178
bool clk_polarity
Definition: abc.cc:98
RTLIL::IdString name
Definition: rtlil.h:853
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
Definition: rtlil.cc:1789
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
Definition: rtlil.cc:1809
RTLIL::IdString name
Definition: rtlil.h:599
void log(const char *format,...)
Definition: log.cc:180
bool find_sig_before_dff(RTLIL::Module *module, std::vector< RTLIL::Cell * > &dff_cells, RTLIL::SigSpec &sig, RTLIL::SigSpec &clk, bool &clk_polarity, bool after=false)
Definition: memory_dff.cc:34

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN void normalize_sig ( RTLIL::Module module,
RTLIL::SigSpec sig 
)

Definition at line 28 of file memory_dff.cc.

29 {
30  for (auto &conn : module->connections())
31  sig.replace(conn.first, conn.second);
32 }
const std::vector< RTLIL::SigSig > & connections() const
Definition: rtlil.cc:1307
void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
Definition: rtlil.cc:2297

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation