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 "simplemap.h"
21 #include "kernel/sigtools.h"
29 void simplemap_not(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
31 RTLIL::SigSpec sig_a
= cell
->getPort(ID(A
));
32 RTLIL::SigSpec sig_y
= cell
->getPort(ID(Y
));
34 sig_a
.extend_u0(GetSize(sig_y
), cell
->parameters
.at(ID(A_SIGNED
)).as_bool());
36 for (int i
= 0; i
< GetSize(sig_y
); i
++) {
37 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, ID($_NOT_
));
38 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
39 gate
->setPort(ID(A
), sig_a
[i
]);
40 gate
->setPort(ID(Y
), sig_y
[i
]);
44 void simplemap_pos(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
46 RTLIL::SigSpec sig_a
= cell
->getPort(ID(A
));
47 RTLIL::SigSpec sig_y
= cell
->getPort(ID(Y
));
49 sig_a
.extend_u0(GetSize(sig_y
), cell
->parameters
.at(ID(A_SIGNED
)).as_bool());
51 module
->connect(RTLIL::SigSig(sig_y
, sig_a
));
54 void simplemap_bitop(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
56 RTLIL::SigSpec sig_a
= cell
->getPort(ID(A
));
57 RTLIL::SigSpec sig_b
= cell
->getPort(ID(B
));
58 RTLIL::SigSpec sig_y
= cell
->getPort(ID(Y
));
60 sig_a
.extend_u0(GetSize(sig_y
), cell
->parameters
.at(ID(A_SIGNED
)).as_bool());
61 sig_b
.extend_u0(GetSize(sig_y
), cell
->parameters
.at(ID(B_SIGNED
)).as_bool());
63 if (cell
->type
== ID($xnor
))
65 RTLIL::SigSpec sig_t
= module
->addWire(NEW_ID
, GetSize(sig_y
));
67 for (int i
= 0; i
< GetSize(sig_y
); i
++) {
68 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, ID($_NOT_
));
69 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
70 gate
->setPort(ID(A
), sig_t
[i
]);
71 gate
->setPort(ID(Y
), sig_y
[i
]);
78 if (cell
->type
== ID($
and)) gate_type
= ID($_AND_
);
79 if (cell
->type
== ID($
or)) gate_type
= ID($_OR_
);
80 if (cell
->type
== ID($
xor)) gate_type
= ID($_XOR_
);
81 if (cell
->type
== ID($xnor
)) gate_type
= ID($_XOR_
);
82 log_assert(!gate_type
.empty());
84 for (int i
= 0; i
< GetSize(sig_y
); i
++) {
85 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, gate_type
);
86 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
87 gate
->setPort(ID(A
), sig_a
[i
]);
88 gate
->setPort(ID(B
), sig_b
[i
]);
89 gate
->setPort(ID(Y
), sig_y
[i
]);
93 void simplemap_reduce(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
95 RTLIL::SigSpec sig_a
= cell
->getPort(ID(A
));
96 RTLIL::SigSpec sig_y
= cell
->getPort(ID(Y
));
98 if (sig_y
.size() == 0)
101 if (sig_a
.size() == 0) {
102 if (cell
->type
== ID($reduce_and
)) module
->connect(RTLIL::SigSig(sig_y
, RTLIL::SigSpec(1, sig_y
.size())));
103 if (cell
->type
== ID($reduce_or
)) module
->connect(RTLIL::SigSig(sig_y
, RTLIL::SigSpec(0, sig_y
.size())));
104 if (cell
->type
== ID($reduce_xor
)) module
->connect(RTLIL::SigSig(sig_y
, RTLIL::SigSpec(0, sig_y
.size())));
105 if (cell
->type
== ID($reduce_xnor
)) module
->connect(RTLIL::SigSig(sig_y
, RTLIL::SigSpec(1, sig_y
.size())));
106 if (cell
->type
== ID($reduce_bool
)) module
->connect(RTLIL::SigSig(sig_y
, RTLIL::SigSpec(0, sig_y
.size())));
110 if (sig_y
.size() > 1) {
111 module
->connect(RTLIL::SigSig(sig_y
.extract(1, sig_y
.size()-1), RTLIL::SigSpec(0, sig_y
.size()-1)));
112 sig_y
= sig_y
.extract(0, 1);
116 if (cell
->type
== ID($reduce_and
)) gate_type
= ID($_AND_
);
117 if (cell
->type
== ID($reduce_or
)) gate_type
= ID($_OR_
);
118 if (cell
->type
== ID($reduce_xor
)) gate_type
= ID($_XOR_
);
119 if (cell
->type
== ID($reduce_xnor
)) gate_type
= ID($_XOR_
);
120 if (cell
->type
== ID($reduce_bool
)) gate_type
= ID($_OR_
);
121 log_assert(!gate_type
.empty());
123 RTLIL::Cell
*last_output_cell
= NULL
;
125 while (sig_a
.size() > 1)
127 RTLIL::SigSpec sig_t
= module
->addWire(NEW_ID
, sig_a
.size() / 2);
129 for (int i
= 0; i
< sig_a
.size(); i
+= 2)
131 if (i
+1 == sig_a
.size()) {
132 sig_t
.append(sig_a
[i
]);
136 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, gate_type
);
137 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
138 gate
->setPort(ID(A
), sig_a
[i
]);
139 gate
->setPort(ID(B
), sig_a
[i
+1]);
140 gate
->setPort(ID(Y
), sig_t
[i
/2]);
141 last_output_cell
= gate
;
147 if (cell
->type
== ID($reduce_xnor
)) {
148 RTLIL::SigSpec sig_t
= module
->addWire(NEW_ID
);
149 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, ID($_NOT_
));
150 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
151 gate
->setPort(ID(A
), sig_a
);
152 gate
->setPort(ID(Y
), sig_t
);
153 last_output_cell
= gate
;
157 if (last_output_cell
== NULL
) {
158 module
->connect(RTLIL::SigSig(sig_y
, sig_a
));
160 last_output_cell
->setPort(ID(Y
), sig_y
);
164 static void logic_reduce(RTLIL::Module
*module
, RTLIL::SigSpec
&sig
, RTLIL::Cell
*cell
)
166 while (sig
.size() > 1)
168 RTLIL::SigSpec sig_t
= module
->addWire(NEW_ID
, sig
.size() / 2);
170 for (int i
= 0; i
< sig
.size(); i
+= 2)
172 if (i
+1 == sig
.size()) {
173 sig_t
.append(sig
[i
]);
177 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, ID($_OR_
));
178 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
179 gate
->setPort(ID(A
), sig
[i
]);
180 gate
->setPort(ID(B
), sig
[i
+1]);
181 gate
->setPort(ID(Y
), sig_t
[i
/2]);
191 void simplemap_lognot(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
193 RTLIL::SigSpec sig_a
= cell
->getPort(ID(A
));
194 logic_reduce(module
, sig_a
, cell
);
196 RTLIL::SigSpec sig_y
= cell
->getPort(ID(Y
));
198 if (sig_y
.size() == 0)
201 if (sig_y
.size() > 1) {
202 module
->connect(RTLIL::SigSig(sig_y
.extract(1, sig_y
.size()-1), RTLIL::SigSpec(0, sig_y
.size()-1)));
203 sig_y
= sig_y
.extract(0, 1);
206 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, ID($_NOT_
));
207 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
208 gate
->setPort(ID(A
), sig_a
);
209 gate
->setPort(ID(Y
), sig_y
);
212 void simplemap_logbin(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
214 RTLIL::SigSpec sig_a
= cell
->getPort(ID(A
));
215 logic_reduce(module
, sig_a
, cell
);
217 RTLIL::SigSpec sig_b
= cell
->getPort(ID(B
));
218 logic_reduce(module
, sig_b
, cell
);
220 RTLIL::SigSpec sig_y
= cell
->getPort(ID(Y
));
222 if (sig_y
.size() == 0)
225 if (sig_y
.size() > 1) {
226 module
->connect(RTLIL::SigSig(sig_y
.extract(1, sig_y
.size()-1), RTLIL::SigSpec(0, sig_y
.size()-1)));
227 sig_y
= sig_y
.extract(0, 1);
231 if (cell
->type
== ID($logic_and
)) gate_type
= ID($_AND_
);
232 if (cell
->type
== ID($logic_or
)) gate_type
= ID($_OR_
);
233 log_assert(!gate_type
.empty());
235 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, gate_type
);
236 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
237 gate
->setPort(ID(A
), sig_a
);
238 gate
->setPort(ID(B
), sig_b
);
239 gate
->setPort(ID(Y
), sig_y
);
242 void simplemap_eqne(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
244 RTLIL::SigSpec sig_a
= cell
->getPort(ID(A
));
245 RTLIL::SigSpec sig_b
= cell
->getPort(ID(B
));
246 RTLIL::SigSpec sig_y
= cell
->getPort(ID(Y
));
247 bool is_signed
= cell
->parameters
.at(ID(A_SIGNED
)).as_bool();
248 bool is_ne
= cell
->type
.in(ID($ne
), ID($nex
));
250 RTLIL::SigSpec xor_out
= module
->addWire(NEW_ID
, max(GetSize(sig_a
), GetSize(sig_b
)));
251 RTLIL::Cell
*xor_cell
= module
->addXor(NEW_ID
, sig_a
, sig_b
, xor_out
, is_signed
);
252 xor_cell
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
253 simplemap_bitop(module
, xor_cell
);
254 module
->remove(xor_cell
);
256 RTLIL::SigSpec reduce_out
= is_ne
? sig_y
: module
->addWire(NEW_ID
);
257 RTLIL::Cell
*reduce_cell
= module
->addReduceOr(NEW_ID
, xor_out
, reduce_out
);
258 reduce_cell
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
259 simplemap_reduce(module
, reduce_cell
);
260 module
->remove(reduce_cell
);
263 RTLIL::Cell
*not_cell
= module
->addLogicNot(NEW_ID
, reduce_out
, sig_y
);
264 not_cell
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
265 simplemap_lognot(module
, not_cell
);
266 module
->remove(not_cell
);
270 void simplemap_mux(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
272 RTLIL::SigSpec sig_a
= cell
->getPort(ID(A
));
273 RTLIL::SigSpec sig_b
= cell
->getPort(ID(B
));
274 RTLIL::SigSpec sig_y
= cell
->getPort(ID(Y
));
276 for (int i
= 0; i
< GetSize(sig_y
); i
++) {
277 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, ID($_MUX_
));
278 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
279 gate
->setPort(ID(A
), sig_a
[i
]);
280 gate
->setPort(ID(B
), sig_b
[i
]);
281 gate
->setPort(ID(S
), cell
->getPort(ID(S
)));
282 gate
->setPort(ID(Y
), sig_y
[i
]);
286 void simplemap_tribuf(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
288 RTLIL::SigSpec sig_a
= cell
->getPort(ID(A
));
289 RTLIL::SigSpec sig_e
= cell
->getPort(ID(EN
));
290 RTLIL::SigSpec sig_y
= cell
->getPort(ID(Y
));
292 for (int i
= 0; i
< GetSize(sig_y
); i
++) {
293 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, ID($_TBUF_
));
294 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
295 gate
->setPort(ID(A
), sig_a
[i
]);
296 gate
->setPort(ID(E
), sig_e
);
297 gate
->setPort(ID(Y
), sig_y
[i
]);
301 void simplemap_lut(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
303 SigSpec lut_ctrl
= cell
->getPort(ID(A
));
304 SigSpec lut_data
= cell
->getParam(ID(LUT
));
305 lut_data
.extend_u0(1 << cell
->getParam(ID(WIDTH
)).as_int());
307 for (int idx
= 0; GetSize(lut_data
) > 1; idx
++) {
308 SigSpec sig_s
= lut_ctrl
[idx
];
309 SigSpec new_lut_data
= module
->addWire(NEW_ID
, GetSize(lut_data
)/2);
310 for (int i
= 0; i
< GetSize(lut_data
); i
+= 2) {
311 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, ID($_MUX_
));
312 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
313 gate
->setPort(ID(A
), lut_data
[i
]);
314 gate
->setPort(ID(B
), lut_data
[i
+1]);
315 gate
->setPort(ID(S
), lut_ctrl
[idx
]);
316 gate
->setPort(ID(Y
), new_lut_data
[i
/2]);
318 lut_data
= new_lut_data
;
321 module
->connect(cell
->getPort(ID(Y
)), lut_data
);
324 void simplemap_sop(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
326 SigSpec ctrl
= cell
->getPort(ID(A
));
327 SigSpec table
= cell
->getParam(ID(TABLE
));
329 int width
= cell
->getParam(ID(WIDTH
)).as_int();
330 int depth
= cell
->getParam(ID(DEPTH
)).as_int();
331 table
.extend_u0(2 * width
* depth
);
335 for (int i
= 0; i
< depth
; i
++) {
337 for (int j
= 0; j
< width
; j
++) {
338 if (table
[2*i
*width
+ 2*j
+ 0] == State::S1
) {
340 pat
.append(State::S0
);
342 if (table
[2*i
*width
+ 2*j
+ 1] == State::S1
) {
344 pat
.append(State::S1
);
348 products
.append(GetSize(in
) > 0 ? module
->Eq(NEW_ID
, in
, pat
) : State::S1
);
351 module
->connect(cell
->getPort(ID(Y
)), module
->ReduceOr(NEW_ID
, products
));
354 void simplemap_slice(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
356 int offset
= cell
->parameters
.at(ID(OFFSET
)).as_int();
357 RTLIL::SigSpec sig_a
= cell
->getPort(ID(A
));
358 RTLIL::SigSpec sig_y
= cell
->getPort(ID(Y
));
359 module
->connect(RTLIL::SigSig(sig_y
, sig_a
.extract(offset
, sig_y
.size())));
362 void simplemap_concat(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
364 RTLIL::SigSpec sig_ab
= cell
->getPort(ID(A
));
365 sig_ab
.append(cell
->getPort(ID(B
)));
366 RTLIL::SigSpec sig_y
= cell
->getPort(ID(Y
));
367 module
->connect(RTLIL::SigSig(sig_y
, sig_ab
));
370 void simplemap_sr(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
372 int width
= cell
->parameters
.at(ID(WIDTH
)).as_int();
373 char set_pol
= cell
->parameters
.at(ID(SET_POLARITY
)).as_bool() ? 'P' : 'N';
374 char clr_pol
= cell
->parameters
.at(ID(CLR_POLARITY
)).as_bool() ? 'P' : 'N';
376 RTLIL::SigSpec sig_s
= cell
->getPort(ID(SET
));
377 RTLIL::SigSpec sig_r
= cell
->getPort(ID(CLR
));
378 RTLIL::SigSpec sig_q
= cell
->getPort(ID(Q
));
380 std::string gate_type
= stringf("$_SR_%c%c_", set_pol
, clr_pol
);
382 for (int i
= 0; i
< width
; i
++) {
383 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, gate_type
);
384 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
385 gate
->setPort(ID(S
), sig_s
[i
]);
386 gate
->setPort(ID(R
), sig_r
[i
]);
387 gate
->setPort(ID(Q
), sig_q
[i
]);
391 void simplemap_ff(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
393 int width
= cell
->parameters
.at(ID(WIDTH
)).as_int();
395 RTLIL::SigSpec sig_d
= cell
->getPort(ID(D
));
396 RTLIL::SigSpec sig_q
= cell
->getPort(ID(Q
));
398 IdString gate_type
= ID($_FF_
);
400 for (int i
= 0; i
< width
; i
++) {
401 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, gate_type
);
402 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
403 gate
->setPort(ID(D
), sig_d
[i
]);
404 gate
->setPort(ID(Q
), sig_q
[i
]);
408 void simplemap_dff(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
410 int width
= cell
->parameters
.at(ID(WIDTH
)).as_int();
411 char clk_pol
= cell
->parameters
.at(ID(CLK_POLARITY
)).as_bool() ? 'P' : 'N';
413 RTLIL::SigSpec sig_clk
= cell
->getPort(ID(CLK
));
414 RTLIL::SigSpec sig_d
= cell
->getPort(ID(D
));
415 RTLIL::SigSpec sig_q
= cell
->getPort(ID(Q
));
417 IdString gate_type
= stringf("$_DFF_%c_", clk_pol
);
419 for (int i
= 0; i
< width
; i
++) {
420 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, gate_type
);
421 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
422 gate
->setPort(ID(C
), sig_clk
);
423 gate
->setPort(ID(D
), sig_d
[i
]);
424 gate
->setPort(ID(Q
), sig_q
[i
]);
428 void simplemap_dffe(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
430 int width
= cell
->parameters
.at(ID(WIDTH
)).as_int();
431 char clk_pol
= cell
->parameters
.at(ID(CLK_POLARITY
)).as_bool() ? 'P' : 'N';
432 char en_pol
= cell
->parameters
.at(ID(EN_POLARITY
)).as_bool() ? 'P' : 'N';
434 RTLIL::SigSpec sig_clk
= cell
->getPort(ID(CLK
));
435 RTLIL::SigSpec sig_en
= cell
->getPort(ID(EN
));
436 RTLIL::SigSpec sig_d
= cell
->getPort(ID(D
));
437 RTLIL::SigSpec sig_q
= cell
->getPort(ID(Q
));
439 IdString gate_type
= stringf("$_DFFE_%c%c_", clk_pol
, en_pol
);
441 for (int i
= 0; i
< width
; i
++) {
442 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, gate_type
);
443 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
444 gate
->setPort(ID(C
), sig_clk
);
445 gate
->setPort(ID(E
), sig_en
);
446 gate
->setPort(ID(D
), sig_d
[i
]);
447 gate
->setPort(ID(Q
), sig_q
[i
]);
451 void simplemap_dffsr(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
453 int width
= cell
->parameters
.at(ID(WIDTH
)).as_int();
454 char clk_pol
= cell
->parameters
.at(ID(CLK_POLARITY
)).as_bool() ? 'P' : 'N';
455 char set_pol
= cell
->parameters
.at(ID(SET_POLARITY
)).as_bool() ? 'P' : 'N';
456 char clr_pol
= cell
->parameters
.at(ID(CLR_POLARITY
)).as_bool() ? 'P' : 'N';
458 RTLIL::SigSpec sig_clk
= cell
->getPort(ID(CLK
));
459 RTLIL::SigSpec sig_s
= cell
->getPort(ID(SET
));
460 RTLIL::SigSpec sig_r
= cell
->getPort(ID(CLR
));
461 RTLIL::SigSpec sig_d
= cell
->getPort(ID(D
));
462 RTLIL::SigSpec sig_q
= cell
->getPort(ID(Q
));
464 IdString gate_type
= stringf("$_DFFSR_%c%c%c_", clk_pol
, set_pol
, clr_pol
);
466 for (int i
= 0; i
< width
; i
++) {
467 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, gate_type
);
468 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
469 gate
->setPort(ID(C
), sig_clk
);
470 gate
->setPort(ID(S
), sig_s
[i
]);
471 gate
->setPort(ID(R
), sig_r
[i
]);
472 gate
->setPort(ID(D
), sig_d
[i
]);
473 gate
->setPort(ID(Q
), sig_q
[i
]);
477 void simplemap_adff(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
479 int width
= cell
->parameters
.at(ID(WIDTH
)).as_int();
480 char clk_pol
= cell
->parameters
.at(ID(CLK_POLARITY
)).as_bool() ? 'P' : 'N';
481 char rst_pol
= cell
->parameters
.at(ID(ARST_POLARITY
)).as_bool() ? 'P' : 'N';
483 std::vector
<RTLIL::State
> rst_val
= cell
->parameters
.at(ID(ARST_VALUE
)).bits
;
484 while (int(rst_val
.size()) < width
)
485 rst_val
.push_back(RTLIL::State::S0
);
487 RTLIL::SigSpec sig_clk
= cell
->getPort(ID(CLK
));
488 RTLIL::SigSpec sig_rst
= cell
->getPort(ID(ARST
));
489 RTLIL::SigSpec sig_d
= cell
->getPort(ID(D
));
490 RTLIL::SigSpec sig_q
= cell
->getPort(ID(Q
));
492 IdString gate_type_0
= stringf("$_DFF_%c%c0_", clk_pol
, rst_pol
);
493 IdString gate_type_1
= stringf("$_DFF_%c%c1_", clk_pol
, rst_pol
);
495 for (int i
= 0; i
< width
; i
++) {
496 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, rst_val
.at(i
) == RTLIL::State::S1
? gate_type_1
: gate_type_0
);
497 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
498 gate
->setPort(ID(C
), sig_clk
);
499 gate
->setPort(ID(R
), sig_rst
);
500 gate
->setPort(ID(D
), sig_d
[i
]);
501 gate
->setPort(ID(Q
), sig_q
[i
]);
505 void simplemap_dlatch(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
507 int width
= cell
->parameters
.at(ID(WIDTH
)).as_int();
508 char en_pol
= cell
->parameters
.at(ID(EN_POLARITY
)).as_bool() ? 'P' : 'N';
510 RTLIL::SigSpec sig_en
= cell
->getPort(ID(EN
));
511 RTLIL::SigSpec sig_d
= cell
->getPort(ID(D
));
512 RTLIL::SigSpec sig_q
= cell
->getPort(ID(Q
));
514 IdString gate_type
= stringf("$_DLATCH_%c_", en_pol
);
516 for (int i
= 0; i
< width
; i
++) {
517 RTLIL::Cell
*gate
= module
->addCell(NEW_ID
, gate_type
);
518 gate
->add_strpool_attribute(ID(src
), cell
->get_strpool_attribute(ID(src
)));
519 gate
->setPort(ID(E
), sig_en
);
520 gate
->setPort(ID(D
), sig_d
[i
]);
521 gate
->setPort(ID(Q
), sig_q
[i
]);
525 void simplemap_get_mappers(std::map
<RTLIL::IdString
, void(*)(RTLIL::Module
*, RTLIL::Cell
*)> &mappers
)
527 mappers
[ID($
not)] = simplemap_not
;
528 mappers
[ID($pos
)] = simplemap_pos
;
529 mappers
[ID($
and)] = simplemap_bitop
;
530 mappers
[ID($
or)] = simplemap_bitop
;
531 mappers
[ID($
xor)] = simplemap_bitop
;
532 mappers
[ID($xnor
)] = simplemap_bitop
;
533 mappers
[ID($reduce_and
)] = simplemap_reduce
;
534 mappers
[ID($reduce_or
)] = simplemap_reduce
;
535 mappers
[ID($reduce_xor
)] = simplemap_reduce
;
536 mappers
[ID($reduce_xnor
)] = simplemap_reduce
;
537 mappers
[ID($reduce_bool
)] = simplemap_reduce
;
538 mappers
[ID($logic_not
)] = simplemap_lognot
;
539 mappers
[ID($logic_and
)] = simplemap_logbin
;
540 mappers
[ID($logic_or
)] = simplemap_logbin
;
541 mappers
[ID($eq
)] = simplemap_eqne
;
542 mappers
[ID($eqx
)] = simplemap_eqne
;
543 mappers
[ID($ne
)] = simplemap_eqne
;
544 mappers
[ID($nex
)] = simplemap_eqne
;
545 mappers
[ID($mux
)] = simplemap_mux
;
546 mappers
[ID($tribuf
)] = simplemap_tribuf
;
547 mappers
[ID($lut
)] = simplemap_lut
;
548 mappers
[ID($sop
)] = simplemap_sop
;
549 mappers
[ID($slice
)] = simplemap_slice
;
550 mappers
[ID($concat
)] = simplemap_concat
;
551 mappers
[ID($sr
)] = simplemap_sr
;
552 mappers
[ID($ff
)] = simplemap_ff
;
553 mappers
[ID($dff
)] = simplemap_dff
;
554 mappers
[ID($dffe
)] = simplemap_dffe
;
555 mappers
[ID($dffsr
)] = simplemap_dffsr
;
556 mappers
[ID($adff
)] = simplemap_adff
;
557 mappers
[ID($dlatch
)] = simplemap_dlatch
;
560 void simplemap(RTLIL::Module
*module
, RTLIL::Cell
*cell
)
562 static std::map
<RTLIL::IdString
, void(*)(RTLIL::Module
*, RTLIL::Cell
*)> mappers
;
563 static bool initialized_mappers
= false;
565 if (!initialized_mappers
) {
566 simplemap_get_mappers(mappers
);
567 initialized_mappers
= true;
570 mappers
.at(cell
->type
)(module
, cell
);
574 PRIVATE_NAMESPACE_BEGIN
576 struct SimplemapPass
: public Pass
{
577 SimplemapPass() : Pass("simplemap", "mapping simple coarse-grain cells") { }
578 void help() YS_OVERRIDE
580 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
582 log(" simplemap [selection]\n");
584 log("This pass maps a small selection of simple coarse-grain cells to yosys gate\n");
585 log("primitives. The following internal cell types are mapped by this pass:\n");
587 log(" $not, $pos, $and, $or, $xor, $xnor\n");
588 log(" $reduce_and, $reduce_or, $reduce_xor, $reduce_xnor, $reduce_bool\n");
589 log(" $logic_not, $logic_and, $logic_or, $mux, $tribuf\n");
590 log(" $sr, $ff, $dff, $dffsr, $adff, $dlatch\n");
593 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
595 log_header(design
, "Executing SIMPLEMAP pass (map simple cells to gate primitives).\n");
596 extra_args(args
, 1, design
);
598 std::map
<RTLIL::IdString
, void(*)(RTLIL::Module
*, RTLIL::Cell
*)> mappers
;
599 simplemap_get_mappers(mappers
);
601 for (auto mod
: design
->modules()) {
602 if (!design
->selected(mod
) || mod
->get_blackbox_attribute())
604 std::vector
<RTLIL::Cell
*> cells
= mod
->cells();
605 for (auto cell
: cells
) {
606 if (mappers
.count(cell
->type
) == 0)
608 if (!design
->selected(mod
, cell
))
610 log("Mapping %s.%s (%s).\n", log_id(mod
), log_id(cell
), log_id(cell
->type
));
611 mappers
.at(cell
->type
)(mod
, cell
);
618 PRIVATE_NAMESPACE_END