2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2019 Miodrag Milanovic <miodrag@symbioticeda.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 static SigBit
get_bit_or_zero(const SigSpec
&sig
)
28 if (GetSize(sig
) == 0)
33 static void fix_carry_chain(Module
*module
)
35 SigMap
sigmap(module
);
38 dict
<SigBit
, SigBit
> mapping_bits
;
40 for (auto cell
: module
->cells())
42 if (cell
->type
== ID(AL_MAP_ADDER
)) {
43 if (cell
->getParam(ID(ALUTYPE
)) != Const("ADD")) continue;
44 SigBit bit_i0
= get_bit_or_zero(cell
->getPort(ID(a
)));
45 SigBit bit_i1
= get_bit_or_zero(cell
->getPort(ID(b
)));
46 if (bit_i0
== State::S0
&& bit_i1
== State::S0
) {
47 SigBit bit_ci
= get_bit_or_zero(cell
->getPort(ID(c
)));
48 SigSpec o
= cell
->getPort(ID(o
));
49 if (GetSize(o
) == 2) {
51 ci_bits
.insert(bit_ci
);
52 mapping_bits
[bit_ci
] = bit_o
;
57 vector
<Cell
*> adders_to_fix_cells
;
58 for (auto cell
: module
->cells())
60 if (cell
->type
== ID(AL_MAP_ADDER
)) {
61 if (cell
->getParam(ID(ALUTYPE
)) != Const("ADD")) continue;
62 SigBit bit_ci
= get_bit_or_zero(cell
->getPort(ID(c
)));
63 SigBit bit_i0
= get_bit_or_zero(cell
->getPort(ID(a
)));
64 SigBit bit_i1
= get_bit_or_zero(cell
->getPort(ID(b
)));
65 SigBit canonical_bit
= sigmap(bit_ci
);
66 if (!ci_bits
.count(canonical_bit
))
68 if (bit_i0
== State::S0
&& bit_i1
== State::S0
)
71 adders_to_fix_cells
.push_back(cell
);
72 log("Found %s cell named %s with invalid 'c' signal.\n", log_id(cell
->type
), log_id(cell
));
76 for (auto cell
: adders_to_fix_cells
)
78 SigBit bit_ci
= get_bit_or_zero(cell
->getPort(ID(c
)));
79 SigBit canonical_bit
= sigmap(bit_ci
);
80 auto bit
= mapping_bits
.at(canonical_bit
);
81 log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell
->type
), log_id(cell
));
82 Cell
*c
= module
->addCell(NEW_ID
, ID(AL_MAP_ADDER
));
83 SigBit new_bit
= module
->addWire(NEW_ID
);
84 SigBit dummy_bit
= module
->addWire(NEW_ID
);
86 bits
.append(dummy_bit
);
88 c
->setParam(ID(ALUTYPE
), Const("ADD_CARRY"));
89 c
->setPort(ID(a
), bit
);
90 c
->setPort(ID(b
), State::S0
);
91 c
->setPort(ID(c
), State::S0
);
92 c
->setPort(ID(o
), bits
);
94 cell
->setPort(ID(c
), new_bit
);
99 struct AnlogicCarryFixPass
: public Pass
{
100 AnlogicCarryFixPass() : Pass("anlogic_fixcarry", "Anlogic: fix carry chain") { }
101 void help() YS_OVERRIDE
103 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
105 log(" anlogic_fixcarry [options] [selection]\n");
107 log("Add Anlogic adders to fix carry chain if needed.\n");
110 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
112 log_header(design
, "Executing anlogic_fixcarry pass (fix invalid carry chain).\n");
115 for (argidx
= 1; argidx
< args
.size(); argidx
++)
119 extra_args(args
, argidx
, design
);
121 Module
*module
= design
->top_module();
123 if (module
== nullptr)
124 log_cmd_error("No top module found.\n");
126 fix_carry_chain(module
);
128 } AnlogicCarryFixPass
;
130 PRIVATE_NAMESPACE_END