143 std::vector<RTLIL::SigSpec> summands;
144 std::vector<RTLIL::SigBit> tree_sum_bits;
145 int unique_tree_bits = 0;
146 int count_tree_words = 0;
151 bool got_data_bits =
false;
153 for (
int i = 0; i <
width; i++)
154 if (!
bits.at(i).empty()) {
155 auto it =
bits.at(i).begin();
157 bits.at(i).erase(it);
158 got_data_bits =
true;
164 summands.push_back(summand);
170 int max_depth = 0, max_position = 0;
171 for (
int i = 0; i <
width; i++)
177 if (max_depth == 0 || max_position > 4)
180 int required_bits = 0;
181 for (
int i = 0; i <= max_position; i++)
183 required_bits += 1 << i;
185 if (required_bits > free_bit_slots)
188 for (
int i = 0; i <= max_position; i++)
190 auto it =
bits.at(i).begin();
192 for (
int k = 0; k < (1 << i); k++, free_bit_slots--)
193 tree_sum_bits.push_back(bit);
194 bits.at(i).erase(it);
202 if (!tree_sum_bits.empty())
203 log(
" packed %d (%d) bits / %d words into adder tree\n",
GetSize(tree_sum_bits), unique_tree_bits, count_tree_words);
212 return summands.front();
217 std::vector<RTLIL::SigSpec> new_summands;
218 for (
int i = 0; i <
GetSize(summands); i += 3)
224 fulladd(in1, in2, in3, out1, out2);
226 if (!tree_sum_bits.empty()) {
227 extra_bit = tree_sum_bits.back();
228 tree_sum_bits.pop_back();
230 new_summands.push_back(out1);
231 new_summands.push_back({out2.
extract(0, width-1), extra_bit});
233 new_summands.push_back(summands[i]);
236 summands.swap(new_summands);
241 c->
setPort(
"\\A", summands.front());
242 c->
setPort(
"\\B", summands.back());
250 if (!tree_sum_bits.empty()) {
251 c->
setPort(
"\\CI", tree_sum_bits.back());
252 tree_sum_bits.pop_back();
void fixup_parameters(bool set_a_signed=false, bool set_b_signed=false)
int tree_bit_slots(int n)
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
void fulladd(RTLIL::SigSpec &in1, RTLIL::SigSpec &in2, RTLIL::SigSpec &in3, RTLIL::SigSpec &out1, RTLIL::SigSpec &out2)
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
int GetSize(RTLIL::Wire *wire)
#define log_assert(_assert_expr_)
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
void log(const char *format,...)
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
std::vector< std::set< RTLIL::SigBit > > bits