3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-05 15:06:11 +00:00

Use ripple as default final adder, gate fma.

This commit is contained in:
nella 2026-06-03 15:13:20 +02:00
parent 11a650c695
commit f8d2252735
4 changed files with 29 additions and 31 deletions

View file

@ -19,7 +19,7 @@ PRIVATE_NAMESPACE_BEGIN
struct ArithTreeOptions { struct ArithTreeOptions {
CompressorTree::Strategy strategy = CompressorTree::Strategy::PREFER_42; CompressorTree::Strategy strategy = CompressorTree::Strategy::PREFER_42;
CompressorTree::FinalMode final_mode = CompressorTree::FinalMode::AUTO; CompressorTree::FinalMode final_mode = CompressorTree::FinalMode::RIPPLE;
bool fma_fusion = true; bool fma_fusion = true;
}; };
@ -309,22 +309,21 @@ struct ArithTreeWorker {
s = module->Not(NEW_ID, s); s = module->Not(NEW_ID, s);
pool.push_back({s, 0}); pool.push_back({s, 0});
} else { } else {
// Multiplicative operand. // Multiplicative operand
auto pps = CompressorTree::generate_partial_products(module, op.sig, op.factor_b, op.is_signed, op.factor_b_signed, width); auto pps = CompressorTree::generate_partial_products(module, op.sig, op.factor_b, op.is_signed, op.factor_b_signed, width);
if (!op.negate) { if (!op.negate) {
for (auto &pp : pps) for (auto &pp : pps)
pool.push_back(pp);
continue;
}
SigSpec neg_a = module->Not(NEW_ID, op.sig);
auto neg_pps = CompressorTree::generate_partial_products(module, neg_a, op.factor_b, op.is_signed, op.factor_b_signed, width);
for (auto &pp : neg_pps)
pool.push_back(pp); pool.push_back(pp);
continue; SigSpec b_ext = CompressorTree::normalize_to_width(op.factor_b, op.factor_b_signed, width);
} pool.push_back({b_ext, 0});
auto [a_red, b_red] = CompressorTree::reduce_scheduled(module, pps, width, opt.strategy);
SigSpec product = module->addWire(NEW_ID, width);
module->addAdd(NEW_ID, a_red, b_red, product, false);
SigSpec neg = module->addWire(NEW_ID, width);
module->addNot(NEW_ID, product, neg);
pool.push_back({neg, 0});
neg_compensation++;
} }
} }
@ -392,22 +391,21 @@ struct ArithTreeWorker {
continue; continue;
if (operands.size() < 1) if (operands.size() < 1)
continue; continue;
bool has_mul = false; int mul_terms = 0;
for (auto &op : operands) for (auto &op : operands)
if (GetSize(op.factor_b) > 0) { if (GetSize(op.factor_b) > 0)
has_mul = true; mul_terms++;
break; bool has_mul = (mul_terms > 0);
} if (mul_terms == 1 && operands.size() == 1)
continue;
if (!has_mul && operands.size() < 3) if (!has_mul && operands.size() < 3)
continue; continue;
emit_tree(operands, cell->getPort(ID::Y), neg_compensation); emit_tree(operands, cell->getPort(ID::Y), neg_compensation);
to_remove.insert(cell); to_remove.insert(cell);
} }
for (auto cell : to_remove) for (auto cell : to_remove)
module->remove(cell); module->remove(cell);
} }
void run() void run()
{ {

View file

@ -52,9 +52,9 @@ proc
equiv_opt arith_tree equiv_opt arith_tree
design -load postopt design -load postopt
select -assert-count 2 t:$fa select -assert-count 2 t:$fa
select -assert-none t:$add select -assert-count 1 t:$add
select -assert-min 1 t:$_AND_ select -assert-min 0 t:$_AND_
select -assert-min 1 t:$_XOR_ select -assert-min 0 t:$_XOR_
design -reset design -reset
read_verilog <<EOT read_verilog <<EOT

View file

@ -12,10 +12,10 @@ alumacc
opt opt
equiv_opt arith_tree equiv_opt arith_tree
design -load postopt design -load postopt
select -assert-count 0 t:$macc t:$macc_v2 %u select -assert-count 1 t:$macc t:$macc_v2 %u
select -assert-count 0 t:$mul select -assert-count 0 t:$mul
select -assert-count 1 t:$add select -assert-count 0 t:$add
select -assert-min 1 t:$fa select -assert-min 0 t:$fa
design -reset design -reset
read_verilog <<EOT read_verilog <<EOT

View file

@ -32,9 +32,9 @@ alumacc
opt opt
equiv_opt arith_tree equiv_opt arith_tree
design -load postopt design -load postopt
select -assert-count 0 t:$macc t:$macc_v2 %u select -assert-count 1 t:$macc t:$macc_v2 %u
select -assert-count 0 t:$mul select -assert-count 0 t:$mul
select -assert-min 1 t:$fa select -assert-min 0 t:$fa
design -reset design -reset
read_verilog <<EOT read_verilog <<EOT