2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2020 R. Ou <rqou@robertou.com>
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 RTLIL::Wire
*makexorbuffer(RTLIL::Module
*module
, SigBit inwire
, const char *cellname
)
28 RTLIL::Wire
*outwire
= nullptr;
30 if (inwire
== SigBit(true))
33 outwire
= module
->addWire(
34 module
->uniquify(stringf("$xc2fix$%s_BUF1_XOR_OUT", cellname
)));
35 auto xor_cell
= module
->addCell(
36 module
->uniquify(stringf("$xc2fix$%s_BUF1_XOR", cellname
)),
38 xor_cell
->setParam("\\INVERT_OUT", true);
39 xor_cell
->setPort("\\OUT", outwire
);
41 else if (inwire
== SigBit(false))
44 outwire
= module
->addWire(
45 module
->uniquify(stringf("$xc2fix$%s_BUF0_XOR_OUT", cellname
)));
46 auto xor_cell
= module
->addCell(
47 module
->uniquify(stringf("$xc2fix$%s_BUF0_XOR", cellname
)),
49 xor_cell
->setParam("\\INVERT_OUT", false);
50 xor_cell
->setPort("\\OUT", outwire
);
52 else if (inwire
== SigBit(RTLIL::State::Sx
))
55 log_warning("While buffering, changing x to 0 into cell %s\n", cellname
);
56 outwire
= module
->addWire(
57 module
->uniquify(stringf("$xc2fix$%s_BUF0_XOR_OUT", cellname
)));
58 auto xor_cell
= module
->addCell(
59 module
->uniquify(stringf("$xc2fix$%s_BUF0_XOR", cellname
)),
61 xor_cell
->setParam("\\INVERT_OUT", false);
62 xor_cell
->setPort("\\OUT", outwire
);
66 auto inwire_name
= inwire
.wire
->name
.c_str();
68 outwire
= module
->addWire(
69 module
->uniquify(stringf("$xc2fix$%s_BUF_XOR_OUT", inwire_name
)));
71 auto and_to_xor_wire
= module
->addWire(
72 module
->uniquify(stringf("$xc2fix$%s_BUF_AND_OUT", inwire_name
)));
74 auto and_cell
= module
->addCell(
75 module
->uniquify(stringf("$xc2fix$%s_BUF_AND", inwire_name
)),
77 and_cell
->setParam("\\TRUE_INP", 1);
78 and_cell
->setParam("\\COMP_INP", 0);
79 and_cell
->setPort("\\OUT", and_to_xor_wire
);
80 and_cell
->setPort("\\IN", inwire
);
81 and_cell
->setPort("\\IN_B", SigSpec());
83 auto xor_cell
= module
->addCell(
84 module
->uniquify(stringf("$xc2fix$%s_BUF_XOR", inwire_name
)),
86 xor_cell
->setParam("\\INVERT_OUT", false);
87 xor_cell
->setPort("\\IN_PTC", and_to_xor_wire
);
88 xor_cell
->setPort("\\OUT", outwire
);
94 RTLIL::Wire
*makeptermbuffer(RTLIL::Module
*module
, SigBit inwire
)
96 auto inwire_name
= inwire
.wire
->name
.c_str();
98 auto outwire
= module
->addWire(
99 module
->uniquify(stringf("$xc2fix$%s_BUF_AND_OUT", inwire_name
)));
101 auto and_cell
= module
->addCell(
102 module
->uniquify(stringf("$xc2fix$%s_BUF_AND", inwire_name
)),
104 and_cell
->setParam("\\TRUE_INP", 1);
105 and_cell
->setParam("\\COMP_INP", 0);
106 and_cell
->setPort("\\OUT", outwire
);
107 and_cell
->setPort("\\IN", inwire
);
108 and_cell
->setPort("\\IN_B", SigSpec());
113 struct Coolrunner2FixupPass
: public Pass
{
114 Coolrunner2FixupPass() : Pass("coolrunner2_fixup", "insert necessary buffer cells for CoolRunner-II architecture") { }
115 void help() YS_OVERRIDE
118 log(" coolrunner2_fixup [options] [selection]\n");
120 log("Insert necessary buffer cells for CoolRunner-II architecture.\n");
123 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
125 log_header(design
, "Executing COOLRUNNER2_FIXUP pass (insert necessary buffer cells for CoolRunner-II architecture).\n");
126 extra_args(args
, 1, design
);
128 for (auto module
: design
->selected_modules())
130 SigMap
sigmap(module
);
132 // Find all the FF outputs
133 pool
<SigBit
> sig_fed_by_ff
;
134 for (auto cell
: module
->selected_cells())
136 if (cell
->type
.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N",
137 "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
139 auto output
= sigmap(cell
->getPort("\\Q")[0]);
140 sig_fed_by_ff
.insert(output
);
144 // Find all the XOR outputs
145 pool
<SigBit
> sig_fed_by_xor
;
146 for (auto cell
: module
->selected_cells())
148 if (cell
->type
== "\\MACROCELL_XOR")
150 auto output
= sigmap(cell
->getPort("\\OUT")[0]);
151 sig_fed_by_xor
.insert(output
);
155 // Find all the input/inout outputs
156 pool
<SigBit
> sig_fed_by_io
;
157 for (auto cell
: module
->selected_cells())
159 if (cell
->type
.in("\\IBUF", "\\IOBUFE"))
161 if (cell
->hasPort("\\O")) {
162 auto output
= sigmap(cell
->getPort("\\O")[0]);
163 sig_fed_by_io
.insert(output
);
168 // Find all the pterm outputs
169 pool
<SigBit
> sig_fed_by_pterm
;
170 for (auto cell
: module
->selected_cells())
172 if (cell
->type
== "\\ANDTERM")
174 auto output
= sigmap(cell
->getPort("\\OUT")[0]);
175 sig_fed_by_pterm
.insert(output
);
179 // Find all the bufg outputs
180 pool
<SigBit
> sig_fed_by_bufg
;
181 for (auto cell
: module
->selected_cells())
183 if (cell
->type
== "\\BUFG")
185 auto output
= sigmap(cell
->getPort("\\O")[0]);
186 sig_fed_by_bufg
.insert(output
);
190 // Find all the bufgsr outputs
191 pool
<SigBit
> sig_fed_by_bufgsr
;
192 for (auto cell
: module
->selected_cells())
194 if (cell
->type
== "\\BUFGSR")
196 auto output
= sigmap(cell
->getPort("\\O")[0]);
197 sig_fed_by_bufgsr
.insert(output
);
201 // Find all the bufgts outputs
202 pool
<SigBit
> sig_fed_by_bufgts
;
203 for (auto cell
: module
->selected_cells())
205 if (cell
->type
== "\\BUFGTS")
207 auto output
= sigmap(cell
->getPort("\\O")[0]);
208 sig_fed_by_bufgts
.insert(output
);
212 // This is used to fix the input -> FF -> output scenario
213 pool
<SigBit
> sig_fed_by_ibuf
;
214 for (auto cell
: module
->selected_cells())
216 if (cell
->type
== "\\IBUF")
218 auto output
= sigmap(cell
->getPort("\\O")[0]);
219 sig_fed_by_ibuf
.insert(output
);
223 // Find all of the sinks for each output from an IBUF
224 dict
<SigBit
, std::pair
<int, RTLIL::Cell
*>> ibuf_fanouts
;
225 for (auto cell
: module
->selected_cells())
227 for (auto &conn
: cell
->connections())
229 if (cell
->input(conn
.first
))
231 for (auto wire_in
: sigmap(conn
.second
))
233 if (sig_fed_by_ibuf
[wire_in
])
235 auto existing_count
= ibuf_fanouts
[wire_in
].first
;
236 ibuf_fanouts
[wire_in
] =
237 std::pair
<int, RTLIL::Cell
*>(existing_count
+ 1, cell
);
244 dict
<SigBit
, RTLIL::Cell
*> ibuf_out_to_packed_reg_cell
;
245 pool
<SigBit
> packed_reg_out
;
246 for (auto x
: ibuf_fanouts
)
248 auto ibuf_out_wire
= x
.first
;
249 auto fanout_count
= x
.second
.first
;
250 auto maybe_ff_cell
= x
.second
.second
;
252 // The register can be packed with the IBUF only if it's
253 // actually a register and it's the only fanout. Otherwise,
254 // the pad-to-zia path has to be used up and the register
255 // can't be packed with the ibuf.
256 if (fanout_count
== 1 && maybe_ff_cell
->type
.in(
257 "\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N",
258 "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
261 if (maybe_ff_cell
->type
.in("\\FTCP", "\\FTCP_N", "\\FTDCP"))
262 input
= sigmap(maybe_ff_cell
->getPort("\\T")[0]);
264 input
= sigmap(maybe_ff_cell
->getPort("\\D")[0]);
265 SigBit output
= sigmap(maybe_ff_cell
->getPort("\\Q")[0]);
267 if (input
== ibuf_out_wire
)
269 log("Found IBUF %s that can be packed with FF %s (type %s)\n",
270 ibuf_out_wire
.wire
->name
.c_str(),
271 maybe_ff_cell
->name
.c_str(),
272 maybe_ff_cell
->type
.c_str());
274 ibuf_out_to_packed_reg_cell
[ibuf_out_wire
] = maybe_ff_cell
;
275 packed_reg_out
.insert(output
);
280 for (auto cell
: module
->selected_cells())
282 if (cell
->type
.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N",
283 "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
285 // Buffering FF inputs. FF inputs can only come from either
286 // an IO pin or from an XOR. Otherwise AND/XOR cells need
289 if (cell
->type
.in("\\FTCP", "\\FTCP_N", "\\FTDCP"))
290 input
= sigmap(cell
->getPort("\\T")[0]);
292 input
= sigmap(cell
->getPort("\\D")[0]);
294 // If the input wasn't an XOR nor an IO, then a buffer
295 // definitely needs to be added.
296 // Otherwise, if it is an IO, only leave unbuffered
297 // if we're being packed with the IO.
298 if ((!sig_fed_by_xor
[input
] && !sig_fed_by_io
[input
]) ||
299 (sig_fed_by_io
[input
] && ibuf_out_to_packed_reg_cell
[input
] != cell
))
301 log("Buffering input to \"%s\"\n", cell
->name
.c_str());
303 auto xor_to_ff_wire
= makexorbuffer(module
, input
, cell
->name
.c_str());
305 if (cell
->type
.in("\\FTCP", "\\FTCP_N", "\\FTDCP"))
306 cell
->setPort("\\T", xor_to_ff_wire
);
308 cell
->setPort("\\D", xor_to_ff_wire
);
311 // Buffering FF clocks. FF clocks can only come from either
312 // a pterm or a bufg. In some cases this will be handled
313 // in coolrunner2_sop (e.g. if clock is generated from
314 // AND-ing two signals) but not in all cases.
316 if (cell
->type
.in("\\LDCP", "\\LDCP_N"))
317 clock
= sigmap(cell
->getPort("\\G")[0]);
319 clock
= sigmap(cell
->getPort("\\C")[0]);
321 if (!sig_fed_by_pterm
[clock
] && !sig_fed_by_bufg
[clock
])
323 log("Buffering clock to \"%s\"\n", cell
->name
.c_str());
325 auto pterm_to_ff_wire
= makeptermbuffer(module
, clock
);
327 if (cell
->type
.in("\\LDCP", "\\LDCP_N"))
328 cell
->setPort("\\G", pterm_to_ff_wire
);
330 cell
->setPort("\\C", pterm_to_ff_wire
);
333 // Buffering FF set/reset. This can only come from either
334 // a pterm or a bufgsr.
336 set
= sigmap(cell
->getPort("\\PRE")[0]);
337 if (set
!= SigBit(false))
339 if (!sig_fed_by_pterm
[set
] && !sig_fed_by_bufgsr
[set
])
341 log("Buffering set to \"%s\"\n", cell
->name
.c_str());
343 auto pterm_to_ff_wire
= makeptermbuffer(module
, set
);
345 cell
->setPort("\\PRE", pterm_to_ff_wire
);
350 reset
= sigmap(cell
->getPort("\\CLR")[0]);
351 if (reset
!= SigBit(false))
353 if (!sig_fed_by_pterm
[reset
] && !sig_fed_by_bufgsr
[reset
])
355 log("Buffering reset to \"%s\"\n", cell
->name
.c_str());
357 auto pterm_to_ff_wire
= makeptermbuffer(module
, reset
);
359 cell
->setPort("\\CLR", pterm_to_ff_wire
);
363 // Buffering FF clock enable
364 // FIXME: This doesn't fully fix PTC conflicts
365 // FIXME: Need to ensure constant enables are optimized out
366 if (cell
->type
.in("\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
369 ce
= sigmap(cell
->getPort("\\CE")[0]);
370 if (!sig_fed_by_pterm
[ce
])
372 log("Buffering clock enable to \"%s\"\n", cell
->name
.c_str());
374 auto pterm_to_ff_wire
= makeptermbuffer(module
, ce
);
376 cell
->setPort("\\CE", pterm_to_ff_wire
);
382 for (auto cell
: module
->selected_cells())
384 if (cell
->type
== "\\IOBUFE")
386 // Buffer IOBUFE inputs. This can only be fed from an XOR or FF.
387 SigBit input
= sigmap(cell
->getPort("\\I")[0]);
389 if ((!sig_fed_by_xor
[input
] && !sig_fed_by_ff
[input
]) ||
390 packed_reg_out
[input
])
392 log("Buffering input to \"%s\"\n", cell
->name
.c_str());
394 auto xor_to_io_wire
= makexorbuffer(module
, input
, cell
->name
.c_str());
396 cell
->setPort("\\I", xor_to_io_wire
);
399 // Buffer IOBUFE enables. This can only be fed from a pterm
401 if (cell
->hasPort("\\E"))
404 oe
= sigmap(cell
->getPort("\\E")[0]);
405 if (!sig_fed_by_pterm
[oe
] && !sig_fed_by_bufgts
[oe
])
407 log("Buffering output enable to \"%s\"\n", cell
->name
.c_str());
409 auto pterm_to_oe_wire
= makeptermbuffer(module
, oe
);
411 cell
->setPort("\\E", pterm_to_oe_wire
);
417 // Now we have to fix up some cases where shared logic can
418 // cause XORs to have multiple fanouts to something other than
419 // pterms (which is not ok)
421 // Find all the XOR outputs
422 dict
<SigBit
, RTLIL::Cell
*> xor_out_to_xor_cell
;
423 for (auto cell
: module
->selected_cells())
425 if (cell
->type
== "\\MACROCELL_XOR")
427 auto output
= sigmap(cell
->getPort("\\OUT")[0]);
428 xor_out_to_xor_cell
[output
] = cell
;
432 // Find all of the sinks for each output from an XOR
433 pool
<SigBit
> xor_fanout_once
;
434 for (auto cell
: module
->selected_cells())
436 if (cell
->type
== "\\ANDTERM")
439 for (auto &conn
: cell
->connections())
441 if (cell
->input(conn
.first
))
443 for (auto wire_in
: sigmap(conn
.second
))
445 auto xor_cell
= xor_out_to_xor_cell
[wire_in
];
448 if (xor_fanout_once
[wire_in
])
450 log("Additional fanout found for %s into %s (type %s), duplicating\n",
451 xor_cell
->name
.c_str(),
455 auto new_xor_cell
= module
->addCell(
456 module
->uniquify(xor_cell
->name
), xor_cell
);
457 auto new_wire
= module
->addWire(
458 module
->uniquify(wire_in
.wire
->name
));
459 new_xor_cell
->setPort("\\OUT", new_wire
);
460 cell
->setPort(conn
.first
, new_wire
);
462 xor_fanout_once
.insert(wire_in
);
469 // Do the same fanout fixing for OR terms. By doing this
470 // after doing XORs, both pieces will be duplicated when necessary.
472 // Find all the OR outputs
473 dict
<SigBit
, RTLIL::Cell
*> or_out_to_or_cell
;
474 for (auto cell
: module
->selected_cells())
476 if (cell
->type
== "\\ORTERM")
478 auto output
= sigmap(cell
->getPort("\\OUT")[0]);
479 or_out_to_or_cell
[output
] = cell
;
483 // Find all of the sinks for each output from an OR
484 pool
<SigBit
> or_fanout_once
;
485 for (auto cell
: module
->selected_cells())
487 for (auto &conn
: cell
->connections())
489 if (cell
->input(conn
.first
))
491 for (auto wire_in
: sigmap(conn
.second
))
493 auto or_cell
= or_out_to_or_cell
[wire_in
];
496 if (or_fanout_once
[wire_in
])
498 log("Additional fanout found for %s into %s (type %s), duplicating\n",
499 or_cell
->name
.c_str(),
503 auto new_or_cell
= module
->addCell(
504 module
->uniquify(or_cell
->name
), or_cell
);
505 auto new_wire
= module
->addWire(
506 module
->uniquify(wire_in
.wire
->name
));
507 new_or_cell
->setPort("\\OUT", new_wire
);
508 cell
->setPort(conn
.first
, new_wire
);
510 or_fanout_once
.insert(wire_in
);
518 } Coolrunner2FixupPass
;
520 PRIVATE_NAMESPACE_END