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.
27 #include <kernel/rtlil.h>
28 #include <kernel/log.h>
32 std::set
<std::string
> cell_types
;
33 std::vector
<const RTLIL::Design
*> designs
;
39 CellTypes(const RTLIL::Design
*design
)
44 void setup(const RTLIL::Design
*design
= NULL
)
49 setup_internals_mem();
54 void setup_design(const RTLIL::Design
*design
)
56 designs
.push_back(design
);
59 void setup_internals()
61 cell_types
.insert("$not");
62 cell_types
.insert("$pos");
63 cell_types
.insert("$bu0");
64 cell_types
.insert("$neg");
65 cell_types
.insert("$and");
66 cell_types
.insert("$or");
67 cell_types
.insert("$xor");
68 cell_types
.insert("$xnor");
69 cell_types
.insert("$reduce_and");
70 cell_types
.insert("$reduce_or");
71 cell_types
.insert("$reduce_xor");
72 cell_types
.insert("$reduce_xnor");
73 cell_types
.insert("$reduce_bool");
74 cell_types
.insert("$shl");
75 cell_types
.insert("$shr");
76 cell_types
.insert("$sshl");
77 cell_types
.insert("$sshr");
78 cell_types
.insert("$lt");
79 cell_types
.insert("$le");
80 cell_types
.insert("$eq");
81 cell_types
.insert("$ne");
82 cell_types
.insert("$eqx");
83 cell_types
.insert("$nex");
84 cell_types
.insert("$ge");
85 cell_types
.insert("$gt");
86 cell_types
.insert("$add");
87 cell_types
.insert("$sub");
88 cell_types
.insert("$mul");
89 cell_types
.insert("$div");
90 cell_types
.insert("$mod");
91 cell_types
.insert("$pow");
92 cell_types
.insert("$logic_not");
93 cell_types
.insert("$logic_and");
94 cell_types
.insert("$logic_or");
95 cell_types
.insert("$mux");
96 cell_types
.insert("$pmux");
97 cell_types
.insert("$safe_pmux");
98 cell_types
.insert("$lut");
99 cell_types
.insert("$assert");
102 void setup_internals_mem()
104 cell_types
.insert("$sr");
105 cell_types
.insert("$dff");
106 cell_types
.insert("$dffsr");
107 cell_types
.insert("$adff");
108 cell_types
.insert("$dlatch");
109 cell_types
.insert("$memrd");
110 cell_types
.insert("$memwr");
111 cell_types
.insert("$mem");
112 cell_types
.insert("$fsm");
115 void setup_stdcells()
117 cell_types
.insert("$_INV_");
118 cell_types
.insert("$_AND_");
119 cell_types
.insert("$_OR_");
120 cell_types
.insert("$_XOR_");
121 cell_types
.insert("$_MUX_");
124 void setup_stdcells_mem()
126 cell_types
.insert("$_SR_NN_");
127 cell_types
.insert("$_SR_NP_");
128 cell_types
.insert("$_SR_PN_");
129 cell_types
.insert("$_SR_PP_");
130 cell_types
.insert("$_DFF_N_");
131 cell_types
.insert("$_DFF_P_");
132 cell_types
.insert("$_DFF_NN0_");
133 cell_types
.insert("$_DFF_NN1_");
134 cell_types
.insert("$_DFF_NP0_");
135 cell_types
.insert("$_DFF_NP1_");
136 cell_types
.insert("$_DFF_PN0_");
137 cell_types
.insert("$_DFF_PN1_");
138 cell_types
.insert("$_DFF_PP0_");
139 cell_types
.insert("$_DFF_PP1_");
140 cell_types
.insert("$_DFFSR_NNN_");
141 cell_types
.insert("$_DFFSR_NNP_");
142 cell_types
.insert("$_DFFSR_NPN_");
143 cell_types
.insert("$_DFFSR_NPP_");
144 cell_types
.insert("$_DFFSR_PNN_");
145 cell_types
.insert("$_DFFSR_PNP_");
146 cell_types
.insert("$_DFFSR_PPN_");
147 cell_types
.insert("$_DFFSR_PPP_");
148 cell_types
.insert("$_DLATCH_N_");
149 cell_types
.insert("$_DLATCH_P_");
158 bool cell_known(std::string type
)
160 if (cell_types
.count(type
) > 0)
162 for (auto design
: designs
)
163 if (design
->modules
.count(type
) > 0)
168 bool cell_output(std::string type
, std::string port
)
170 if (cell_types
.count(type
) == 0) {
171 for (auto design
: designs
)
172 if (design
->modules
.count(type
) > 0) {
173 if (design
->modules
.at(type
)->wires
.count(port
))
174 return design
->modules
.at(type
)->wires
.at(port
)->port_output
;
180 if (port
== "\\Y" || port
== "\\Q" || port
== "\\RD_DATA")
182 if (type
== "$memrd" && port
== "\\DATA")
184 if (type
== "$fsm" && port
== "\\CTRL_OUT")
186 if (type
== "$lut" && port
== "\\O")
191 bool cell_input(std::string type
, std::string port
)
193 if (cell_types
.count(type
) == 0) {
194 for (auto design
: designs
)
195 if (design
->modules
.count(type
) > 0) {
196 if (design
->modules
.at(type
)->wires
.count(port
))
197 return design
->modules
.at(type
)->wires
.at(port
)->port_input
;
203 if (cell_types
.count(type
) > 0)
204 return !cell_output(type
, port
);
209 static RTLIL::Const
eval(std::string type
, const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
211 if (type
== "$sshr" && !signed1
)
213 if (type
== "$sshl" && !signed1
)
216 if (type
!= "$sshr" && type
!= "$sshl" && type
!= "$shr" && type
!= "$shl" &&
217 type
!= "$pos" && type
!= "$neg" && type
!= "$not") {
218 if (!signed1
|| !signed2
)
219 signed1
= false, signed2
= false;
222 #define HANDLE_CELL_TYPE(_t) if (type == "$" #_t) return const_ ## _t(arg1, arg2, signed1, signed2, result_len);
223 HANDLE_CELL_TYPE(not)
224 HANDLE_CELL_TYPE(and)
226 HANDLE_CELL_TYPE(xor)
227 HANDLE_CELL_TYPE(xnor
)
228 HANDLE_CELL_TYPE(reduce_and
)
229 HANDLE_CELL_TYPE(reduce_or
)
230 HANDLE_CELL_TYPE(reduce_xor
)
231 HANDLE_CELL_TYPE(reduce_xnor
)
232 HANDLE_CELL_TYPE(reduce_bool
)
233 HANDLE_CELL_TYPE(logic_not
)
234 HANDLE_CELL_TYPE(logic_and
)
235 HANDLE_CELL_TYPE(logic_or
)
236 HANDLE_CELL_TYPE(shl
)
237 HANDLE_CELL_TYPE(shr
)
238 HANDLE_CELL_TYPE(sshl
)
239 HANDLE_CELL_TYPE(sshr
)
244 HANDLE_CELL_TYPE(eqx
)
245 HANDLE_CELL_TYPE(nex
)
248 HANDLE_CELL_TYPE(add
)
249 HANDLE_CELL_TYPE(sub
)
250 HANDLE_CELL_TYPE(mul
)
251 HANDLE_CELL_TYPE(div
)
252 HANDLE_CELL_TYPE(mod
)
253 HANDLE_CELL_TYPE(pow
)
254 HANDLE_CELL_TYPE(pos
)
255 HANDLE_CELL_TYPE(bu0
)
256 HANDLE_CELL_TYPE(neg
)
257 #undef HANDLE_CELL_TYPE
259 if (type
== "$_INV_")
260 return const_not(arg1
, arg2
, false, false, 1);
261 if (type
== "$_AND_")
262 return const_and(arg1
, arg2
, false, false, 1);
264 return const_or(arg1
, arg2
, false, false, 1);
265 if (type
== "$_XOR_")
266 return const_xor(arg1
, arg2
, false, false, 1);
271 static RTLIL::Const
eval(RTLIL::Cell
*cell
, const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
)
273 bool signed_a
= cell
->parameters
.count("\\A_SIGNED") > 0 && cell
->parameters
["\\A_SIGNED"].as_bool();
274 bool signed_b
= cell
->parameters
.count("\\B_SIGNED") > 0 && cell
->parameters
["\\B_SIGNED"].as_bool();
275 int result_len
= cell
->parameters
.count("\\Y_WIDTH") > 0 ? cell
->parameters
["\\Y_WIDTH"].as_int() : -1;
276 return eval(cell
->type
, arg1
, arg2
, signed_a
, signed_b
, result_len
);
279 static RTLIL::Const
eval(RTLIL::Cell
*cell
, const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, const RTLIL::Const
&sel
)
281 if (cell
->type
== "$mux" || cell
->type
== "$pmux" || cell
->type
== "$safe_pmux" || cell
->type
== "$_MUX_") {
282 RTLIL::Const ret
= arg1
;
283 for (size_t i
= 0; i
< sel
.bits
.size(); i
++)
284 if (sel
.bits
[i
] == RTLIL::State::S1
) {
285 std::vector
<RTLIL::State
> bits(arg2
.bits
.begin() + i
*arg1
.bits
.size(), arg2
.bits
.begin() + (i
+1)*arg1
.bits
.size());
286 ret
= RTLIL::Const(bits
);
291 assert(sel
.bits
.size() == 0);
292 bool signed_a
= cell
->parameters
.count("\\A_SIGNED") > 0 && cell
->parameters
["\\A_SIGNED"].as_bool();
293 bool signed_b
= cell
->parameters
.count("\\B_SIGNED") > 0 && cell
->parameters
["\\B_SIGNED"].as_bool();
294 int result_len
= cell
->parameters
.count("\\Y_WIDTH") > 0 ? cell
->parameters
["\\Y_WIDTH"].as_int() : -1;
295 return eval(cell
->type
, arg1
, arg2
, signed_a
, signed_b
, result_len
);