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/yosys.h"
21 #include "kernel/sigtools.h"
24 PRIVATE_NAMESPACE_BEGIN
26 struct ZinitPass
: public Pass
{
27 ZinitPass() : Pass("zinit", "add inverters so all FF are zero-initialized") { }
28 void help() YS_OVERRIDE
30 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
32 log(" zinit [options] [selection]\n");
34 log("Add inverters as needed to make all FFs zero-initialized.\n");
37 log(" also add zero initialization to uninitialized FFs\n");
40 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
42 bool all_mode
= false;
44 log_header(design
, "Executing ZINIT pass (make all FFs zero-initialized).\n");
47 for (argidx
= 1; argidx
< args
.size(); argidx
++)
49 if (args
[argidx
] == "-all") {
55 extra_args(args
, argidx
, design
);
57 for (auto module
: design
->selected_modules())
59 SigMap
sigmap(module
);
60 dict
<SigBit
, State
> initbits
;
61 pool
<SigBit
> donebits
;
63 for (auto wire
: module
->selected_wires())
65 if (wire
->attributes
.count("\\init") == 0)
68 SigSpec wirebits
= sigmap(wire
);
69 Const initval
= wire
->attributes
.at("\\init");
70 wire
->attributes
.erase("\\init");
72 for (int i
= 0; i
< GetSize(wirebits
) && i
< GetSize(initval
); i
++)
74 SigBit bit
= wirebits
[i
];
75 State val
= initval
[i
];
77 if (val
!= State::S0
&& val
!= State::S1
&& bit
.wire
!= nullptr)
80 if (initbits
.count(bit
)) {
81 if (initbits
.at(bit
) != val
)
82 log_error("Conflicting init values for signal %s (%s = %s != %s).\n",
83 log_signal(bit
), log_signal(SigBit(wire
, i
)),
84 log_signal(val
), log_signal(initbits
.at(bit
)));
92 pool
<IdString
> dff_types
= {
93 "$ff", "$dff", "$dffe", "$dffsr", "$adff",
94 "$_FF_", "$_DFFE_NN_", "$_DFFE_NP_", "$_DFFE_PN_", "$_DFFE_PP_",
95 "$_DFFSR_NNN_", "$_DFFSR_NNP_", "$_DFFSR_NPN_", "$_DFFSR_NPP_",
96 "$_DFFSR_PNN_", "$_DFFSR_PNP_", "$_DFFSR_PPN_", "$_DFFSR_PPP_",
97 "$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_",
98 "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1_", "$_DFF_PP0_", "$_DFF_PP1_"
101 for (auto cell
: module
->selected_cells())
103 if (!dff_types
.count(cell
->type
))
106 SigSpec sig_d
= sigmap(cell
->getPort("\\D"));
107 SigSpec sig_q
= sigmap(cell
->getPort("\\Q"));
109 if (GetSize(sig_d
) < 1 || GetSize(sig_q
) < 1)
114 for (int i
= 0; i
< GetSize(sig_q
); i
++) {
115 if (initbits
.count(sig_q
[i
])) {
116 initval
.bits
.push_back(initbits
.at(sig_q
[i
]));
117 donebits
.insert(sig_q
[i
]);
119 initval
.bits
.push_back(all_mode
? State::S0
: State::Sx
);
122 Wire
*initwire
= module
->addWire(NEW_ID
, GetSize(initval
));
123 initwire
->attributes
["\\init"] = initval
;
125 for (int i
= 0; i
< GetSize(initwire
); i
++)
126 if (initval
.bits
.at(i
) == State::S1
)
128 sig_d
[i
] = module
->NotGate(NEW_ID
, sig_d
[i
]);
129 module
->addNotGate(NEW_ID
, SigSpec(initwire
, i
), sig_q
[i
]);
130 initwire
->attributes
["\\init"].bits
.at(i
) = State::S0
;
134 module
->connect(sig_q
[i
], SigSpec(initwire
, i
));
137 log("FF init value for cell %s (%s): %s = %s\n", log_id(cell
), log_id(cell
->type
),
138 log_signal(sig_q
), log_signal(initval
));
140 cell
->setPort("\\D", sig_d
);
141 cell
->setPort("\\Q", initwire
);
144 for (auto &it
: initbits
)
145 if (donebits
.count(it
.first
) == 0)
146 log_error("Failed to handle init bit %s = %s.\n", log_signal(it
.first
), log_signal(it
.second
));
151 PRIVATE_NAMESPACE_END