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.
20 #include "kernel/register.h"
21 #include "kernel/celltypes.h"
22 #include "kernel/sigtools.h"
23 #include "kernel/rtlil.h"
24 #include "kernel/log.h"
31 #define MODE_ANYCONST 5
34 PRIVATE_NAMESPACE_BEGIN
36 static RTLIL::Wire
* add_wire(RTLIL::Module
*module
, std::string name
, int width
, bool flag_input
, bool flag_output
)
38 RTLIL::Wire
*wire
= NULL
;
39 name
= RTLIL::escape_id(name
);
41 if (module
->count_id(name
) != 0)
43 log("Module %s already has such an object %s.\n", module
->name
.c_str(), name
.c_str());
45 return add_wire(module
, name
, width
, flag_input
, flag_output
);
49 wire
= module
->addWire(name
, width
);
50 wire
->port_input
= flag_input
;
51 wire
->port_output
= flag_output
;
53 if (flag_input
|| flag_output
) {
54 wire
->port_id
= module
->wires_
.size();
55 module
->fixup_ports();
58 log("Added wire %s to module %s.\n", name
.c_str(), module
->name
.c_str());
67 uint32_t next_bit_state
;
68 vector
<SigSpec
*> siglist
;
70 RTLIL::State
next_bit()
72 if (next_bit_mode
== MODE_ZERO
)
73 return RTLIL::State::S0
;
75 if (next_bit_mode
== MODE_ONE
)
76 return RTLIL::State::S1
;
78 if (next_bit_mode
== MODE_UNDEF
)
79 return RTLIL::State::Sx
;
81 if (next_bit_mode
== MODE_RANDOM
)
84 next_bit_state
^= next_bit_state
<< 13;
85 next_bit_state
^= next_bit_state
>> 17;
86 next_bit_state
^= next_bit_state
<< 5;
87 log_assert(next_bit_state
!= 0);
89 return ((next_bit_state
>> (next_bit_state
& 15)) & 16) ? RTLIL::State::S0
: RTLIL::State::S1
;
95 void operator()(RTLIL::SigSpec
&sig
)
97 if (next_bit_mode
== MODE_ANYSEQ
|| next_bit_mode
== MODE_ANYCONST
) {
98 siglist
.push_back(&sig
);
102 for (auto &bit
: sig
)
103 if (bit
.wire
== NULL
&& bit
.data
> RTLIL::State::S1
)
108 struct SetundefPass
: public Pass
{
109 SetundefPass() : Pass("setundef", "replace undef values with defined constants") { }
110 void help() YS_OVERRIDE
112 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
114 log(" setundef [options] [selection]\n");
116 log("This command replaces undef (x) constants with defined (0/1) constants.\n");
119 log(" also set undriven nets to constant values\n");
122 log(" also expose undriven nets as inputs (use with -undriven)\n");
125 log(" replace with bits cleared (0)\n");
128 log(" replace with bits set (1)\n");
131 log(" replace with undef (x) bits, may be used with -undriven\n");
134 log(" replace with $anyseq drivers (for formal)\n");
137 log(" replace with $anyconst drivers (for formal)\n");
139 log(" -random <seed>\n");
140 log(" replace with random bits using the specified integer as seed\n");
141 log(" value for the random number generator.\n");
144 log(" also create/update init values for flip-flops\n");
147 log(" replace undef in cell parameters\n");
150 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
152 bool got_value
= false;
153 bool undriven_mode
= false;
154 bool expose_mode
= false;
155 bool init_mode
= false;
156 bool params_mode
= false;
157 SetundefWorker worker
;
159 log_header(design
, "Executing SETUNDEF pass (replace undef values with defined constants).\n");
162 for (argidx
= 1; argidx
< args
.size(); argidx
++)
164 if (args
[argidx
] == "-undriven") {
165 undriven_mode
= true;
168 if (args
[argidx
] == "-expose") {
172 if (args
[argidx
] == "-zero") {
174 worker
.next_bit_mode
= MODE_ZERO
;
175 worker
.next_bit_state
= 0;
178 if (args
[argidx
] == "-one") {
180 worker
.next_bit_mode
= MODE_ONE
;
181 worker
.next_bit_state
= 0;
184 if (args
[argidx
] == "-anyseq") {
186 worker
.next_bit_mode
= MODE_ANYSEQ
;
187 worker
.next_bit_state
= 0;
190 if (args
[argidx
] == "-anyconst") {
192 worker
.next_bit_mode
= MODE_ANYCONST
;
193 worker
.next_bit_state
= 0;
196 if (args
[argidx
] == "-undef") {
198 worker
.next_bit_mode
= MODE_UNDEF
;
199 worker
.next_bit_state
= 0;
202 if (args
[argidx
] == "-init") {
206 if (args
[argidx
] == "-params") {
210 if (args
[argidx
] == "-random" && !got_value
&& argidx
+1 < args
.size()) {
212 worker
.next_bit_mode
= MODE_RANDOM
;
213 worker
.next_bit_state
= atoi(args
[++argidx
].c_str()) + 1;
214 for (int i
= 0; i
< 10; i
++)
220 extra_args(args
, argidx
, design
);
222 if (!got_value
&& expose_mode
) {
223 log("Using default as -undef with -expose.\n");
225 worker
.next_bit_mode
= MODE_UNDEF
;
226 worker
.next_bit_state
= 0;
229 if (expose_mode
&& !undriven_mode
)
230 log_cmd_error("Option -expose must be used with option -undriven.\n");
232 log_cmd_error("One of the options -zero, -one, -anyseq, -anyconst, or -random <seed> must be specified.\n");
234 if (init_mode
&& (worker
.next_bit_mode
== MODE_ANYSEQ
|| worker
.next_bit_mode
== MODE_ANYCONST
))
235 log_cmd_error("The options -init and -anyseq / -anyconst are exclusive.\n");
237 for (auto module
: design
->selected_modules())
241 for (auto *cell
: module
->selected_cells()) {
242 for (auto ¶meter
: cell
->parameters
) {
243 for (auto &bit
: parameter
.second
.bits
) {
244 if (bit
> RTLIL::State::S1
)
245 bit
= worker
.next_bit();
253 if (!module
->processes
.empty())
254 log_error("The 'setundef' command can't operate in -undriven mode on modules with processes. Run 'proc' first.\n");
258 SigMap
sigmap(module
);
259 dict
<SigBit
, bool> wire_drivers
;
260 pool
<SigBit
> used_wires
;
261 SigPool undriven_signals
;
263 for (auto cell
: module
->cells())
264 for (auto &conn
: cell
->connections()) {
265 SigSpec sig
= sigmap(conn
.second
);
266 if (cell
->input(conn
.first
))
269 used_wires
.insert(bit
);
270 if (cell
->output(conn
.first
))
271 for (int i
= 0; i
< GetSize(sig
); i
++)
273 wire_drivers
[sig
[i
]] = true;
276 for (auto wire
: module
->wires()) {
277 if (wire
->port_input
) {
278 SigSpec sig
= sigmap(wire
);
279 for (int i
= 0; i
< GetSize(sig
); i
++)
280 wire_drivers
[sig
[i
]] = true;
282 if (wire
->port_output
) {
283 SigSpec sig
= sigmap(wire
);
286 used_wires
.insert(bit
);
290 pool
<RTLIL::Wire
*> undriven_wires
;
291 for (auto bit
: used_wires
)
292 if (!wire_drivers
.count(bit
))
293 undriven_wires
.insert(bit
.wire
);
295 for (auto &it
: undriven_wires
)
296 undriven_signals
.add(sigmap(it
));
298 for (auto &it
: undriven_wires
)
300 undriven_signals
.del(sigmap(it
));
302 CellTypes
ct(design
);
303 for (auto &it
: module
->cells_
)
304 for (auto &conn
: it
.second
->connections())
305 if (!ct
.cell_known(it
.second
->type
) || ct
.cell_output(it
.second
->type
, conn
.first
))
306 undriven_signals
.del(sigmap(conn
.second
));
308 RTLIL::SigSpec sig
= undriven_signals
.export_all();
309 for (auto &c
: sig
.chunks()) {
311 if (c
.wire
->width
== c
.width
) {
313 wire
->port_input
= true;
315 string name
= c
.wire
->name
.str() + "$[" + std::to_string(c
.width
+ c
.offset
) + ":" + std::to_string(c
.offset
) + "]";
316 wire
= add_wire(module
, name
, c
.width
, true, false);
317 module
->connect(RTLIL::SigSig(c
, wire
));
319 log("Exposing undriven wire %s as input.\n", wire
->name
.c_str());
321 module
->fixup_ports();
325 SigMap
sigmap(module
);
326 SigPool undriven_signals
;
328 for (auto &it
: module
->wires_
)
329 undriven_signals
.add(sigmap(it
.second
));
331 for (auto &it
: module
->wires_
)
332 if (it
.second
->port_input
)
333 undriven_signals
.del(sigmap(it
.second
));
335 CellTypes
ct(design
);
336 for (auto &it
: module
->cells_
)
337 for (auto &conn
: it
.second
->connections())
338 if (!ct
.cell_known(it
.second
->type
) || ct
.cell_output(it
.second
->type
, conn
.first
))
339 undriven_signals
.del(sigmap(conn
.second
));
341 RTLIL::SigSpec sig
= undriven_signals
.export_all();
342 for (auto &c
: sig
.chunks()) {
344 if (worker
.next_bit_mode
== MODE_ANYSEQ
)
345 bits
= module
->Anyseq(NEW_ID
, c
.width
);
346 else if (worker
.next_bit_mode
== MODE_ANYCONST
)
347 bits
= module
->Anyconst(NEW_ID
, c
.width
);
349 for (int i
= 0; i
< c
.width
; i
++)
350 bits
.append(worker
.next_bit());
351 module
->connect(RTLIL::SigSig(c
, bits
));
358 SigMap
sigmap(module
);
360 pool
<Wire
*> initwires
;
362 pool
<IdString
> fftypes
;
363 fftypes
.insert("$dff");
364 fftypes
.insert("$dffe");
365 fftypes
.insert("$dffsr");
366 fftypes
.insert("$adff");
368 std::vector
<char> list_np
= {'N', 'P'}, list_01
= {'0', '1'};
370 for (auto c1
: list_np
)
371 fftypes
.insert(stringf("$_DFF_%c_", c1
));
373 for (auto c1
: list_np
)
374 for (auto c2
: list_np
)
375 fftypes
.insert(stringf("$_DFFE_%c%c_", c1
, c2
));
377 for (auto c1
: list_np
)
378 for (auto c2
: list_np
)
379 for (auto c3
: list_01
)
380 fftypes
.insert(stringf("$_DFF_%c%c%c_", c1
, c2
, c3
));
382 for (auto c1
: list_np
)
383 for (auto c2
: list_np
)
384 for (auto c3
: list_np
)
385 fftypes
.insert(stringf("$_DFFSR_%c%c%c_", c1
, c2
, c3
));
387 for (auto cell
: module
->cells())
389 if (!fftypes
.count(cell
->type
))
392 for (auto bit
: sigmap(cell
->getPort("\\Q")))
396 auto process_initwires
= [&]()
398 dict
<Wire
*, int> wire_weights
;
400 for (auto wire
: initwires
)
404 for (auto bit
: sigmap(wire
))
405 weight
+= ffbits
.count(bit
) ? +1 : -1;
407 wire_weights
[wire
] = weight
;
410 initwires
.sort([&](Wire
*a
, Wire
*b
) { return wire_weights
.at(a
) > wire_weights
.at(b
); });
412 for (auto wire
: initwires
)
414 Const
&initval
= wire
->attributes
["\\init"];
415 initval
.bits
.resize(GetSize(wire
), State::Sx
);
417 for (int i
= 0; i
< GetSize(wire
); i
++) {
418 SigBit bit
= sigmap(SigBit(wire
, i
));
419 if (initval
[i
] == State::Sx
&& ffbits
.count(bit
)) {
420 initval
[i
] = worker
.next_bit();
425 if (initval
.is_fully_undef())
426 wire
->attributes
.erase("\\init");
432 for (int wire_types
= 0; wire_types
< 2; wire_types
++)
434 // prioritize wires that already have an init attribute
437 for (auto wire
: module
->wires())
439 if (wire
->name
[0] == (wire_types
? '\\' : '$'))
442 if (!wire
->attributes
.count("\\init"))
445 Const
&initval
= wire
->attributes
["\\init"];
446 initval
.bits
.resize(GetSize(wire
), State::Sx
);
448 if (initval
.is_fully_undef()) {
449 wire
->attributes
.erase("\\init");
453 for (int i
= 0; i
< GetSize(wire
); i
++)
454 if (initval
[i
] != State::Sx
)
455 ffbits
.erase(sigmap(SigBit(wire
, i
)));
457 initwires
.insert(wire
);
463 // next consider wires that completely contain bits to be initialized
466 for (auto wire
: module
->wires())
468 if (wire
->name
[0] == (wire_types
? '\\' : '$'))
471 for (auto bit
: sigmap(wire
))
472 if (!ffbits
.count(bit
))
475 initwires
.insert(wire
);
484 // finally use whatever wire we can find.
487 for (auto wire
: module
->wires())
489 if (wire
->name
[0] == (wire_types
? '\\' : '$'))
492 for (auto bit
: sigmap(wire
))
493 if (ffbits
.count(bit
))
494 initwires
.insert(wire
);
501 log_assert(ffbits
.empty());
504 module
->rewrite_sigspecs(worker
);
506 if (worker
.next_bit_mode
== MODE_ANYSEQ
|| worker
.next_bit_mode
== MODE_ANYCONST
)
508 vector
<SigSpec
*> siglist
;
509 siglist
.swap(worker
.siglist
);
511 for (auto sigptr
: siglist
)
513 SigSpec
&sig
= *sigptr
;
516 while (cursor
< GetSize(sig
))
519 while (cursor
+width
< GetSize(sig
) && sig
[cursor
+width
] == State::Sx
)
523 if (worker
.next_bit_mode
== MODE_ANYSEQ
)
524 sig
.replace(cursor
, module
->Anyseq(NEW_ID
, width
));
526 sig
.replace(cursor
, module
->Anyconst(NEW_ID
, width
));
538 PRIVATE_NAMESPACE_END