From f79c0ad21464b24c8b0fb013d7e1c1ad7a9286e8 Mon Sep 17 00:00:00 2001 From: Leo Moser Date: Wed, 24 Jun 2026 14:44:39 +0200 Subject: [PATCH] fabulous: add `-multiplier-map` option, map to `$__FABULOUS_MUL` - an example: `-multiplier-map multiplier_map.v 8:8:2:2:10` Signed-off-by: Leo Moser --- techlibs/fabulous/synth_fabulous.cc | 42 +++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/techlibs/fabulous/synth_fabulous.cc b/techlibs/fabulous/synth_fabulous.cc index 11fcefbb2..979db0165 100644 --- a/techlibs/fabulous/synth_fabulous.cc +++ b/techlibs/fabulous/synth_fabulous.cc @@ -61,6 +61,9 @@ struct SynthPass : public ScriptPass log(" -clkbuf-map \n"); log(" insert clock buffers using clkbufmap and map to the specified Verilog file.\n"); log("\n"); + log(" -multiplier-map \n"); + log(" convert multiplications to multiplier primitives and map to the specified Verilog file.\n"); + log("\n"); log(" -extra-plib \n"); log(" use the specified Verilog file for extra primitives (can be specified multiple\n"); log(" times).\n"); @@ -112,12 +115,12 @@ struct SynthPass : public ScriptPass log("\n"); } - string top_module, json_file, blif_file, fsm_opts, memory_opts, carry_mode, clkbuf_map; + string top_module, json_file, blif_file, fsm_opts, memory_opts, carry_mode, clkbuf_map, multiplier_map; std::vector extra_plib, extra_map, extra_mlibmap; std::vector> extra_ffs; bool autotop, noalumacc, nofsm, noshare, noiopad, flatten; - int lut; + int lut, multiplier_a_max, multiplier_b_max, multiplier_a_min, multiplier_b_min, multiplier_y_min; void clear_flags() override { @@ -183,6 +186,15 @@ struct SynthPass : public ScriptPass clkbuf_map = args[++argidx]; continue; } + if (args[argidx] == "-multiplier-map" && argidx+6 < args.size()) { + multiplier_map = args[++argidx]; + multiplier_a_max = atoi(args[++argidx].c_str()); + multiplier_b_max = atoi(args[++argidx].c_str()); + multiplier_a_min = atoi(args[++argidx].c_str()); + multiplier_b_min = atoi(args[++argidx].c_str()); + multiplier_y_min = atoi(args[++argidx].c_str()); + continue; + } if (args[argidx] == "-extra-plib" && argidx+1 < args.size()) { extra_plib.push_back(args[++argidx]); continue; @@ -293,6 +305,32 @@ struct SynthPass : public ScriptPass run("techmap -map +/cmp2lut.v -map +/cmp2lcu.v", " (if -lut)"); else if (lut) run(stringf("techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=%d", lut)); + if (help_mode || multiplier_map != "") { + run("wreduce t:$mul"); + if (help_mode) { + run("techmap -map +/mul2dsp.v -map -D DSP_A_MAXWIDTH= -D DSP_B_MAXWIDTH= " + "-D DSP_A_MINWIDTH= -D DSP_B_MINWIDTH= -D DSP_Y_MINWIDTH= " + "-D DSP_NAME=$__FABULOUS_MUL", "(if -multiplier-map)"); + } else { + run(stringf("techmap -map +/mul2dsp.v -map %s -D DSP_A_MAXWIDTH=%d -D DSP_B_MAXWIDTH=%d " + "-D DSP_A_MINWIDTH=%d -D DSP_B_MINWIDTH=%d -D DSP_Y_MINWIDTH=%d " + "-D DSP_NAME=$__FABULOUS_MUL", + multiplier_map.c_str(), + multiplier_a_max, + multiplier_b_max, + multiplier_a_min, + multiplier_b_min, + multiplier_y_min + ) + ); + } + run("select a:mul2dsp", " (if -multiplier-map)"); + run("setattr -unset mul2dsp", " (if -multiplier-map)"); + run("opt_expr -fine", " (if -multiplier-map)"); + run("wreduce", " (if -multiplier-map)"); + run("select -clear", " (if -multiplier-map)"); + run("chtype -set $mul t:$__soft_mul", "(if -multiplier-map)"); + } if (!noalumacc) run("alumacc", " (unless -noalumacc)"); if (!noshare)