yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
celltypes.h
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 #ifndef CELLTYPES_H
21 #define CELLTYPES_H
22 
23 #include <kernel/yosys.h>
24 
26 
27 struct CellType
28 {
30  std::set<RTLIL::IdString> inputs, outputs;
32 };
33 
34 struct CellTypes
35 {
36  std::map<RTLIL::IdString, CellType> cell_types;
37 
39  {
40  }
41 
43  {
44  setup(design);
45  }
46 
47  void setup(RTLIL::Design *design = NULL)
48  {
49  if (design)
50  setup_design(design);
51 
56  }
57 
58  void setup_type(RTLIL::IdString type, const std::set<RTLIL::IdString> &inputs, const std::set<RTLIL::IdString> &outputs, bool is_evaluable = false)
59  {
60  CellType ct = {type, inputs, outputs, is_evaluable};
61  cell_types[ct.type] = ct;
62  }
63 
65  {
66  std::set<RTLIL::IdString> inputs, outputs;
67  for (RTLIL::IdString wire_name : module->ports) {
68  RTLIL::Wire *wire = module->wire(wire_name);
69  if (wire->port_input)
70  inputs.insert(wire->name);
71  if (wire->port_output)
72  outputs.insert(wire->name);
73  }
74  setup_type(module->name, inputs, outputs);
75  }
76 
78  {
79  for (auto module : design->modules())
81  }
82 
84  {
85  std::vector<RTLIL::IdString> unary_ops = {
86  "$not", "$pos", "$neg",
87  "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool",
88  "$logic_not", "$slice", "$lut"
89  };
90 
91  std::vector<RTLIL::IdString> binary_ops = {
92  "$and", "$or", "$xor", "$xnor",
93  "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
94  "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
95  "$add", "$sub", "$mul", "$div", "$mod", "$pow",
96  "$logic_and", "$logic_or", "$concat", "$macc"
97  };
98 
99  for (auto type : unary_ops)
100  setup_type(type, {"\\A"}, {"\\Y"}, true);
101 
102  for (auto type : binary_ops)
103  setup_type(type, {"\\A", "\\B"}, {"\\Y"}, true);
104 
105  for (auto type : std::vector<RTLIL::IdString>({"$mux", "$pmux"}))
106  setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, true);
107 
108  setup_type("$lcu", {"\\P", "\\G", "\\CI"}, {"\\CO"}, true);
109  setup_type("$alu", {"\\A", "\\B", "\\CI", "\\BI"}, {"\\X", "\\Y", "\\CO"}, true);
110  setup_type("$fa", {"\\A", "\\B", "\\C"}, {"\\X", "\\Y"}, true);
111 
112  setup_type("$assert", {"\\A", "\\EN"}, std::set<RTLIL::IdString>(), true);
113  }
114 
116  {
117  setup_type("$sr", {"\\SET", "\\CLR"}, {"\\Q"});
118  setup_type("$dff", {"\\CLK", "\\D"}, {"\\Q"});
119  setup_type("$dffe", {"\\CLK", "\\EN", "\\D"}, {"\\Q"});
120  setup_type("$dffsr", {"\\CLK", "\\SET", "\\CLR", "\\D"}, {"\\Q"});
121  setup_type("$adff", {"\\CLK", "\\ARST", "\\D"}, {"\\Q"});
122  setup_type("$dlatch", {"\\EN", "\\D"}, {"\\Q"});
123  setup_type("$dlatchsr", {"\\EN", "\\SET", "\\CLR", "\\D"}, {"\\Q"});
124 
125  setup_type("$memrd", {"\\CLK", "\\ADDR"}, {"\\DATA"});
126  setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, std::set<RTLIL::IdString>());
127  setup_type("$mem", {"\\RD_CLK", "\\RD_ADDR", "\\WR_CLK", "\\WR_EN", "\\WR_ADDR", "\\WR_DATA"}, {"\\RD_DATA"});
128 
129  setup_type("$fsm", {"\\CLK", "\\ARST", "\\CTRL_IN"}, {"\\CTRL_OUT"});
130  }
131 
133  {
134  setup_type("$_BUF_", {"\\A"}, {"\\Y"}, true);
135  setup_type("$_NOT_", {"\\A"}, {"\\Y"}, true);
136  setup_type("$_AND_", {"\\A", "\\B"}, {"\\Y"}, true);
137  setup_type("$_NAND_", {"\\A", "\\B"}, {"\\Y"}, true);
138  setup_type("$_OR_", {"\\A", "\\B"}, {"\\Y"}, true);
139  setup_type("$_NOR_", {"\\A", "\\B"}, {"\\Y"}, true);
140  setup_type("$_XOR_", {"\\A", "\\B"}, {"\\Y"}, true);
141  setup_type("$_XNOR_", {"\\A", "\\B"}, {"\\Y"}, true);
142  setup_type("$_MUX_", {"\\A", "\\B", "\\S"}, {"\\Y"}, true);
143  setup_type("$_AOI3_", {"\\A", "\\B", "\\C"}, {"\\Y"}, true);
144  setup_type("$_OAI3_", {"\\A", "\\B", "\\C"}, {"\\Y"}, true);
145  setup_type("$_AOI4_", {"\\A", "\\B", "\\C", "\\D"}, {"\\Y"}, true);
146  setup_type("$_OAI4_", {"\\A", "\\B", "\\C", "\\D"}, {"\\Y"}, true);
147  }
148 
150  {
151  std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'};
152 
153  for (auto c1 : list_np)
154  for (auto c2 : list_np)
155  setup_type(stringf("$_SR_%c%c_", c1, c2), {"\\S", "\\R"}, {"\\Q"});
156 
157  for (auto c1 : list_np)
158  setup_type(stringf("$_DFF_%c_", c1), {"\\C", "\\D"}, {"\\Q"});
159 
160  for (auto c1 : list_np)
161  for (auto c2 : list_np)
162  setup_type(stringf("$_DFFE_%c%c_", c1, c2), {"\\C", "\\D", "\\E"}, {"\\Q"});
163 
164  for (auto c1 : list_np)
165  for (auto c2 : list_np)
166  for (auto c3 : list_01)
167  setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {"\\C", "\\R", "\\D"}, {"\\Q"});
168 
169  for (auto c1 : list_np)
170  for (auto c2 : list_np)
171  for (auto c3 : list_np)
172  setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {"\\C", "\\S", "\\R", "\\D"}, {"\\Q"});
173 
174  for (auto c1 : list_np)
175  setup_type(stringf("$_DLATCH_%c_", c1), {"\\E", "\\D"}, {"\\Q"});
176 
177  for (auto c1 : list_np)
178  for (auto c2 : list_np)
179  for (auto c3 : list_np)
180  setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {"\\E", "\\S", "\\R", "\\D"}, {"\\Q"});
181  }
182 
183  void clear()
184  {
185  cell_types.clear();
186  }
187 
189  {
190  return cell_types.count(type) != 0;
191  }
192 
194  {
195  auto it = cell_types.find(type);
196  return it != cell_types.end() && it->second.outputs.count(port) != 0;
197  }
198 
200  {
201  auto it = cell_types.find(type);
202  return it != cell_types.end() && it->second.inputs.count(port) != 0;
203  }
204 
206  {
207  auto it = cell_types.find(type);
208  return it != cell_types.end() && it->second.is_evaluable;
209  }
210 
212  {
213  for (auto &bit : v.bits)
214  if (bit == RTLIL::S0) bit = RTLIL::S1;
215  else if (bit == RTLIL::S1) bit = RTLIL::S0;
216  return v;
217  }
218 
219  static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
220  {
221  if (type == "$sshr" && !signed1)
222  type = "$shr";
223  if (type == "$sshl" && !signed1)
224  type = "$shl";
225 
226  if (type != "$sshr" && type != "$sshl" && type != "$shr" && type != "$shl" && type != "$shift" && type != "$shiftx" &&
227  type != "$pos" && type != "$neg" && type != "$not") {
228  if (!signed1 || !signed2)
229  signed1 = false, signed2 = false;
230  }
231 
232 #define HANDLE_CELL_TYPE(_t) if (type == "$" #_t) return const_ ## _t(arg1, arg2, signed1, signed2, result_len);
233  HANDLE_CELL_TYPE(not)
234  HANDLE_CELL_TYPE(and)
235  HANDLE_CELL_TYPE(or)
236  HANDLE_CELL_TYPE(xor)
237  HANDLE_CELL_TYPE(xnor)
238  HANDLE_CELL_TYPE(reduce_and)
239  HANDLE_CELL_TYPE(reduce_or)
240  HANDLE_CELL_TYPE(reduce_xor)
241  HANDLE_CELL_TYPE(reduce_xnor)
242  HANDLE_CELL_TYPE(reduce_bool)
243  HANDLE_CELL_TYPE(logic_not)
246  HANDLE_CELL_TYPE(shl)
247  HANDLE_CELL_TYPE(shr)
248  HANDLE_CELL_TYPE(sshl)
249  HANDLE_CELL_TYPE(sshr)
250  HANDLE_CELL_TYPE(shift)
251  HANDLE_CELL_TYPE(shiftx)
252  HANDLE_CELL_TYPE(lt)
253  HANDLE_CELL_TYPE(le)
254  HANDLE_CELL_TYPE(eq)
255  HANDLE_CELL_TYPE(ne)
256  HANDLE_CELL_TYPE(eqx)
257  HANDLE_CELL_TYPE(nex)
258  HANDLE_CELL_TYPE(ge)
259  HANDLE_CELL_TYPE(gt)
260  HANDLE_CELL_TYPE(add)
261  HANDLE_CELL_TYPE(sub)
262  HANDLE_CELL_TYPE(mul)
263  HANDLE_CELL_TYPE(div)
264  HANDLE_CELL_TYPE(mod)
265  HANDLE_CELL_TYPE(pow)
266  HANDLE_CELL_TYPE(pos)
267  HANDLE_CELL_TYPE(neg)
268 #undef HANDLE_CELL_TYPE
269 
270  if (type == "$_BUF_")
271  return arg1;
272  if (type == "$_NOT_")
273  return eval_not(arg1);
274  if (type == "$_AND_")
275  return const_and(arg1, arg2, false, false, 1);
276  if (type == "$_NAND_")
277  return eval_not(const_and(arg1, arg2, false, false, 1));
278  if (type == "$_OR_")
279  return const_or(arg1, arg2, false, false, 1);
280  if (type == "$_NOR_")
281  return eval_not(const_and(arg1, arg2, false, false, 1));
282  if (type == "$_XOR_")
283  return const_xor(arg1, arg2, false, false, 1);
284  if (type == "$_XNOR_")
285  return const_xnor(arg1, arg2, false, false, 1);
286 
287  log_abort();
288  }
289 
290  static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2)
291  {
292  if (cell->type == "$slice") {
293  RTLIL::Const ret;
294  int width = cell->parameters.at("\\Y_WIDTH").as_int();
295  int offset = cell->parameters.at("\\OFFSET").as_int();
296  ret.bits.insert(ret.bits.end(), arg1.bits.begin()+offset, arg1.bits.begin()+offset+width);
297  return ret;
298  }
299 
300  if (cell->type == "$concat") {
301  RTLIL::Const ret = arg1;
302  ret.bits.insert(ret.bits.end(), arg2.bits.begin(), arg2.bits.end());
303  return ret;
304  }
305 
306  if (cell->type == "$lut")
307  {
308  int width = cell->parameters.at("\\WIDTH").as_int();
309 
310  std::vector<RTLIL::State> t = cell->parameters.at("\\LUT").bits;
311  while (GetSize(t) < (1 << width))
312  t.push_back(RTLIL::S0);
313  t.resize(1 << width);
314 
315  for (int i = width-1; i >= 0; i--) {
316  RTLIL::State sel = arg1.bits.at(i);
317  std::vector<RTLIL::State> new_t;
318  if (sel == RTLIL::S0)
319  new_t = std::vector<RTLIL::State>(t.begin(), t.begin() + GetSize(t)/2);
320  else if (sel == RTLIL::S1)
321  new_t = std::vector<RTLIL::State>(t.begin() + GetSize(t)/2, t.end());
322  else
323  for (int j = 0; j < GetSize(t)/2; j++)
324  new_t.push_back(t[j] == t[j + GetSize(t)/2] ? t[j] : RTLIL::Sx);
325  t.swap(new_t);
326  }
327 
328  log_assert(GetSize(t) == 1);
329  return t;
330  }
331 
332  bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool();
333  bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool();
334  int result_len = cell->parameters.count("\\Y_WIDTH") > 0 ? cell->parameters["\\Y_WIDTH"].as_int() : -1;
335  return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len);
336  }
337 
338  static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3)
339  {
340  if (cell->type.in("$mux", "$pmux", "$_MUX_")) {
341  RTLIL::Const ret = arg1;
342  for (size_t i = 0; i < arg3.bits.size(); i++)
343  if (arg3.bits[i] == RTLIL::State::S1) {
344  std::vector<RTLIL::State> bits(arg2.bits.begin() + i*arg1.bits.size(), arg2.bits.begin() + (i+1)*arg1.bits.size());
345  ret = RTLIL::Const(bits);
346  }
347  return ret;
348  }
349 
350  if (cell->type == "$_AOI3_")
351  return eval_not(const_or(const_and(arg1, arg2, false, false, 1), arg3, false, false, 1));
352  if (cell->type == "$_OAI3_")
353  return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1));
354 
355  log_assert(arg3.bits.size() == 0);
356  return eval(cell, arg1, arg2);
357  }
358 
359  static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4)
360  {
361  if (cell->type == "$_AOI4_")
362  return eval_not(const_or(const_and(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1));
363  if (cell->type == "$_OAI4_")
364  return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1));
365 
366  log_assert(arg4.bits.size() == 0);
367  return eval(cell, arg1, arg2, arg3);
368  }
369 };
370 
372 
373 #endif
374 
bool is_evaluable
Definition: celltypes.h:31
void clear()
Definition: celltypes.h:183
#define HANDLE_CELL_TYPE(_t)
RTLIL::Wire * wire(RTLIL::IdString id)
Definition: rtlil.h:637
RTLIL::Const const_xor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:175
std::string stringf(const char *fmt,...)
Definition: yosys.cc:58
void setup_stdcells()
Definition: celltypes.h:132
CellTypes(RTLIL::Design *design)
Definition: celltypes.h:42
void setup_internals_mem()
Definition: celltypes.h:115
void setup(RTLIL::Design *design=NULL)
Definition: celltypes.h:47
CellTypes ct
Definition: opt_clean.cc:33
#define YOSYS_NAMESPACE_END
Definition: yosys.h:100
bool port_input
Definition: rtlil.h:827
RTLIL::Module * module
Definition: abc.cc:94
RTLIL::IdString type
Definition: rtlil.h:854
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856
#define log_abort()
Definition: log.h:84
RTLIL::Const const_or(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:170
bool in(T first, Args...rest)
Definition: rtlil.h:241
RTLIL::Const const_and(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:165
static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2)
Definition: celltypes.h:290
bool port_output
Definition: rtlil.h:827
static RTLIL::Const eval_not(RTLIL::Const v)
Definition: celltypes.h:211
std::map< RTLIL::IdString, CellType > cell_types
Definition: celltypes.h:36
bool cell_known(RTLIL::IdString type)
Definition: celltypes.h:188
std::vector< RTLIL::IdString > ports
Definition: rtlil.h:617
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
Definition: celltypes.h:193
RTLIL::Const const_xnor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: calc.cc:180
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
Definition: celltypes.h:219
#define log_assert(_assert_expr_)
Definition: log.h:85
void setup_module(RTLIL::Module *module)
Definition: celltypes.h:64
RTLIL::IdString name
Definition: rtlil.h:599
RTLIL::IdString type
Definition: celltypes.h:29
RTLIL::IdString name
Definition: rtlil.h:825
static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4)
Definition: celltypes.h:359
RTLIL::ObjRange< RTLIL::Module * > modules()
Definition: rtlil.cc:249
#define NULL
#define YOSYS_NAMESPACE_BEGIN
Definition: yosys.h:99
void setup_type(RTLIL::IdString type, const std::set< RTLIL::IdString > &inputs, const std::set< RTLIL::IdString > &outputs, bool is_evaluable=false)
Definition: celltypes.h:58
void setup_internals()
Definition: celltypes.h:83
std::vector< RTLIL::State > bits
Definition: rtlil.h:438
static RTLIL::State logic_or(RTLIL::State a, RTLIL::State b)
Definition: calc.cc:102
void setup_design(RTLIL::Design *design)
Definition: celltypes.h:77
void setup_stdcells_mem()
Definition: celltypes.h:149
static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3)
Definition: celltypes.h:338
CellTypes()
Definition: celltypes.h:38
State
Definition: rtlil.h:29
bool cell_evaluable(RTLIL::IdString type)
Definition: celltypes.h:205
bool cell_input(RTLIL::IdString type, RTLIL::IdString port)
Definition: celltypes.h:199
static RTLIL::State logic_and(RTLIL::State a, RTLIL::State b)
Definition: calc.cc:93
std::set< RTLIL::IdString > outputs
Definition: celltypes.h:30
std::set< RTLIL::IdString > inputs
Definition: celltypes.h:30