3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-15 03:35:40 +00:00
yosys/techlibs/gowin/macc_map_gw5a.v
Johan Olby 4d215665a1
gowin: infer DSP multiply-accumulate for the GW5A family
Map $macc_v2 cells (one signed <=27x18 product + one <=48-bit addend)
to MULTALU27X18 with the C addend enabled, so a*b+c maps to a single
DSP block instead of a multiply + fabric adder.

The C addend requires DYN_C_SEL("TRUE") + CSEL=1 (gowin_pack reads the
CSEL port, not the C_SEL parameter).

alumacc + macc techmap run before wreduce for gw5a, so $mul and $add
ports still have matching widths when alumacc tries to merge them.
Running after wreduce breaks the merge: wreduce narrows $mul Y (48->45)
but not $add A (stays 48), and alumacc can't merge mismatched widths.
2026-07-13 20:57:08 +02:00

59 lines
1.2 KiB
Verilog

module \$macc_v2 (A, B, C, Y);
parameter NPRODUCTS = 0;
parameter PRODUCT_NEGATED = 1'b0;
parameter NADDENDS = 0;
parameter ADDEND_NEGATED = 1'b0;
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter C_SIGNED = 0;
parameter A_WIDTHS = 1;
parameter B_WIDTHS = 1;
parameter C_WIDTHS = 1;
parameter Y_WIDTH = 1;
input [A_WIDTHS-1:0] A;
input [B_WIDTHS-1:0] B;
input [C_WIDTHS-1:0] C;
output [Y_WIDTH-1:0] Y;
wire _TECHMAP_FAIL_ = !(NPRODUCTS == 1 && NADDENDS == 1 &&
PRODUCT_NEGATED == 1'b0 && ADDEND_NEGATED == 1'b0 &&
A_SIGNED && B_SIGNED && C_SIGNED &&
A_WIDTHS <= 27 && B_WIDTHS <= 18 && C_WIDTHS <= 48);
wire [47:0] dout_w;
MULTALU27X18 #(
.MULT12X12_EN("FALSE"),
.MULT_RESET_MODE("SYNC"),
.AREG_CLK("BYPASS"),
.BREG_CLK("BYPASS"),
.PREG_CLK("BYPASS"),
.OREG_CLK("BYPASS"),
.DYN_C_SEL("TRUE")
) __TECHMAP_REPLACE__ (
.DOUT(dout_w),
.CASO(),
.SOA(),
.A(A),
.SIA(27'd0),
.B(B),
.C(C),
.D(26'd0),
.CASI(48'd0),
.ACCSEL(1'b0),
.PSEL(1'b0),
.ASEL(1'b0),
.PADDSUB(1'b0),
.CSEL(1'b1),
.CASISEL(1'b0),
.ADDSUB(2'b00),
.CLK(2'b00),
.CE(2'b00),
.RESET(2'b00)
);
assign Y = dout_w;
endmodule