2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
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.
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.
23 #include "kernel/yosys.h"
30 pool
<RTLIL::IdString
> inputs
, outputs
;
36 dict
<RTLIL::IdString
, CellType
> cell_types
;
42 CellTypes(RTLIL::Design
*design
)
47 void setup(RTLIL::Design
*design
= NULL
)
53 setup_internals_mem();
58 void setup_type(RTLIL::IdString type
, const pool
<RTLIL::IdString
> &inputs
, const pool
<RTLIL::IdString
> &outputs
, bool is_evaluable
= false)
60 CellType ct
= {type
, inputs
, outputs
, is_evaluable
};
61 cell_types
[ct
.type
] = ct
;
64 void setup_module(RTLIL::Module
*module
)
66 pool
<RTLIL::IdString
> inputs
, outputs
;
67 for (RTLIL::IdString wire_name
: module
->ports
) {
68 RTLIL::Wire
*wire
= module
->wire(wire_name
);
70 inputs
.insert(wire
->name
);
71 if (wire
->port_output
)
72 outputs
.insert(wire
->name
);
74 setup_type(module
->name
, inputs
, outputs
);
77 void setup_design(RTLIL::Design
*design
)
79 for (auto module
: design
->modules())
83 void setup_internals()
85 setup_internals_eval();
87 setup_type(ID($tribuf
), {ID::A
, ID::EN
}, {ID::Y
}, true);
89 setup_type(ID($
assert), {ID::A
, ID::EN
}, pool
<RTLIL::IdString
>(), true);
90 setup_type(ID($assume
), {ID::A
, ID::EN
}, pool
<RTLIL::IdString
>(), true);
91 setup_type(ID($live
), {ID::A
, ID::EN
}, pool
<RTLIL::IdString
>(), true);
92 setup_type(ID($fair
), {ID::A
, ID::EN
}, pool
<RTLIL::IdString
>(), true);
93 setup_type(ID($cover
), {ID::A
, ID::EN
}, pool
<RTLIL::IdString
>(), true);
94 setup_type(ID($initstate
), pool
<RTLIL::IdString
>(), {ID::Y
}, true);
95 setup_type(ID($anyconst
), pool
<RTLIL::IdString
>(), {ID::Y
}, true);
96 setup_type(ID($anyseq
), pool
<RTLIL::IdString
>(), {ID::Y
}, true);
97 setup_type(ID($allconst
), pool
<RTLIL::IdString
>(), {ID::Y
}, true);
98 setup_type(ID($allseq
), pool
<RTLIL::IdString
>(), {ID::Y
}, true);
99 setup_type(ID($equiv
), {ID::A
, ID::B
}, {ID::Y
}, true);
100 setup_type(ID($specify2
), {ID::EN
, ID::SRC
, ID::DST
}, pool
<RTLIL::IdString
>(), true);
101 setup_type(ID($specify3
), {ID::EN
, ID::SRC
, ID::DST
, ID::DAT
}, pool
<RTLIL::IdString
>(), true);
102 setup_type(ID($specrule
), {ID::EN_SRC
, ID::EN_DST
, ID::SRC
, ID::DST
}, pool
<RTLIL::IdString
>(), true);
105 void setup_internals_eval()
107 std::vector
<RTLIL::IdString
> unary_ops
= {
108 ID($
not), ID($pos
), ID($neg
),
109 ID($reduce_and
), ID($reduce_or
), ID($reduce_xor
), ID($reduce_xnor
), ID($reduce_bool
),
110 ID($logic_not
), ID($slice
), ID($lut
), ID($sop
)
113 std::vector
<RTLIL::IdString
> binary_ops
= {
114 ID($
and), ID($
or), ID($
xor), ID($xnor
),
115 ID($shl
), ID($shr
), ID($sshl
), ID($sshr
), ID($shift
), ID($shiftx
),
116 ID($lt
), ID($le
), ID($eq
), ID($ne
), ID($eqx
), ID($nex
), ID($ge
), ID($gt
),
117 ID($add
), ID($sub
), ID($mul
), ID($div
), ID($mod
), ID($divfloor
), ID($modfloor
), ID($pow
),
118 ID($logic_and
), ID($logic_or
), ID($concat
), ID($macc
)
121 for (auto type
: unary_ops
)
122 setup_type(type
, {ID::A
}, {ID::Y
}, true);
124 for (auto type
: binary_ops
)
125 setup_type(type
, {ID::A
, ID::B
}, {ID::Y
}, true);
127 for (auto type
: std::vector
<RTLIL::IdString
>({ID($mux
), ID($pmux
)}))
128 setup_type(type
, {ID::A
, ID::B
, ID::S
}, {ID::Y
}, true);
130 for (auto type
: std::vector
<RTLIL::IdString
>({ID($bmux
), ID($demux
)}))
131 setup_type(type
, {ID::A
, ID::S
}, {ID::Y
}, true);
133 setup_type(ID($lcu
), {ID::P
, ID::G
, ID::CI
}, {ID::CO
}, true);
134 setup_type(ID($alu
), {ID::A
, ID::B
, ID::CI
, ID::BI
}, {ID::X
, ID::Y
, ID::CO
}, true);
135 setup_type(ID($fa
), {ID::A
, ID::B
, ID::C
}, {ID::X
, ID::Y
}, true);
138 void setup_internals_ff()
140 setup_type(ID($sr
), {ID::SET
, ID::CLR
}, {ID::Q
});
141 setup_type(ID($ff
), {ID::D
}, {ID::Q
});
142 setup_type(ID($dff
), {ID::CLK
, ID::D
}, {ID::Q
});
143 setup_type(ID($dffe
), {ID::CLK
, ID::EN
, ID::D
}, {ID::Q
});
144 setup_type(ID($dffsr
), {ID::CLK
, ID::SET
, ID::CLR
, ID::D
}, {ID::Q
});
145 setup_type(ID($dffsre
), {ID::CLK
, ID::SET
, ID::CLR
, ID::D
, ID::EN
}, {ID::Q
});
146 setup_type(ID($adff
), {ID::CLK
, ID::ARST
, ID::D
}, {ID::Q
});
147 setup_type(ID($adffe
), {ID::CLK
, ID::ARST
, ID::D
, ID::EN
}, {ID::Q
});
148 setup_type(ID($aldff
), {ID::CLK
, ID::ALOAD
, ID::AD
, ID::D
}, {ID::Q
});
149 setup_type(ID($aldffe
), {ID::CLK
, ID::ALOAD
, ID::AD
, ID::D
, ID::EN
}, {ID::Q
});
150 setup_type(ID($sdff
), {ID::CLK
, ID::SRST
, ID::D
}, {ID::Q
});
151 setup_type(ID($sdffe
), {ID::CLK
, ID::SRST
, ID::D
, ID::EN
}, {ID::Q
});
152 setup_type(ID($sdffce
), {ID::CLK
, ID::SRST
, ID::D
, ID::EN
}, {ID::Q
});
153 setup_type(ID($dlatch
), {ID::EN
, ID::D
}, {ID::Q
});
154 setup_type(ID($adlatch
), {ID::EN
, ID::D
, ID::ARST
}, {ID::Q
});
155 setup_type(ID($dlatchsr
), {ID::EN
, ID::SET
, ID::CLR
, ID::D
}, {ID::Q
});
158 void setup_internals_mem()
160 setup_internals_ff();
162 setup_type(ID($memrd
), {ID::CLK
, ID::EN
, ID::ADDR
}, {ID::DATA
});
163 setup_type(ID($memrd_v2
), {ID::CLK
, ID::EN
, ID::ARST
, ID::SRST
, ID::ADDR
}, {ID::DATA
});
164 setup_type(ID($memwr
), {ID::CLK
, ID::EN
, ID::ADDR
, ID::DATA
}, pool
<RTLIL::IdString
>());
165 setup_type(ID($memwr_v2
), {ID::CLK
, ID::EN
, ID::ADDR
, ID::DATA
}, pool
<RTLIL::IdString
>());
166 setup_type(ID($meminit
), {ID::ADDR
, ID::DATA
}, pool
<RTLIL::IdString
>());
167 setup_type(ID($meminit_v2
), {ID::ADDR
, ID::DATA
, ID::EN
}, pool
<RTLIL::IdString
>());
168 setup_type(ID($mem
), {ID::RD_CLK
, ID::RD_EN
, ID::RD_ADDR
, ID::WR_CLK
, ID::WR_EN
, ID::WR_ADDR
, ID::WR_DATA
}, {ID::RD_DATA
});
169 setup_type(ID($mem_v2
), {ID::RD_CLK
, ID::RD_EN
, ID::RD_ARST
, ID::RD_SRST
, ID::RD_ADDR
, ID::WR_CLK
, ID::WR_EN
, ID::WR_ADDR
, ID::WR_DATA
}, {ID::RD_DATA
});
171 setup_type(ID($fsm
), {ID::CLK
, ID::ARST
, ID::CTRL_IN
}, {ID::CTRL_OUT
});
174 void setup_stdcells()
176 setup_stdcells_eval();
178 setup_type(ID($_TBUF_
), {ID::A
, ID::E
}, {ID::Y
}, true);
181 void setup_stdcells_eval()
183 setup_type(ID($_BUF_
), {ID::A
}, {ID::Y
}, true);
184 setup_type(ID($_NOT_
), {ID::A
}, {ID::Y
}, true);
185 setup_type(ID($_AND_
), {ID::A
, ID::B
}, {ID::Y
}, true);
186 setup_type(ID($_NAND_
), {ID::A
, ID::B
}, {ID::Y
}, true);
187 setup_type(ID($_OR_
), {ID::A
, ID::B
}, {ID::Y
}, true);
188 setup_type(ID($_NOR_
), {ID::A
, ID::B
}, {ID::Y
}, true);
189 setup_type(ID($_XOR_
), {ID::A
, ID::B
}, {ID::Y
}, true);
190 setup_type(ID($_XNOR_
), {ID::A
, ID::B
}, {ID::Y
}, true);
191 setup_type(ID($_ANDNOT_
), {ID::A
, ID::B
}, {ID::Y
}, true);
192 setup_type(ID($_ORNOT_
), {ID::A
, ID::B
}, {ID::Y
}, true);
193 setup_type(ID($_MUX_
), {ID::A
, ID::B
, ID::S
}, {ID::Y
}, true);
194 setup_type(ID($_NMUX_
), {ID::A
, ID::B
, ID::S
}, {ID::Y
}, true);
195 setup_type(ID($_MUX4_
), {ID::A
, ID::B
, ID::C
, ID::D
, ID::S
, ID::T
}, {ID::Y
}, true);
196 setup_type(ID($_MUX8_
), {ID::A
, ID::B
, ID::C
, ID::D
, ID::E
, ID::F
, ID::G
, ID::H
, ID::S
, ID::T
, ID::U
}, {ID::Y
}, true);
197 setup_type(ID($_MUX16_
), {ID::A
, ID::B
, ID::C
, ID::D
, ID::E
, ID::F
, ID::G
, ID::H
, ID::I
, ID::J
, ID::K
, ID::L
, ID::M
, ID::N
, ID::O
, ID::P
, ID::S
, ID::T
, ID::U
, ID::V
}, {ID::Y
}, true);
198 setup_type(ID($_AOI3_
), {ID::A
, ID::B
, ID::C
}, {ID::Y
}, true);
199 setup_type(ID($_OAI3_
), {ID::A
, ID::B
, ID::C
}, {ID::Y
}, true);
200 setup_type(ID($_AOI4_
), {ID::A
, ID::B
, ID::C
, ID::D
}, {ID::Y
}, true);
201 setup_type(ID($_OAI4_
), {ID::A
, ID::B
, ID::C
, ID::D
}, {ID::Y
}, true);
204 void setup_stdcells_mem()
206 std::vector
<char> list_np
= {'N', 'P'}, list_01
= {'0', '1'};
208 for (auto c1
: list_np
)
209 for (auto c2
: list_np
)
210 setup_type(stringf("$_SR_%c%c_", c1
, c2
), {ID::S
, ID::R
}, {ID::Q
});
212 setup_type(ID($_FF_
), {ID::D
}, {ID::Q
});
214 for (auto c1
: list_np
)
215 setup_type(stringf("$_DFF_%c_", c1
), {ID::C
, ID::D
}, {ID::Q
});
217 for (auto c1
: list_np
)
218 for (auto c2
: list_np
)
219 setup_type(stringf("$_DFFE_%c%c_", c1
, c2
), {ID::C
, ID::D
, ID::E
}, {ID::Q
});
221 for (auto c1
: list_np
)
222 for (auto c2
: list_np
)
223 for (auto c3
: list_01
)
224 setup_type(stringf("$_DFF_%c%c%c_", c1
, c2
, c3
), {ID::C
, ID::R
, ID::D
}, {ID::Q
});
226 for (auto c1
: list_np
)
227 for (auto c2
: list_np
)
228 for (auto c3
: list_01
)
229 for (auto c4
: list_np
)
230 setup_type(stringf("$_DFFE_%c%c%c%c_", c1
, c2
, c3
, c4
), {ID::C
, ID::R
, ID::D
, ID::E
}, {ID::Q
});
232 for (auto c1
: list_np
)
233 for (auto c2
: list_np
)
234 setup_type(stringf("$_ALDFF_%c%c_", c1
, c2
), {ID::C
, ID::L
, ID::AD
, ID::D
}, {ID::Q
});
236 for (auto c1
: list_np
)
237 for (auto c2
: list_np
)
238 for (auto c3
: list_np
)
239 setup_type(stringf("$_ALDFFE_%c%c%c_", c1
, c2
, c3
), {ID::C
, ID::L
, ID::AD
, ID::D
, ID::E
}, {ID::Q
});
241 for (auto c1
: list_np
)
242 for (auto c2
: list_np
)
243 for (auto c3
: list_np
)
244 setup_type(stringf("$_DFFSR_%c%c%c_", c1
, c2
, c3
), {ID::C
, ID::S
, ID::R
, ID::D
}, {ID::Q
});
246 for (auto c1
: list_np
)
247 for (auto c2
: list_np
)
248 for (auto c3
: list_np
)
249 for (auto c4
: list_np
)
250 setup_type(stringf("$_DFFSRE_%c%c%c%c_", c1
, c2
, c3
, c4
), {ID::C
, ID::S
, ID::R
, ID::D
, ID::E
}, {ID::Q
});
252 for (auto c1
: list_np
)
253 for (auto c2
: list_np
)
254 for (auto c3
: list_01
)
255 setup_type(stringf("$_SDFF_%c%c%c_", c1
, c2
, c3
), {ID::C
, ID::R
, ID::D
}, {ID::Q
});
257 for (auto c1
: list_np
)
258 for (auto c2
: list_np
)
259 for (auto c3
: list_01
)
260 for (auto c4
: list_np
)
261 setup_type(stringf("$_SDFFE_%c%c%c%c_", c1
, c2
, c3
, c4
), {ID::C
, ID::R
, ID::D
, ID::E
}, {ID::Q
});
263 for (auto c1
: list_np
)
264 for (auto c2
: list_np
)
265 for (auto c3
: list_01
)
266 for (auto c4
: list_np
)
267 setup_type(stringf("$_SDFFCE_%c%c%c%c_", c1
, c2
, c3
, c4
), {ID::C
, ID::R
, ID::D
, ID::E
}, {ID::Q
});
269 for (auto c1
: list_np
)
270 setup_type(stringf("$_DLATCH_%c_", c1
), {ID::E
, ID::D
}, {ID::Q
});
272 for (auto c1
: list_np
)
273 for (auto c2
: list_np
)
274 for (auto c3
: list_01
)
275 setup_type(stringf("$_DLATCH_%c%c%c_", c1
, c2
, c3
), {ID::E
, ID::R
, ID::D
}, {ID::Q
});
277 for (auto c1
: list_np
)
278 for (auto c2
: list_np
)
279 for (auto c3
: list_np
)
280 setup_type(stringf("$_DLATCHSR_%c%c%c_", c1
, c2
, c3
), {ID::E
, ID::S
, ID::R
, ID::D
}, {ID::Q
});
288 bool cell_known(RTLIL::IdString type
) const
290 return cell_types
.count(type
) != 0;
293 bool cell_output(RTLIL::IdString type
, RTLIL::IdString port
) const
295 auto it
= cell_types
.find(type
);
296 return it
!= cell_types
.end() && it
->second
.outputs
.count(port
) != 0;
299 bool cell_input(RTLIL::IdString type
, RTLIL::IdString port
) const
301 auto it
= cell_types
.find(type
);
302 return it
!= cell_types
.end() && it
->second
.inputs
.count(port
) != 0;
305 bool cell_evaluable(RTLIL::IdString type
) const
307 auto it
= cell_types
.find(type
);
308 return it
!= cell_types
.end() && it
->second
.is_evaluable
;
311 static RTLIL::Const
eval_not(RTLIL::Const v
)
313 for (auto &bit
: v
.bits
)
314 if (bit
== State::S0
) bit
= State::S1
;
315 else if (bit
== State::S1
) bit
= State::S0
;
319 static RTLIL::Const
eval(RTLIL::IdString type
, const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
, bool *errp
= nullptr)
321 if (type
== ID($sshr
) && !signed1
)
323 if (type
== ID($sshl
) && !signed1
)
326 if (type
!= ID($sshr
) && type
!= ID($sshl
) && type
!= ID($shr
) && type
!= ID($shl
) && type
!= ID($shift
) && type
!= ID($shiftx
) &&
327 type
!= ID($pos
) && type
!= ID($neg
) && type
!= ID($
not)) {
328 if (!signed1
|| !signed2
)
329 signed1
= false, signed2
= false;
332 #define HANDLE_CELL_TYPE(_t) if (type == ID($##_t)) return const_ ## _t(arg1, arg2, signed1, signed2, result_len);
333 HANDLE_CELL_TYPE(not)
334 HANDLE_CELL_TYPE(and)
336 HANDLE_CELL_TYPE(xor)
337 HANDLE_CELL_TYPE(xnor
)
338 HANDLE_CELL_TYPE(reduce_and
)
339 HANDLE_CELL_TYPE(reduce_or
)
340 HANDLE_CELL_TYPE(reduce_xor
)
341 HANDLE_CELL_TYPE(reduce_xnor
)
342 HANDLE_CELL_TYPE(reduce_bool
)
343 HANDLE_CELL_TYPE(logic_not
)
344 HANDLE_CELL_TYPE(logic_and
)
345 HANDLE_CELL_TYPE(logic_or
)
346 HANDLE_CELL_TYPE(shl
)
347 HANDLE_CELL_TYPE(shr
)
348 HANDLE_CELL_TYPE(sshl
)
349 HANDLE_CELL_TYPE(sshr
)
350 HANDLE_CELL_TYPE(shift
)
351 HANDLE_CELL_TYPE(shiftx
)
356 HANDLE_CELL_TYPE(eqx
)
357 HANDLE_CELL_TYPE(nex
)
360 HANDLE_CELL_TYPE(add
)
361 HANDLE_CELL_TYPE(sub
)
362 HANDLE_CELL_TYPE(mul
)
363 HANDLE_CELL_TYPE(div
)
364 HANDLE_CELL_TYPE(mod
)
365 HANDLE_CELL_TYPE(divfloor
)
366 HANDLE_CELL_TYPE(modfloor
)
367 HANDLE_CELL_TYPE(pow
)
368 HANDLE_CELL_TYPE(pos
)
369 HANDLE_CELL_TYPE(neg
)
370 #undef HANDLE_CELL_TYPE
372 if (type
== ID($_BUF_
))
374 if (type
== ID($_NOT_
))
375 return eval_not(arg1
);
376 if (type
== ID($_AND_
))
377 return const_and(arg1
, arg2
, false, false, 1);
378 if (type
== ID($_NAND_
))
379 return eval_not(const_and(arg1
, arg2
, false, false, 1));
380 if (type
== ID($_OR_
))
381 return const_or(arg1
, arg2
, false, false, 1);
382 if (type
== ID($_NOR_
))
383 return eval_not(const_or(arg1
, arg2
, false, false, 1));
384 if (type
== ID($_XOR_
))
385 return const_xor(arg1
, arg2
, false, false, 1);
386 if (type
== ID($_XNOR_
))
387 return const_xnor(arg1
, arg2
, false, false, 1);
388 if (type
== ID($_ANDNOT_
))
389 return const_and(arg1
, eval_not(arg2
), false, false, 1);
390 if (type
== ID($_ORNOT_
))
391 return const_or(arg1
, eval_not(arg2
), false, false, 1);
393 if (errp
!= nullptr) {
401 static RTLIL::Const
eval(RTLIL::Cell
*cell
, const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool *errp
= nullptr)
403 if (cell
->type
== ID($slice
)) {
405 int width
= cell
->parameters
.at(ID::Y_WIDTH
).as_int();
406 int offset
= cell
->parameters
.at(ID::OFFSET
).as_int();
407 ret
.bits
.insert(ret
.bits
.end(), arg1
.bits
.begin()+offset
, arg1
.bits
.begin()+offset
+width
);
411 if (cell
->type
== ID($concat
)) {
412 RTLIL::Const ret
= arg1
;
413 ret
.bits
.insert(ret
.bits
.end(), arg2
.bits
.begin(), arg2
.bits
.end());
417 if (cell
->type
== ID($bmux
))
419 return const_bmux(arg1
, arg2
);
422 if (cell
->type
== ID($demux
))
424 return const_demux(arg1
, arg2
);
427 if (cell
->type
== ID($lut
))
429 int width
= cell
->parameters
.at(ID::WIDTH
).as_int();
431 std::vector
<RTLIL::State
> t
= cell
->parameters
.at(ID::LUT
).bits
;
432 while (GetSize(t
) < (1 << width
))
433 t
.push_back(State::S0
);
434 t
.resize(1 << width
);
436 return const_bmux(t
, arg1
);
439 if (cell
->type
== ID($sop
))
441 int width
= cell
->parameters
.at(ID::WIDTH
).as_int();
442 int depth
= cell
->parameters
.at(ID::DEPTH
).as_int();
443 std::vector
<RTLIL::State
> t
= cell
->parameters
.at(ID::TABLE
).bits
;
445 while (GetSize(t
) < width
*depth
*2)
446 t
.push_back(State::S0
);
448 RTLIL::State default_ret
= State::S0
;
450 for (int i
= 0; i
< depth
; i
++)
455 for (int j
= 0; j
< width
; j
++) {
456 RTLIL::State a
= arg1
.bits
.at(j
);
457 if (t
.at(2*width
*i
+ 2*j
+ 0) == State::S1
) {
458 if (a
== State::S1
) match_x
= false;
459 if (a
!= State::S0
) match
= false;
461 if (t
.at(2*width
*i
+ 2*j
+ 1) == State::S1
) {
462 if (a
== State::S0
) match_x
= false;
463 if (a
!= State::S1
) match
= false;
471 default_ret
= State::Sx
;
477 bool signed_a
= cell
->parameters
.count(ID::A_SIGNED
) > 0 && cell
->parameters
[ID::A_SIGNED
].as_bool();
478 bool signed_b
= cell
->parameters
.count(ID::B_SIGNED
) > 0 && cell
->parameters
[ID::B_SIGNED
].as_bool();
479 int result_len
= cell
->parameters
.count(ID::Y_WIDTH
) > 0 ? cell
->parameters
[ID::Y_WIDTH
].as_int() : -1;
480 return eval(cell
->type
, arg1
, arg2
, signed_a
, signed_b
, result_len
, errp
);
483 static RTLIL::Const
eval(RTLIL::Cell
*cell
, const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, const RTLIL::Const
&arg3
, bool *errp
= nullptr)
485 if (cell
->type
.in(ID($mux
), ID($pmux
), ID($_MUX_
))) {
486 RTLIL::Const ret
= arg1
;
487 for (size_t i
= 0; i
< arg3
.bits
.size(); i
++)
488 if (arg3
.bits
[i
] == RTLIL::State::S1
) {
489 std::vector
<RTLIL::State
> bits(arg2
.bits
.begin() + i
*arg1
.bits
.size(), arg2
.bits
.begin() + (i
+1)*arg1
.bits
.size());
490 ret
= RTLIL::Const(bits
);
495 if (cell
->type
== ID($_AOI3_
))
496 return eval_not(const_or(const_and(arg1
, arg2
, false, false, 1), arg3
, false, false, 1));
497 if (cell
->type
== ID($_OAI3_
))
498 return eval_not(const_and(const_or(arg1
, arg2
, false, false, 1), arg3
, false, false, 1));
500 log_assert(arg3
.bits
.size() == 0);
501 return eval(cell
, arg1
, arg2
, errp
);
504 static RTLIL::Const
eval(RTLIL::Cell
*cell
, const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, const RTLIL::Const
&arg3
, const RTLIL::Const
&arg4
, bool *errp
= nullptr)
506 if (cell
->type
== ID($_AOI4_
))
507 return eval_not(const_or(const_and(arg1
, arg2
, false, false, 1), const_and(arg3
, arg4
, false, false, 1), false, false, 1));
508 if (cell
->type
== ID($_OAI4_
))
509 return eval_not(const_and(const_or(arg1
, arg2
, false, false, 1), const_or(arg3
, arg4
, false, false, 1), false, false, 1));
511 log_assert(arg4
.bits
.size() == 0);
512 return eval(cell
, arg1
, arg2
, arg3
, errp
);
516 // initialized by yosys_setup()
517 extern CellTypes yosys_celltypes
;