2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
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
));
138 if (!eval(sig_s
, undef
, cell
))
142 if (cell
->hasPort(ID::A
))
143 sig_a
= cell
->getPort(ID::A
);
145 if (cell
->hasPort(ID::B
))
146 sig_b
= cell
->getPort(ID::B
);
148 if (cell
->type
.in(ID($mux
), ID($pmux
), ID($_MUX_
), ID($_NMUX_
)))
150 std::vector
<RTLIL::SigSpec
> y_candidates
;
151 int count_maybe_set_s_bits
= 0;
152 int count_set_s_bits
= 0;
154 for (int i
= 0; i
< sig_s
.size(); i
++)
156 RTLIL::State s_bit
= sig_s
.extract(i
, 1).as_const().bits
.at(0);
157 RTLIL::SigSpec b_slice
= sig_b
.extract(sig_y
.size()*i
, sig_y
.size());
159 if (s_bit
== RTLIL::State::Sx
|| s_bit
== RTLIL::State::S1
)
160 y_candidates
.push_back(b_slice
);
162 if (s_bit
== RTLIL::State::S1
|| s_bit
== RTLIL::State::Sx
)
163 count_maybe_set_s_bits
++;
165 if (s_bit
== RTLIL::State::S1
)
169 if (count_set_s_bits
== 0)
170 y_candidates
.push_back(sig_a
);
172 std::vector
<RTLIL::Const
> y_values
;
174 log_assert(y_candidates
.size() > 0);
175 for (auto &yc
: y_candidates
) {
176 if (!eval(yc
, undef
, cell
))
178 if (cell
->type
== ID($_NMUX_
))
179 y_values
.push_back(RTLIL::const_not(yc
.as_const(), Const(), false, false, GetSize(yc
)));
181 y_values
.push_back(yc
.as_const());
184 if (y_values
.size() > 1)
186 std::vector
<RTLIL::State
> master_bits
= y_values
.at(0).bits
;
188 for (size_t i
= 1; i
< y_values
.size(); i
++) {
189 std::vector
<RTLIL::State
> &slave_bits
= y_values
.at(i
).bits
;
190 log_assert(master_bits
.size() == slave_bits
.size());
191 for (size_t j
= 0; j
< master_bits
.size(); j
++)
192 if (master_bits
[j
] != slave_bits
[j
])
193 master_bits
[j
] = RTLIL::State::Sx
;
196 set(sig_y
, RTLIL::Const(master_bits
));
199 set(sig_y
, y_values
.front());
201 else if (cell
->type
== ID($fa
))
203 RTLIL::SigSpec sig_c
= cell
->getPort(ID(C
));
204 RTLIL::SigSpec sig_x
= cell
->getPort(ID(X
));
205 int width
= GetSize(sig_c
);
207 if (!eval(sig_a
, undef
, cell
))
210 if (!eval(sig_b
, undef
, cell
))
213 if (!eval(sig_c
, undef
, cell
))
216 RTLIL::Const t1
= const_xor(sig_a
.as_const(), sig_b
.as_const(), false, false, width
);
217 RTLIL::Const val_y
= const_xor(t1
, sig_c
.as_const(), false, false, width
);
219 RTLIL::Const t2
= const_and(sig_a
.as_const(), sig_b
.as_const(), false, false, width
);
220 RTLIL::Const t3
= const_and(sig_c
.as_const(), t1
, false, false, width
);
221 RTLIL::Const val_x
= const_or(t2
, t3
, false, false, width
);
223 for (int i
= 0; i
< GetSize(val_y
); i
++)
224 if (val_y
.bits
[i
] == RTLIL::Sx
)
225 val_x
.bits
[i
] = RTLIL::Sx
;
230 else if (cell
->type
== ID($alu
))
232 bool signed_a
= cell
->parameters
.count(ID(A_SIGNED
)) > 0 && cell
->parameters
[ID(A_SIGNED
)].as_bool();
233 bool signed_b
= cell
->parameters
.count(ID(B_SIGNED
)) > 0 && cell
->parameters
[ID(B_SIGNED
)].as_bool();
235 RTLIL::SigSpec sig_ci
= cell
->getPort(ID(CI
));
236 RTLIL::SigSpec sig_bi
= cell
->getPort(ID(BI
));
238 if (!eval(sig_a
, undef
, cell
))
241 if (!eval(sig_b
, undef
, cell
))
244 if (!eval(sig_ci
, undef
, cell
))
247 if (!eval(sig_bi
, undef
, cell
))
250 RTLIL::SigSpec sig_x
= cell
->getPort(ID(X
));
251 RTLIL::SigSpec sig_co
= cell
->getPort(ID(CO
));
253 bool any_input_undef
= !(sig_a
.is_fully_def() && sig_b
.is_fully_def() && sig_ci
.is_fully_def() && sig_bi
.is_fully_def());
254 sig_a
.extend_u0(GetSize(sig_y
), signed_a
);
255 sig_b
.extend_u0(GetSize(sig_y
), signed_b
);
257 bool carry
= sig_ci
[0] == State::S1
;
258 bool b_inv
= sig_bi
[0] == State::S1
;
260 for (int i
= 0; i
< GetSize(sig_y
); i
++)
262 RTLIL::SigSpec x_inputs
= { sig_a
[i
], sig_b
[i
], sig_bi
[0] };
264 if (!x_inputs
.is_fully_def()) {
265 set(sig_x
[i
], RTLIL::Sx
);
267 bool bit_a
= sig_a
[i
] == State::S1
;
268 bool bit_b
= (sig_b
[i
] == State::S1
) != b_inv
;
269 bool bit_x
= bit_a
!= bit_b
;
270 set(sig_x
[i
], bit_x
? State::S1
: State::S0
);
273 if (any_input_undef
) {
274 set(sig_y
[i
], RTLIL::Sx
);
275 set(sig_co
[i
], RTLIL::Sx
);
277 bool bit_a
= sig_a
[i
] == State::S1
;
278 bool bit_b
= (sig_b
[i
] == State::S1
) != b_inv
;
279 bool bit_y
= (bit_a
!= bit_b
) != carry
;
280 carry
= (bit_a
&& bit_b
) || (bit_a
&& carry
) || (bit_b
&& carry
);
281 set(sig_y
[i
], bit_y
? State::S1
: State::S0
);
282 set(sig_co
[i
], carry
? State::S1
: State::S0
);
286 else if (cell
->type
== ID($macc
))
289 macc
.from_cell(cell
);
291 if (!eval(macc
.bit_ports
, undef
, cell
))
294 for (auto &port
: macc
.ports
) {
295 if (!eval(port
.in_a
, undef
, cell
))
297 if (!eval(port
.in_b
, undef
, cell
))
301 RTLIL::Const
result(0, GetSize(cell
->getPort(ID::Y
)));
302 if (!macc
.eval(result
))
305 set(cell
->getPort(ID::Y
), result
);
309 RTLIL::SigSpec sig_c
, sig_d
;
311 if (cell
->type
.in(ID($_AOI3_
), ID($_OAI3_
), ID($_AOI4_
), ID($_OAI4_
))) {
312 if (cell
->hasPort(ID(C
)))
313 sig_c
= cell
->getPort(ID(C
));
314 if (cell
->hasPort(ID(D
)))
315 sig_d
= cell
->getPort(ID(D
));
318 if (sig_a
.size() > 0 && !eval(sig_a
, undef
, cell
))
320 if (sig_b
.size() > 0 && !eval(sig_b
, undef
, cell
))
322 if (sig_c
.size() > 0 && !eval(sig_c
, undef
, cell
))
324 if (sig_d
.size() > 0 && !eval(sig_d
, undef
, cell
))
327 bool eval_err
= false;
328 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
);
333 set(sig_y
, eval_ret
);
339 bool eval(RTLIL::SigSpec
&sig
, RTLIL::SigSpec
&undef
, RTLIL::Cell
*busy_cell
= NULL
)
341 assign_map
.apply(sig
);
342 values_map
.apply(sig
);
344 if (sig
.is_fully_const())
347 if (stop_signals
.check_any(sig
)) {
348 undef
= stop_signals
.extract(sig
);
353 if (busy
.count(busy_cell
) > 0) {
357 busy
.insert(busy_cell
);
360 std::set
<RTLIL::Cell
*> driver_cells
;
361 sig2driver
.find(sig
, driver_cells
);
362 for (auto cell
: driver_cells
) {
363 if (!eval(cell
, undef
)) {
365 busy
.erase(busy_cell
);
371 busy
.erase(busy_cell
);
373 values_map
.apply(sig
);
374 if (sig
.is_fully_const())
377 if (defaultval
!= RTLIL::State::Sm
) {
378 for (auto &bit
: sig
)
379 if (bit
.wire
) bit
= defaultval
;
383 for (auto &c
: sig
.chunks())
389 bool eval(RTLIL::SigSpec
&sig
)
391 RTLIL::SigSpec undef
;
392 return eval(sig
, undef
);