mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-23 23:52:32 +00:00
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.
This commit is contained in:
parent
0e82bbefe5
commit
4d215665a1
5 changed files with 198 additions and 0 deletions
|
|
@ -52,4 +52,5 @@ yosys_pass(synth_gowin
|
|||
lutrams_map.v
|
||||
lutrams.txt
|
||||
dsp_map.v
|
||||
macc_map_gw5a.v
|
||||
)
|
||||
|
|
|
|||
59
techlibs/gowin/macc_map_gw5a.v
Normal file
59
techlibs/gowin/macc_map_gw5a.v
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
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
|
||||
|
|
@ -277,6 +277,13 @@ struct SynthGowinPass : public ScriptPass
|
|||
run("opt -nodffe -nosdff");
|
||||
run("fsm");
|
||||
run("opt");
|
||||
// GW5A MAC: run alumacc + macc techmap BEFORE wreduce. wreduce
|
||||
// narrows $mul Y but not the connected $add A, leaving a width
|
||||
// mismatch that prevents alumacc from merging $mul into $add.
|
||||
if (!nodsp && family == "gw5a") {
|
||||
run("alumacc");
|
||||
run("techmap -map +/gowin/macc_map_gw5a.v");
|
||||
}
|
||||
run("wreduce");
|
||||
run("peepopt");
|
||||
run("opt_clean");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue