3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-05-25 11:26:22 +00:00

Remove black boxes for now.

This commit is contained in:
nella 2026-05-25 10:38:51 +02:00
parent b17792c451
commit 932be8c611
3 changed files with 6 additions and 86 deletions

View file

@ -47,14 +47,12 @@ enum class FinalAdder {
DEFAULT, // emit $add and let downstream techmap pick
RIPPLE, // emit $add with explicit narrow hint
PARALLEL_PREFIX, // emit $add with PARALLEL_PREFIX
ELARITH_MOP_CSV, // black-box instance of \AddMopCsv
};
enum class FinalMode {
AUTO,
RIPPLE,
PREFIX,
ELARITH
};
inline std::pair<SigSpec, SigSpec> emit_compressor_32(Module *module, SigSpec a, SigSpec b, SigSpec c, int width)
@ -393,11 +391,10 @@ inline void emit_kogge_stone(Module *module, SigSpec a, SigSpec b, SigSpec y)
* @b: Signal B
* @y: Signal Y
* @choice: Adder type to instantiate
* @any_signed: Signed info for library macros
*
* Return: Cell* of the emitted instance
*/
inline Cell *emit_final_adder(Module *module, SigSpec a, SigSpec b, SigSpec y, FinalAdder choice, bool any_signed) {
inline Cell *emit_final_adder(Module *module, SigSpec a, SigSpec b, SigSpec y, FinalAdder choice) {
switch (choice) {
case FinalAdder::DEFAULT:
case FinalAdder::RIPPLE: {
@ -407,17 +404,6 @@ inline Cell *emit_final_adder(Module *module, SigSpec a, SigSpec b, SigSpec y, F
emit_kogge_stone(module, a, b, y);
return nullptr;
}
case FinalAdder::ELARITH_MOP_CSV: {
Cell *c = module->addCell(NEW_ID, IdString("\\AddMopCsv"));
int w = GetSize(y);
c->setParam(IdString("\\WIDTH"), w);
c->setParam(IdString("\\NUM_OPERANDS"), 2);
c->setParam(IdString("\\SIGNED"), any_signed ? 1 : 0);
c->setParam(IdString("\\SPEED"), Const("fast"));
c->setPort(IdString("\\Operands"), {a, b});
c->setPort(IdString("\\Sum"), y);
return c;
}
}
log_assert(false && "CompressorTree::emit_final_adder: invalid choice");
return nullptr;
@ -427,7 +413,6 @@ inline FinalAdder pick_final_adder(int width, FinalMode mode) {
switch (mode) {
case FinalMode::RIPPLE: return FinalAdder::RIPPLE;
case FinalMode::PREFIX: return FinalAdder::PARALLEL_PREFIX;
case FinalMode::ELARITH: return FinalAdder::ELARITH_MOP_CSV;
case FinalMode::AUTO:
default: return (width < RIPPLE_PREFIX_THRESHOLD) ? FinalAdder::DEFAULT : FinalAdder::PARALLEL_PREFIX;
}

View file

@ -21,7 +21,6 @@ struct ArithTreeOptions {
CompressorTree::Strategy strategy = CompressorTree::Strategy::PREFER_42;
CompressorTree::FinalMode final_mode = CompressorTree::FinalMode::AUTO;
bool fma_fusion = true;
bool elarith_macro = false;
};
struct ArithTreeWorker {
@ -335,52 +334,13 @@ struct ArithTreeWorker {
return pool;
}
void emit_tree(std::vector<Operand> &operands, SigSpec result_y, int neg_compensation, bool any_signed, const char *desc)
void emit_tree(std::vector<Operand> &operands, SigSpec result_y, int neg_compensation)
{
int width = GetSize(result_y);
if (opt.elarith_macro) {
// Bypass the compressor
emit_elarith_macro(operands, result_y, neg_compensation, any_signed, desc);
return;
}
auto pool = build_operand_pool(operands, width, neg_compensation);
auto [a, b] = CompressorTree::reduce_scheduled(module, std::move(pool), width, opt.strategy);
auto final_choice = CompressorTree::pick_final_adder(width, opt.final_mode);
CompressorTree::emit_final_adder(module, a, b, result_y, final_choice, any_signed);
}
void emit_elarith_macro(std::vector<Operand> &operands, SigSpec result_y, int neg_compensation, bool any_signed, const char *desc)
{
// Multi operand
int width = GetSize(result_y);
auto pool = build_operand_pool(operands, width, neg_compensation);
log(" arith_tree::elarith: %s -> \\AddMopCsv macro, %d operands, width %d (module %s)\n", desc, (int)pool.size(), width, log_id(module));
// Pack all operands
SigSpec flat;
for (auto &dp : pool) {
SigSpec ext = CompressorTree::normalize_to_width(dp.sig, false, width);
flat.append(ext);
}
Cell *c = module->addCell(NEW_ID, IdString("\\AddMopCsv"));
c->setParam(IdString("\\WIDTH"), width);
c->setParam(IdString("\\NUM_OPERANDS"), (int)pool.size());
c->setParam(IdString("\\SIGNED"), any_signed ? 1 : 0);
c->setParam(IdString("\\SPEED"), Const("fast"));
c->setPort(IdString("\\Operands"), flat);
c->setPort(IdString("\\Sum"), result_y);
}
bool any_operand_signed(const std::vector<Operand> &operands)
{
for (auto &op : operands)
if (op.is_signed || op.factor_b_signed)
return true;
return false;
CompressorTree::emit_final_adder(module, a, b, result_y, final_choice);
}
void process_chains()
@ -415,7 +375,7 @@ struct ArithTreeWorker {
for (auto c : chain)
to_remove.insert(c);
emit_tree(operands, root->getPort(ID::Y), neg_compensation, any_operand_signed(operands), "Replaced $add/$sub chain");
emit_tree(operands, root->getPort(ID::Y), neg_compensation);
}
for (auto cell : to_remove)
@ -442,7 +402,7 @@ struct ArithTreeWorker {
if (!has_mul && operands.size() < 3)
continue;
emit_tree(operands, cell->getPort(ID::Y), neg_compensation, any_operand_signed(operands), has_mul ? "Replaced $macc (FMA)" : "Replaced $macc");
emit_tree(operands, cell->getPort(ID::Y), neg_compensation);
to_remove.insert(cell);
}
for (auto cell : to_remove)
@ -477,17 +437,12 @@ struct ArithTreePass : public Pass {
log(" '42' (the default) prefers 4:2 compressor groupings, with\n");
log(" fallback to 3:2 compressors for residuals\n");
log("\n");
log(" -final <auto|ripple|prefix|elarith>\n");
log(" -final <auto|ripple|prefix>\n");
log(" Selects the architecture used for the final two-vector add.\n");
log("\n");
log(" -no-fma\n");
log(" Disable fused multiply-add expansion in $macc cells\n");
log("\n");
log(" -elarith-macro\n");
log(" Replace each detected chain with a single \\AddMopCsv black-box\n");
log(" instance instead of expanding it into $fa cells. The downstream\n");
log(" flow must provide an \\AddMopCsv implementation\n");
log("\n");
log("The default behaviour delivers 4:2 compression, FMA fusion, and a\n");
log("width-adaptive final adder\n");
log("\n");
@ -514,7 +469,6 @@ struct ArithTreePass : public Pass {
if (v == "auto") { opt.final_mode = CompressorTree::FinalMode::AUTO; }
else if (v == "ripple") { opt.final_mode = CompressorTree::FinalMode::RIPPLE; }
else if (v == "prefix") { opt.final_mode = CompressorTree::FinalMode::PREFIX; }
else if (v == "elarith") { opt.final_mode = CompressorTree::FinalMode::ELARITH; }
else { log_cmd_error("arith_tree: unknown -final '%s'\n", v.c_str()); }
continue;
}
@ -522,10 +476,6 @@ struct ArithTreePass : public Pass {
opt.fma_fusion = false;
continue;
}
if (arg == "-elarith-macro") {
opt.elarith_macro = true;
continue;
}
break;
}
extra_args(args, argidx, design);

View file

@ -68,18 +68,3 @@ select -assert-min 1 t:$_AND_
select -assert-min 1 t:$_XOR_
design -reset
read_verilog <<EOT
module elarith_macro(
input [15:0] a, b, c, d,
output [15:0] y
);
assign y = a + b + c + d;
endmodule
EOT
hierarchy -auto-top
proc
arith_tree -elarith-macro
select -assert-count 0 t:$fa
select -assert-count 0 t:$add
select -assert-count 1 t:\AddMopCsv
design -reset