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 void dffsr_worker(SigMap
&sigmap
, Module
*module
, Cell
*cell
)
28 if (cell
->type
== ID($dffsr
))
30 int width
= cell
->getParam("\\WIDTH").as_int();
31 bool setpol
= cell
->getParam("\\SET_POLARITY").as_bool();
32 bool clrpol
= cell
->getParam("\\CLR_POLARITY").as_bool();
34 SigBit setunused
= setpol
? State::S0
: State::S1
;
35 SigBit clrunused
= clrpol
? State::S0
: State::S1
;
37 SigSpec setsig
= sigmap(cell
->getPort("\\SET"));
38 SigSpec clrsig
= sigmap(cell
->getPort("\\CLR"));
41 SigSpec setctrl
, clrctrl
;
43 for (int i
= 0; i
< width
; i
++)
45 SigBit setbit
= setsig
[i
], clrbit
= clrsig
[i
];
47 if (setbit
== setunused
) {
48 clrctrl
.append(clrbit
);
49 reset_val
.bits
.push_back(State::S0
);
53 if (clrbit
== clrunused
) {
54 setctrl
.append(setbit
);
55 reset_val
.bits
.push_back(State::S1
);
62 setctrl
.sort_and_unify();
63 clrctrl
.sort_and_unify();
65 if (GetSize(setctrl
) > 1 || GetSize(clrctrl
) > 1)
68 if (GetSize(setctrl
) == 0 && GetSize(clrctrl
) == 0)
71 if (GetSize(setctrl
) == 1 && GetSize(clrctrl
) == 1) {
74 if (setctrl
!= clrctrl
)
78 log("Converting %s cell %s.%s to $adff.\n", log_id(cell
->type
), log_id(module
), log_id(cell
));
80 if (GetSize(setctrl
) == 1) {
81 cell
->setPort("\\ARST", setctrl
);
82 cell
->setParam("\\ARST_POLARITY", setpol
);
84 cell
->setPort("\\ARST", clrctrl
);
85 cell
->setParam("\\ARST_POLARITY", clrpol
);
88 cell
->type
= ID($adff
);
89 cell
->unsetPort("\\SET");
90 cell
->unsetPort("\\CLR");
91 cell
->setParam("\\ARST_VALUE", reset_val
);
92 cell
->unsetParam("\\SET_POLARITY");
93 cell
->unsetParam("\\CLR_POLARITY");
98 if (cell
->type
.in(ID($_DFFSR_NNN_
), ID($_DFFSR_NNP_
), ID($_DFFSR_NPN_
), ID($_DFFSR_NPP_
),
99 ID($_DFFSR_PNN_
), ID($_DFFSR_PNP_
), ID($_DFFSR_PPN_
), ID($_DFFSR_PPP_
)))
101 char clkpol
= cell
->type
.c_str()[8];
102 char setpol
= cell
->type
.c_str()[9];
103 char clrpol
= cell
->type
.c_str()[10];
105 SigBit setbit
= sigmap(cell
->getPort("\\S"));
106 SigBit clrbit
= sigmap(cell
->getPort("\\R"));
108 SigBit setunused
= setpol
== 'P' ? State::S0
: State::S1
;
109 SigBit clrunused
= clrpol
== 'P' ? State::S0
: State::S1
;
111 IdString oldtype
= cell
->type
;
113 if (setbit
== setunused
) {
114 cell
->type
= stringf("$_DFF_%c%c0_", clkpol
, clrpol
);
115 cell
->unsetPort("\\S");
119 if (clrbit
== clrunused
) {
120 cell
->type
= stringf("$_DFF_%c%c1_", clkpol
, setpol
);
121 cell
->setPort("\\R", cell
->getPort("\\S"));
122 cell
->unsetPort("\\S");
129 log("Converting %s cell %s.%s to %s.\n", log_id(oldtype
), log_id(module
), log_id(cell
), log_id(cell
->type
));
134 void adff_worker(SigMap
&sigmap
, Module
*module
, Cell
*cell
)
136 if (cell
->type
== ID($adff
))
138 bool rstpol
= cell
->getParam("\\ARST_POLARITY").as_bool();
139 SigBit rstunused
= rstpol
? State::S0
: State::S1
;
140 SigSpec rstsig
= sigmap(cell
->getPort("\\ARST"));
142 if (rstsig
!= rstunused
)
145 log("Converting %s cell %s.%s to $dff.\n", log_id(cell
->type
), log_id(module
), log_id(cell
));
147 cell
->type
= ID($dff
);
148 cell
->unsetPort("\\ARST");
149 cell
->unsetParam("\\ARST_VALUE");
150 cell
->unsetParam("\\ARST_POLARITY");
155 if (cell
->type
.in(ID($_DFF_NN0_
), ID($_DFF_NN1_
), ID($_DFF_NP0_
), ID($_DFF_NP1_
),
156 ID($_DFF_PN0_
), ID($_DFF_PN1_
), ID($_DFF_PP0_
), ID($_DFF_PP1_
)))
158 char clkpol
= cell
->type
.c_str()[6];
159 char rstpol
= cell
->type
.c_str()[7];
161 SigBit rstbit
= sigmap(cell
->getPort("\\R"));
162 SigBit rstunused
= rstpol
== 'P' ? State::S0
: State::S1
;
164 if (rstbit
!= rstunused
)
167 IdString newtype
= stringf("$_DFF_%c_", clkpol
);
168 log("Converting %s cell %s.%s to %s.\n", log_id(cell
->type
), log_id(module
), log_id(cell
), log_id(newtype
));
170 cell
->type
= newtype
;
171 cell
->unsetPort("\\R");
177 struct Dffsr2dffPass
: public Pass
{
178 Dffsr2dffPass() : Pass("dffsr2dff", "convert DFFSR cells to simpler FF cell types") { }
179 void help() YS_OVERRIDE
181 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
183 log(" dffsr2dff [options] [selection]\n");
185 log("This pass converts DFFSR cells ($dffsr, $_DFFSR_???_) and ADFF cells ($adff,\n");
186 log("$_DFF_???_) to simpler FF cell types when any of the set/reset inputs is unused.\n");
189 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
191 log_header(design
, "Executing DFFSR2DFF pass (mapping DFFSR cells to simpler FFs).\n");
194 for (argidx
= 1; argidx
< args
.size(); argidx
++)
196 // if (args[argidx] == "-v") {
201 extra_args(args
, argidx
, design
);
203 for (auto module
: design
->selected_modules()) {
204 SigMap
sigmap(module
);
205 for (auto cell
: module
->selected_cells()) {
206 dffsr_worker(sigmap
, module
, cell
);
207 adff_worker(sigmap
, module
, cell
);
213 PRIVATE_NAMESPACE_END