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/rtlil.h"
24 #include "kernel/sigtools.h"
25 #include "kernel/celltypes.h"
26 #include "kernel/macc.h"
32 RTLIL::Module
*module
;
36 SigSet
<RTLIL::Cell
*> sig2driver
;
37 std::set
<RTLIL::Cell
*> busy
;
38 std::vector
<SigMap
> stack
;
39 RTLIL::State defaultval
;
41 ConstEval(RTLIL::Module
*module
, RTLIL::State defaultval
= RTLIL::State::Sm
) : module(module
), assign_map(module
), defaultval(defaultval
)
47 for (auto &it
: module
->cells_
) {
48 if (!ct
.cell_known(it
.second
->type
))
50 for (auto &it2
: it
.second
->connections())
51 if (ct
.cell_output(it
.second
->type
, it2
.first
))
52 sig2driver
.insert(assign_map(it2
.second
), it
.second
);
64 stack
.push_back(values_map
);
69 values_map
.swap(stack
.back());
73 void set(RTLIL::SigSpec sig
, RTLIL::Const value
)
75 assign_map
.apply(sig
);
77 RTLIL::SigSpec current_val
= values_map(sig
);
78 for (int i
= 0; i
< GetSize(current_val
); i
++)
79 log_assert(current_val
[i
].wire
!= NULL
|| current_val
[i
] == value
.bits
[i
]);
81 values_map
.add(sig
, RTLIL::SigSpec(value
));
84 void stop(RTLIL::SigSpec sig
)
86 assign_map
.apply(sig
);
87 stop_signals
.add(sig
);
90 bool eval(RTLIL::Cell
*cell
, RTLIL::SigSpec
&undef
)
92 if (cell
->type
== ID($lcu
))
94 RTLIL::SigSpec sig_p
= cell
->getPort(ID::P
);
95 RTLIL::SigSpec sig_g
= cell
->getPort(ID::G
);
96 RTLIL::SigSpec sig_ci
= cell
->getPort(ID::CI
);
97 RTLIL::SigSpec sig_co
= values_map(assign_map(cell
->getPort(ID::CO
)));
99 if (sig_co
.is_fully_const())
102 if (!eval(sig_p
, undef
, cell
))
105 if (!eval(sig_g
, undef
, cell
))
108 if (!eval(sig_ci
, undef
, cell
))
111 if (sig_p
.is_fully_def() && sig_g
.is_fully_def() && sig_ci
.is_fully_def())
113 RTLIL::Const
coval(RTLIL::Sx
, GetSize(sig_co
));
114 bool carry
= sig_ci
.as_bool();
116 for (int i
= 0; i
< GetSize(coval
); i
++) {
117 carry
= (sig_g
[i
] == State::S1
) || (sig_p
[i
] == RTLIL::S1
&& carry
);
118 coval
.bits
[i
] = carry
? State::S1
: State::S0
;
124 set(sig_co
, RTLIL::Const(RTLIL::Sx
, GetSize(sig_co
)));
129 RTLIL::SigSpec sig_a
, sig_b
, sig_s
, sig_y
;
131 log_assert(cell
->hasPort(ID::Y
));
132 sig_y
= values_map(assign_map(cell
->getPort(ID::Y
)));
133 if (sig_y
.is_fully_const())
136 if (cell
->hasPort(ID::S
)) {
137 sig_s
= cell
->getPort(ID::S
);
140 if (cell
->hasPort(ID::A
))
141 sig_a
= cell
->getPort(ID::A
);
143 if (cell
->hasPort(ID::B
))
144 sig_b
= cell
->getPort(ID::B
);
146 if (cell
->type
.in(ID($mux
), ID($pmux
), ID($_MUX_
), ID($_NMUX_
)))
148 std::vector
<RTLIL::SigSpec
> y_candidates
;
149 int count_maybe_set_s_bits
= 0;
150 int count_set_s_bits
= 0;
152 if (!eval(sig_s
, undef
, cell
))
155 for (int i
= 0; i
< sig_s
.size(); i
++)
157 RTLIL::State s_bit
= sig_s
.extract(i
, 1).as_const().bits
.at(0);
158 RTLIL::SigSpec b_slice
= sig_b
.extract(sig_y
.size()*i
, sig_y
.size());
160 if (s_bit
== RTLIL::State::Sx
|| s_bit
== RTLIL::State::S1
)
161 y_candidates
.push_back(b_slice
);
163 if (s_bit
== RTLIL::State::S1
|| s_bit
== RTLIL::State::Sx
)
164 count_maybe_set_s_bits
++;
166 if (s_bit
== RTLIL::State::S1
)
170 if (count_set_s_bits
== 0)
171 y_candidates
.push_back(sig_a
);
173 std::vector
<RTLIL::Const
> y_values
;
175 log_assert(y_candidates
.size() > 0);
176 for (auto &yc
: y_candidates
) {
177 if (!eval(yc
, undef
, cell
))
179 if (cell
->type
== ID($_NMUX_
))
180 y_values
.push_back(RTLIL::const_not(yc
.as_const(), Const(), false, false, GetSize(yc
)));
182 y_values
.push_back(yc
.as_const());
185 if (y_values
.size() > 1)
187 std::vector
<RTLIL::State
> master_bits
= y_values
.at(0).bits
;
189 for (size_t i
= 1; i
< y_values
.size(); i
++) {
190 std::vector
<RTLIL::State
> &slave_bits
= y_values
.at(i
).bits
;
191 log_assert(master_bits
.size() == slave_bits
.size());
192 for (size_t j
= 0; j
< master_bits
.size(); j
++)
193 if (master_bits
[j
] != slave_bits
[j
])
194 master_bits
[j
] = RTLIL::State::Sx
;
197 set(sig_y
, RTLIL::Const(master_bits
));
200 set(sig_y
, y_values
.front());
202 else if (cell
->type
== ID($bmux
))
204 if (!eval(sig_s
, undef
, cell
))
207 if (sig_s
.is_fully_def()) {
208 int sel
= sig_s
.as_int();
209 int width
= GetSize(sig_y
);
210 SigSpec res
= sig_a
.extract(sel
* width
, width
);
211 if (!eval(res
, undef
, cell
))
213 set(sig_y
, res
.as_const());
215 if (!eval(sig_a
, undef
, cell
))
217 set(sig_y
, const_bmux(sig_a
.as_const(), sig_s
.as_const()));
220 else if (cell
->type
== ID($demux
))
222 if (!eval(sig_a
, undef
, cell
))
224 if (sig_a
.is_fully_zero()) {
225 set(sig_y
, Const(0, GetSize(sig_y
)));
227 if (!eval(sig_s
, undef
, cell
))
229 set(sig_y
, const_demux(sig_a
.as_const(), sig_s
.as_const()));
232 else if (cell
->type
== ID($fa
))
234 RTLIL::SigSpec sig_c
= cell
->getPort(ID::C
);
235 RTLIL::SigSpec sig_x
= cell
->getPort(ID::X
);
236 int width
= GetSize(sig_c
);
238 if (!eval(sig_a
, undef
, cell
))
241 if (!eval(sig_b
, undef
, cell
))
244 if (!eval(sig_c
, undef
, cell
))
247 RTLIL::Const t1
= const_xor(sig_a
.as_const(), sig_b
.as_const(), false, false, width
);
248 RTLIL::Const val_y
= const_xor(t1
, sig_c
.as_const(), false, false, width
);
250 RTLIL::Const t2
= const_and(sig_a
.as_const(), sig_b
.as_const(), false, false, width
);
251 RTLIL::Const t3
= const_and(sig_c
.as_const(), t1
, false, false, width
);
252 RTLIL::Const val_x
= const_or(t2
, t3
, false, false, width
);
254 for (int i
= 0; i
< GetSize(val_y
); i
++)
255 if (val_y
.bits
[i
] == RTLIL::Sx
)
256 val_x
.bits
[i
] = RTLIL::Sx
;
261 else if (cell
->type
== ID($alu
))
263 bool signed_a
= cell
->parameters
.count(ID::A_SIGNED
) > 0 && cell
->parameters
[ID::A_SIGNED
].as_bool();
264 bool signed_b
= cell
->parameters
.count(ID::B_SIGNED
) > 0 && cell
->parameters
[ID::B_SIGNED
].as_bool();
266 RTLIL::SigSpec sig_ci
= cell
->getPort(ID::CI
);
267 RTLIL::SigSpec sig_bi
= cell
->getPort(ID::BI
);
269 if (!eval(sig_a
, undef
, cell
))
272 if (!eval(sig_b
, undef
, cell
))
275 if (!eval(sig_ci
, undef
, cell
))
278 if (!eval(sig_bi
, undef
, cell
))
281 RTLIL::SigSpec sig_x
= cell
->getPort(ID::X
);
282 RTLIL::SigSpec sig_co
= cell
->getPort(ID::CO
);
284 bool any_input_undef
= !(sig_a
.is_fully_def() && sig_b
.is_fully_def() && sig_ci
.is_fully_def() && sig_bi
.is_fully_def());
285 sig_a
.extend_u0(GetSize(sig_y
), signed_a
);
286 sig_b
.extend_u0(GetSize(sig_y
), signed_b
);
288 bool carry
= sig_ci
[0] == State::S1
;
289 bool b_inv
= sig_bi
[0] == State::S1
;
291 for (int i
= 0; i
< GetSize(sig_y
); i
++)
293 RTLIL::SigSpec x_inputs
= { sig_a
[i
], sig_b
[i
], sig_bi
[0] };
295 if (!x_inputs
.is_fully_def()) {
296 set(sig_x
[i
], RTLIL::Sx
);
298 bool bit_a
= sig_a
[i
] == State::S1
;
299 bool bit_b
= (sig_b
[i
] == State::S1
) != b_inv
;
300 bool bit_x
= bit_a
!= bit_b
;
301 set(sig_x
[i
], bit_x
? State::S1
: State::S0
);
304 if (any_input_undef
) {
305 set(sig_y
[i
], RTLIL::Sx
);
306 set(sig_co
[i
], RTLIL::Sx
);
308 bool bit_a
= sig_a
[i
] == State::S1
;
309 bool bit_b
= (sig_b
[i
] == State::S1
) != b_inv
;
310 bool bit_y
= (bit_a
!= bit_b
) != carry
;
311 carry
= (bit_a
&& bit_b
) || (bit_a
&& carry
) || (bit_b
&& carry
);
312 set(sig_y
[i
], bit_y
? State::S1
: State::S0
);
313 set(sig_co
[i
], carry
? State::S1
: State::S0
);
317 else if (cell
->type
== ID($macc
))
320 macc
.from_cell(cell
);
322 if (!eval(macc
.bit_ports
, undef
, cell
))
325 for (auto &port
: macc
.ports
) {
326 if (!eval(port
.in_a
, undef
, cell
))
328 if (!eval(port
.in_b
, undef
, cell
))
332 RTLIL::Const
result(0, GetSize(cell
->getPort(ID::Y
)));
333 if (!macc
.eval(result
))
336 set(cell
->getPort(ID::Y
), result
);
340 RTLIL::SigSpec sig_c
, sig_d
;
342 if (cell
->type
.in(ID($_AOI3_
), ID($_OAI3_
), ID($_AOI4_
), ID($_OAI4_
))) {
343 if (cell
->hasPort(ID::C
))
344 sig_c
= cell
->getPort(ID::C
);
345 if (cell
->hasPort(ID::D
))
346 sig_d
= cell
->getPort(ID::D
);
349 if (sig_a
.size() > 0 && !eval(sig_a
, undef
, cell
))
351 if (sig_b
.size() > 0 && !eval(sig_b
, undef
, cell
))
353 if (sig_c
.size() > 0 && !eval(sig_c
, undef
, cell
))
355 if (sig_d
.size() > 0 && !eval(sig_d
, undef
, cell
))
358 bool eval_err
= false;
359 RTLIL::Const eval_ret
= CellTypes::eval(cell
, sig_a
.as_const(), sig_b
.as_const(), sig_c
.as_const(), sig_d
.as_const(), &eval_err
);
364 set(sig_y
, eval_ret
);
370 bool eval(RTLIL::SigSpec
&sig
, RTLIL::SigSpec
&undef
, RTLIL::Cell
*busy_cell
= NULL
)
372 assign_map
.apply(sig
);
373 values_map
.apply(sig
);
375 if (sig
.is_fully_const())
378 if (stop_signals
.check_any(sig
)) {
379 undef
= stop_signals
.extract(sig
);
384 if (busy
.count(busy_cell
) > 0) {
388 busy
.insert(busy_cell
);
391 std::set
<RTLIL::Cell
*> driver_cells
;
392 sig2driver
.find(sig
, driver_cells
);
393 for (auto cell
: driver_cells
) {
394 if (!eval(cell
, undef
)) {
396 busy
.erase(busy_cell
);
402 busy
.erase(busy_cell
);
404 values_map
.apply(sig
);
405 if (sig
.is_fully_const())
408 if (defaultval
!= RTLIL::State::Sm
) {
409 for (auto &bit
: sig
)
410 if (bit
.wire
) bit
= defaultval
;
414 for (auto &c
: sig
.chunks())
420 bool eval(RTLIL::SigSpec
&sig
)
422 RTLIL::SigSpec undef
;
423 return eval(sig
, undef
);