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.
29 std::set
<std::string
> cell_types
;
30 std::vector
<const RTLIL::Design
*> designs
;
32 void setup_internals()
34 cell_types
.insert("$not");
35 cell_types
.insert("$pos");
36 cell_types
.insert("$neg");
37 cell_types
.insert("$and");
38 cell_types
.insert("$or");
39 cell_types
.insert("$xor");
40 cell_types
.insert("$xnor");
41 cell_types
.insert("$reduce_and");
42 cell_types
.insert("$reduce_or");
43 cell_types
.insert("$reduce_xor");
44 cell_types
.insert("$reduce_xnor");
45 cell_types
.insert("$reduce_bool");
46 cell_types
.insert("$shl");
47 cell_types
.insert("$shr");
48 cell_types
.insert("$sshl");
49 cell_types
.insert("$sshr");
50 cell_types
.insert("$lt");
51 cell_types
.insert("$le");
52 cell_types
.insert("$eq");
53 cell_types
.insert("$ne");
54 cell_types
.insert("$ge");
55 cell_types
.insert("$gt");
56 cell_types
.insert("$add");
57 cell_types
.insert("$sub");
58 cell_types
.insert("$mul");
59 cell_types
.insert("$div");
60 cell_types
.insert("$mod");
61 cell_types
.insert("$pow");
62 cell_types
.insert("$logic_not");
63 cell_types
.insert("$logic_and");
64 cell_types
.insert("$logic_or");
65 cell_types
.insert("$mux");
66 cell_types
.insert("$pmux");
67 cell_types
.insert("$safe_pmux");
70 void setup_internals_mem()
72 cell_types
.insert("$dff");
73 cell_types
.insert("$adff");
74 cell_types
.insert("$memrd");
75 cell_types
.insert("$memwr");
76 cell_types
.insert("$mem");
77 cell_types
.insert("$fsm");
82 cell_types
.insert("$_INV_");
83 cell_types
.insert("$_AND_");
84 cell_types
.insert("$_OR_");
85 cell_types
.insert("$_XOR_");
86 cell_types
.insert("$_MUX_");
89 void setup_stdcells_mem()
91 cell_types
.insert("$_DFF_N_");
92 cell_types
.insert("$_DFF_P_");
93 cell_types
.insert("$_DFF_NN0_");
94 cell_types
.insert("$_DFF_NN1_");
95 cell_types
.insert("$_DFF_NP0_");
96 cell_types
.insert("$_DFF_NP1_");
97 cell_types
.insert("$_DFF_PN0_");
98 cell_types
.insert("$_DFF_PN1_");
99 cell_types
.insert("$_DFF_PP0_");
100 cell_types
.insert("$_DFF_PP1_");
103 void setup_design(const RTLIL::Design
*design
)
105 designs
.push_back(design
);
114 bool cell_known(std::string type
)
116 if (cell_types
.count(type
) > 0)
118 for (auto design
: designs
)
119 if (design
->modules
.count(type
) > 0)
124 bool cell_output(std::string type
, std::string port
)
126 if (cell_types
.count(type
) == 0) {
127 for (auto design
: designs
)
128 if (design
->modules
.count(type
) > 0) {
129 if (design
->modules
.at(type
)->wires
.count(port
))
130 return design
->modules
.at(type
)->wires
.at(port
)->port_output
;
136 if (port
== "\\Y" || port
== "\\Q" || port
== "\\RD_DATA")
138 if (type
== "$memrd" && port
== "\\DATA")
140 if (type
== "$fsm" && port
== "\\CTRL_OUT")
145 bool cell_input(std::string type
, std::string port
)
147 if (cell_types
.count(type
) == 0) {
148 for (auto design
: designs
)
149 if (design
->modules
.count(type
) > 0) {
150 if (design
->modules
.at(type
)->wires
.count(port
))
151 return design
->modules
.at(type
)->wires
.at(port
)->port_input
;
157 if (cell_types
.count(type
) > 0)
158 return !cell_output(type
, port
);
163 static RTLIL::Const
eval(std::string type
, const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
165 #define HANDLE_CELL_TYPE(_t) if (type == "$" #_t) return const_ ## _t(arg1, arg2, signed1, signed2, result_len);
166 HANDLE_CELL_TYPE(not)
167 HANDLE_CELL_TYPE(and)
169 HANDLE_CELL_TYPE(xor)
170 HANDLE_CELL_TYPE(xnor
)
171 HANDLE_CELL_TYPE(reduce_and
)
172 HANDLE_CELL_TYPE(reduce_or
)
173 HANDLE_CELL_TYPE(reduce_xor
)
174 HANDLE_CELL_TYPE(reduce_xnor
)
175 HANDLE_CELL_TYPE(reduce_bool
)
176 HANDLE_CELL_TYPE(logic_not
)
177 HANDLE_CELL_TYPE(logic_and
)
178 HANDLE_CELL_TYPE(logic_or
)
179 HANDLE_CELL_TYPE(shl
)
180 HANDLE_CELL_TYPE(shr
)
181 HANDLE_CELL_TYPE(sshl
)
182 HANDLE_CELL_TYPE(sshr
)
189 HANDLE_CELL_TYPE(add
)
190 HANDLE_CELL_TYPE(sub
)
191 HANDLE_CELL_TYPE(mul
)
192 HANDLE_CELL_TYPE(div
)
193 HANDLE_CELL_TYPE(mod
)
194 HANDLE_CELL_TYPE(pow
)
195 HANDLE_CELL_TYPE(pos
)
196 HANDLE_CELL_TYPE(neg
)
197 #undef HANDLE_CELL_TYPE
199 if (type
== "$_INV_")
200 return const_not(arg1
, arg2
, false, false, 1);
201 if (type
== "$_AND_")
202 return const_and(arg1
, arg2
, false, false, 1);
204 return const_or(arg1
, arg2
, false, false, 1);
205 if (type
== "$_XOR_")
206 return const_xor(arg1
, arg2
, false, false, 1);
208 assert(!"Called CellType.eval() with unsupported cell type!");
212 static RTLIL::Const
eval(RTLIL::Cell
*cell
, const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
)
214 bool signed_a
= cell
->parameters
.count("\\A_SIGNED") > 0 && cell
->parameters
["\\A_SIGNED"].as_bool();
215 bool signed_b
= cell
->parameters
.count("\\B_SIGNED") > 0 && cell
->parameters
["\\B_SIGNED"].as_bool();
216 int result_len
= cell
->parameters
.count("\\Y_WIDTH") > 0 ? cell
->parameters
["\\Y_WIDTH"].as_int() : -1;
217 return eval(cell
->type
, arg1
, arg2
, signed_a
, signed_b
, result_len
);
220 static RTLIL::Const
eval(RTLIL::Cell
*cell
, const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, const RTLIL::Const
&sel
)
222 if (cell
->type
== "$mux" || cell
->type
== "$pmux" || cell
->type
== "$safe_pmux" || cell
->type
== "$_MUX_") {
223 RTLIL::Const ret
= arg1
;
224 for (size_t i
= 0; i
< sel
.bits
.size(); i
++)
225 if (sel
.bits
[i
] == RTLIL::State::S1
) {
226 std::vector
<RTLIL::State
> bits(arg2
.bits
.begin() + i
*arg1
.bits
.size(), arg2
.bits
.begin() + (i
+1)*arg1
.bits
.size());
227 ret
= RTLIL::Const(bits
);
232 assert(sel
.bits
.size() == 0);
233 bool signed_a
= cell
->parameters
.count("\\A_SIGNED") > 0 && cell
->parameters
["\\A_SIGNED"].as_bool();
234 bool signed_b
= cell
->parameters
.count("\\B_SIGNED") > 0 && cell
->parameters
["\\B_SIGNED"].as_bool();
235 int result_len
= cell
->parameters
.count("\\Y_WIDTH") > 0 ? cell
->parameters
["\\Y_WIDTH"].as_int() : -1;
236 return eval(cell
->type
, arg1
, arg2
, signed_a
, signed_b
, result_len
);