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

Go to the source code of this file.

Data Structures

struct  cell_mapping
 
struct  DfflibmapPass
 

Functions

static void logmap (std::string dff)
 
static void logmap_all ()
 
static bool parse_pin (LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol)
 
static void find_cell (LibertyAst *ast, std::string cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval)
 
static void find_cell_sr (LibertyAst *ast, std::string cell_type, bool clkpol, bool setpol, bool clrpol)
 
static bool expand_cellmap_worker (std::string from, std::string to, std::string inv)
 
static bool expand_cellmap (std::string pattern, std::string inv)
 
static void map_sr_to_arst (const char *from, const char *to)
 
static void dfflibmap (RTLIL::Design *design, RTLIL::Module *module)
 

Variables

static std::map
< RTLIL::IdString,
cell_mapping
cell_mappings
 
DfflibmapPass DfflibmapPass
 

Function Documentation

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

Definition at line 387 of file dfflibmap.cc.

388 {
389  log("Mapping DFF cells in module `%s':\n", module->name.c_str());
390 
391  std::vector<RTLIL::Cell*> cell_list;
392  for (auto &it : module->cells_) {
393  if (design->selected(module, it.second) && cell_mappings.count(it.second->type) > 0)
394  cell_list.push_back(it.second);
395  }
396 
397  std::map<std::string, int> stats;
398  for (auto cell : cell_list)
399  {
400  auto cell_type = cell->type;
401  auto cell_name = cell->name;
402  auto cell_connections = cell->connections();
403  module->remove(cell);
404 
405  cell_mapping &cm = cell_mappings[cell_type];
406  RTLIL::Cell *new_cell = module->addCell(cell_name, "\\" + cm.cell_name);
407 
408  for (auto &port : cm.ports) {
409  RTLIL::SigSpec sig;
410  if ('A' <= port.second && port.second <= 'Z') {
411  sig = cell_connections[std::string("\\") + port.second];
412  } else
413  if (port.second == 'q') {
414  RTLIL::SigSpec old_sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))];
415  sig = module->addWire(NEW_ID, GetSize(old_sig));
416  module->addNotGate(NEW_ID, sig, old_sig);
417  } else
418  if ('a' <= port.second && port.second <= 'z') {
419  sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))];
420  sig = module->NotGate(NEW_ID, sig);
421  } else
422  if (port.second == '0' || port.second == '1') {
423  sig = RTLIL::SigSpec(port.second == '0' ? 0 : 1, 1);
424  } else
425  if (port.second != 0)
426  log_abort();
427  new_cell->setPort("\\" + port.first, sig);
428  }
429 
430  stats[stringf(" mapped %%d %s cells to %s cells.\n", cell_type.c_str(), new_cell->type.c_str())]++;
431  }
432 
433  for (auto &stat: stats)
434  log(stat.first.c_str(), stat.second);
435 }
const char * c_str() const
Definition: rtlil.h:178
bool selected(T1 *module) const
Definition: rtlil.h:551
static std::map< RTLIL::IdString, cell_mapping > cell_mappings
Definition: dfflibmap.cc:33
std::map< std::string, char > ports
Definition: dfflibmap.cc:31
std::string stringf(const char *fmt,...)
Definition: yosys.cc:58
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
Definition: rtlil.cc:1353
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
Definition: rtlil.cc:1789
RTLIL::IdString type
Definition: rtlil.h:854
#define log_abort()
Definition: log.h:84
RTLIL::Cell * addNotGate(RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y)
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
std::string cell_name
Definition: dfflibmap.cc:30
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
Definition: rtlil.cc:1331
RTLIL::IdString name
Definition: rtlil.h:599
#define NEW_ID
Definition: yosys.h:166
RTLIL::SigBit NotGate(RTLIL::IdString name, RTLIL::SigBit sig_a)
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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static bool expand_cellmap ( std::string  pattern,
std::string  inv 
)
static

Definition at line 317 of file dfflibmap.cc.

318 {
319  std::vector<std::pair<std::string, std::string>> from_to_list;
320  bool return_status = false;
321 
322  for (auto &it : cell_mappings) {
323  std::string from = it.first.str(), to = it.first.str();
324  if (from.size() != pattern.size())
325  continue;
326  for (size_t i = 0; i < from.size(); i++) {
327  if (pattern[i] == '*') {
328  to[i] = from[i] == 'P' ? 'N' :
329  from[i] == 'N' ? 'P' :
330  from[i] == '1' ? '0' :
331  from[i] == '0' ? '1' : '*';
332  } else
333  if (pattern[i] != '?' && pattern[i] != from[i])
334  goto pattern_failed;
335  }
336  from_to_list.push_back(std::pair<std::string, std::string>(from, to));
337  pattern_failed:;
338  }
339 
340  for (auto &it : from_to_list)
341  return_status = return_status || expand_cellmap_worker(it.first, it.second, inv);
342  return return_status;
343 }
static std::map< RTLIL::IdString, cell_mapping > cell_mappings
Definition: dfflibmap.cc:33
static bool expand_cellmap_worker(std::string from, std::string to, std::string inv)
Definition: dfflibmap.cc:294

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static bool expand_cellmap_worker ( std::string  from,
std::string  to,
std::string  inv 
)
static

Definition at line 294 of file dfflibmap.cc.

295 {
296  if (cell_mappings.count(to) > 0)
297  return false;
298 
299  log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str());
300  cell_mappings[to].cell_name = cell_mappings[from].cell_name;
301  cell_mappings[to].ports = cell_mappings[from].ports;
302 
303  for (auto &it : cell_mappings[to].ports) {
304  char cmp_ch = it.second;
305  if ('a' <= cmp_ch && cmp_ch <= 'z')
306  cmp_ch -= 'a' - 'A';
307  if (inv.find(cmp_ch) == std::string::npos)
308  continue;
309  if ('a' <= it.second && it.second <= 'z')
310  it.second -= 'a' - 'A';
311  else if ('A' <= it.second && it.second <= 'Z')
312  it.second += 'a' - 'A';
313  }
314  return true;
315 }
static std::map< RTLIL::IdString, cell_mapping > cell_mappings
Definition: dfflibmap.cc:33
void log(const char *format,...)
Definition: log.cc:180

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void find_cell ( LibertyAst *  ast,
std::string  cell_type,
bool  clkpol,
bool  has_reset,
bool  rstpol,
bool  rstval 
)
static

Definition at line 106 of file dfflibmap.cc.

107 {
108  LibertyAst *best_cell = NULL;
109  std::map<std::string, char> best_cell_ports;
110  int best_cell_pins = 0;
111  double best_cell_area = 0;
112 
113  if (ast->id != "library")
114  log_error("Format error in liberty file.\n");
115 
116  for (auto cell : ast->children)
117  {
118  if (cell->id != "cell" || cell->args.size() != 1)
119  continue;
120 
121  LibertyAst *ff = cell->find("ff");
122  if (ff == NULL)
123  continue;
124 
125  std::string cell_clk_pin, cell_rst_pin, cell_next_pin;
126  bool cell_clk_pol, cell_rst_pol, cell_next_pol;
127 
128  if (!parse_pin(cell, ff->find("clocked_on"), cell_clk_pin, cell_clk_pol) || cell_clk_pol != clkpol)
129  continue;
130  if (!parse_pin(cell, ff->find("next_state"), cell_next_pin, cell_next_pol))
131  continue;
132  if (has_reset && rstval == false) {
133  if (!parse_pin(cell, ff->find("clear"), cell_rst_pin, cell_rst_pol) || cell_rst_pol != rstpol)
134  continue;
135  }
136  if (has_reset && rstval == true) {
137  if (!parse_pin(cell, ff->find("preset"), cell_rst_pin, cell_rst_pol) || cell_rst_pol != rstpol)
138  continue;
139  }
140 
141  std::map<std::string, char> this_cell_ports;
142  this_cell_ports[cell_clk_pin] = 'C';
143  if (has_reset)
144  this_cell_ports[cell_rst_pin] = 'R';
145  this_cell_ports[cell_next_pin] = 'D';
146 
147  double area = 0;
148  LibertyAst *ar = cell->find("area");
149  if (ar != NULL && !ar->value.empty())
150  area = atof(ar->value.c_str());
151 
152  int num_pins = 0;
153  bool found_output = false;
154  for (auto pin : cell->children)
155  {
156  if (pin->id != "pin" || pin->args.size() != 1)
157  continue;
158 
159  LibertyAst *dir = pin->find("direction");
160  if (dir == NULL || dir->value == "internal")
161  continue;
162  num_pins++;
163 
164  if (dir->value == "input" && this_cell_ports.count(pin->args[0]) == 0)
165  goto continue_cell_loop;
166 
167  LibertyAst *func = pin->find("function");
168  if (dir->value == "output" && func != NULL) {
169  std::string value = func->value;
170  for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t"))
171  value.erase(pos, 1);
172  if ((cell_next_pol == true && value == ff->args[0]) || (cell_next_pol == false && value == ff->args[1])) {
173  this_cell_ports[pin->args[0]] = 'Q';
174  found_output = true;
175  }
176  }
177 
178  if (this_cell_ports.count(pin->args[0]) == 0)
179  this_cell_ports[pin->args[0]] = 0;
180  }
181 
182  if (!found_output || (best_cell != NULL && num_pins > best_cell_pins))
183  continue;
184 
185  if (best_cell != NULL && num_pins == best_cell_pins && area > best_cell_area)
186  continue;
187 
188  best_cell = cell;
189  best_cell_pins = num_pins;
190  best_cell_area = area;
191  best_cell_ports.swap(this_cell_ports);
192  continue_cell_loop:;
193  }
194 
195  if (best_cell != NULL) {
196  log(" cell %s (pins=%d, area=%.2f) is a direct match for cell type %s.\n", best_cell->args[0].c_str(), best_cell_pins, best_cell_area, cell_type.substr(1).c_str());
197  cell_mappings[cell_type].cell_name = best_cell->args[0];
198  cell_mappings[cell_type].ports = best_cell_ports;
199  }
200 }
static std::map< RTLIL::IdString, cell_mapping > cell_mappings
Definition: dfflibmap.cc:33
void log_error(const char *format,...)
Definition: log.cc:204
#define NULL
void log(const char *format,...)
Definition: log.cc:180
static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol)
Definition: dfflibmap.cc:79

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void find_cell_sr ( LibertyAst *  ast,
std::string  cell_type,
bool  clkpol,
bool  setpol,
bool  clrpol 
)
static

Definition at line 202 of file dfflibmap.cc.

203 {
204  LibertyAst *best_cell = NULL;
205  std::map<std::string, char> best_cell_ports;
206  int best_cell_pins = 0;
207  double best_cell_area = 0;
208 
209  if (ast->id != "library")
210  log_error("Format error in liberty file.\n");
211 
212  for (auto cell : ast->children)
213  {
214  if (cell->id != "cell" || cell->args.size() != 1)
215  continue;
216 
217  LibertyAst *ff = cell->find("ff");
218  if (ff == NULL)
219  continue;
220 
221  std::string cell_clk_pin, cell_set_pin, cell_clr_pin, cell_next_pin;
222  bool cell_clk_pol, cell_set_pol, cell_clr_pol, cell_next_pol;
223 
224  if (!parse_pin(cell, ff->find("clocked_on"), cell_clk_pin, cell_clk_pol) || cell_clk_pol != clkpol)
225  continue;
226  if (!parse_pin(cell, ff->find("next_state"), cell_next_pin, cell_next_pol))
227  continue;
228  if (!parse_pin(cell, ff->find("preset"), cell_set_pin, cell_set_pol) || cell_set_pol != setpol)
229  continue;
230  if (!parse_pin(cell, ff->find("clear"), cell_clr_pin, cell_clr_pol) || cell_clr_pol != clrpol)
231  continue;
232 
233  std::map<std::string, char> this_cell_ports;
234  this_cell_ports[cell_clk_pin] = 'C';
235  this_cell_ports[cell_set_pin] = 'S';
236  this_cell_ports[cell_clr_pin] = 'R';
237  this_cell_ports[cell_next_pin] = 'D';
238 
239  double area = 0;
240  LibertyAst *ar = cell->find("area");
241  if (ar != NULL && !ar->value.empty())
242  area = atof(ar->value.c_str());
243 
244  int num_pins = 0;
245  bool found_output = false;
246  for (auto pin : cell->children)
247  {
248  if (pin->id != "pin" || pin->args.size() != 1)
249  continue;
250 
251  LibertyAst *dir = pin->find("direction");
252  if (dir == NULL || dir->value == "internal")
253  continue;
254  num_pins++;
255 
256  if (dir->value == "input" && this_cell_ports.count(pin->args[0]) == 0)
257  goto continue_cell_loop;
258 
259  LibertyAst *func = pin->find("function");
260  if (dir->value == "output" && func != NULL) {
261  std::string value = func->value;
262  for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t"))
263  value.erase(pos, 1);
264  if ((cell_next_pol == true && value == ff->args[0]) || (cell_next_pol == false && value == ff->args[1])) {
265  this_cell_ports[pin->args[0]] = 'Q';
266  found_output = true;
267  }
268  }
269 
270  if (this_cell_ports.count(pin->args[0]) == 0)
271  this_cell_ports[pin->args[0]] = 0;
272  }
273 
274  if (!found_output || (best_cell != NULL && num_pins > best_cell_pins))
275  continue;
276 
277  if (best_cell != NULL && num_pins == best_cell_pins && area > best_cell_area)
278  continue;
279 
280  best_cell = cell;
281  best_cell_pins = num_pins;
282  best_cell_area = area;
283  best_cell_ports.swap(this_cell_ports);
284  continue_cell_loop:;
285  }
286 
287  if (best_cell != NULL) {
288  log(" cell %s (pins=%d, area=%.2f) is a direct match for cell type %s.\n", best_cell->args[0].c_str(), best_cell_pins, best_cell_area, cell_type.substr(1).c_str());
289  cell_mappings[cell_type].cell_name = best_cell->args[0];
290  cell_mappings[cell_type].ports = best_cell_ports;
291  }
292 }
static std::map< RTLIL::IdString, cell_mapping > cell_mappings
Definition: dfflibmap.cc:33
void log_error(const char *format,...)
Definition: log.cc:204
#define NULL
void log(const char *format,...)
Definition: log.cc:180
static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol)
Definition: dfflibmap.cc:79

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void logmap ( std::string  dff)
static

Definition at line 35 of file dfflibmap.cc.

36 {
37  if (cell_mappings.count(dff) == 0) {
38  log(" unmapped dff cell: %s\n", dff.c_str());
39  } else {
40  log(" %s %s (", cell_mappings[dff].cell_name.c_str(), dff.substr(1).c_str());
41  bool first = true;
42  for (auto &port : cell_mappings[dff].ports) {
43  char arg[3] = { port.second, 0, 0 };
44  if ('a' <= arg[0] && arg[0] <= 'z')
45  arg[1] = arg[0] - ('a' - 'A'), arg[0] = '~';
46  else
47  arg[1] = arg[0], arg[0] = ' ';
48  log("%s.%s(%s)", first ? "" : ", ", port.first.c_str(), arg);
49  first = false;
50  }
51  log(");\n");
52  }
53 }
static std::map< RTLIL::IdString, cell_mapping > cell_mappings
Definition: dfflibmap.cc:33
void log(const char *format,...)
Definition: log.cc:180

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void logmap_all ( )
static

Definition at line 55 of file dfflibmap.cc.

56 {
57  logmap("$_DFF_N_");
58  logmap("$_DFF_P_");
59 
60  logmap("$_DFF_NN0_");
61  logmap("$_DFF_NN1_");
62  logmap("$_DFF_NP0_");
63  logmap("$_DFF_NP1_");
64  logmap("$_DFF_PN0_");
65  logmap("$_DFF_PN1_");
66  logmap("$_DFF_PP0_");
67  logmap("$_DFF_PP1_");
68 
69  logmap("$_DFFSR_NNN_");
70  logmap("$_DFFSR_NNP_");
71  logmap("$_DFFSR_NPN_");
72  logmap("$_DFFSR_NPP_");
73  logmap("$_DFFSR_PNN_");
74  logmap("$_DFFSR_PNP_");
75  logmap("$_DFFSR_PPN_");
76  logmap("$_DFFSR_PPP_");
77 }
static void logmap(std::string dff)
Definition: dfflibmap.cc:35

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void map_sr_to_arst ( const char *  from,
const char *  to 
)
static

Definition at line 345 of file dfflibmap.cc.

346 {
347  if (!cell_mappings.count(from) || cell_mappings.count(to) > 0)
348  return;
349 
350  char from_clk_pol = from[8], from_set_pol = from[9], from_clr_pol = from[10];
351  char to_clk_pol = to[6], to_rst_pol = to[7], to_rst_val = to[8];
352 
353  log_assert(from_clk_pol == to_clk_pol);
354  log_assert(to_rst_pol == from_set_pol && to_rst_pol == from_clr_pol);
355 
356  log(" create mapping for %s from mapping for %s.\n", to, from);
357  cell_mappings[to].cell_name = cell_mappings[from].cell_name;
358  cell_mappings[to].ports = cell_mappings[from].ports;
359 
360  for (auto &it : cell_mappings[to].ports)
361  {
362  bool is_set_pin = it.second == 'S' || it.second == 's';
363  bool is_clr_pin = it.second == 'R' || it.second == 'r';
364 
365  if (!is_set_pin && !is_clr_pin)
366  continue;
367 
368  if ((to_rst_val == '0' && is_set_pin) || (to_rst_val == '1' && is_clr_pin))
369  {
370  // this is the unused set/clr pin -- deactivate it
371  if (is_set_pin)
372  it.second = (from_set_pol == 'P') == (it.second == 'S') ? '0' : '1';
373  else
374  it.second = (from_clr_pol == 'P') == (it.second == 'R') ? '0' : '1';
375  }
376  else
377  {
378  // this is the used set/clr pin -- rename it to 'reset'
379  if (it.second == 'S')
380  it.second = 'R';
381  if (it.second == 's')
382  it.second = 'r';
383  }
384  }
385 }
static std::map< RTLIL::IdString, cell_mapping > cell_mappings
Definition: dfflibmap.cc:33
#define log_assert(_assert_expr_)
Definition: log.h:85
void log(const char *format,...)
Definition: log.cc:180

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static bool parse_pin ( LibertyAst *  cell,
LibertyAst *  attr,
std::string &  pin_name,
bool &  pin_pol 
)
static

Definition at line 79 of file dfflibmap.cc.

80 {
81  if (cell == NULL || attr == NULL || attr->value.empty())
82  return false;
83 
84  std::string value = attr->value;
85 
86  for (size_t pos = value.find_first_of("\" \t()"); pos != std::string::npos; pos = value.find_first_of("\" \t()"))
87  value.erase(pos, 1);
88 
89  if (value[value.size()-1] == '\'') {
90  pin_name = value.substr(0, value.size()-1);
91  pin_pol = false;
92  } else if (value[0] == '!') {
93  pin_name = value.substr(1, value.size()-1);
94  pin_pol = false;
95  } else {
96  pin_name = value;
97  pin_pol = true;
98  }
99 
100  for (auto child : cell->children)
101  if (child->id == "pin" && child->args.size() == 1 && child->args[0] == pin_name)
102  return true;
103  return false;
104 }
#define NULL

+ Here is the caller graph for this function:

Variable Documentation

std::map<RTLIL::IdString, cell_mapping> cell_mappings
static

Definition at line 33 of file dfflibmap.cc.