Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions techlibs/gowin/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ $(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams.txt))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams.txt))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/dsp_map.v))
65 changes: 65 additions & 0 deletions techlibs/gowin/dsp_map.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
module \$__MUL9X9 (input [8:0] A, input [8:0] B, output [17:0] Y);
parameter A_WIDTH = 9;
parameter B_WIDTH = 9;
parameter Y_WIDTH = 18;
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;

wire [8:0] soa;
wire [8:0] sob;

MULT9X9 _TECHMAP_REPLACE_ (
.A(A),
.B(B),
.SIA(8'b0),
.SIB(8'b0),
.ASIGN(A_SIGNED),
.BSIGN(B_SIGNED),
.ASEL(1'b0),
.BSEL(1'b0),
.SOA(soa),
.SOB(sob),
.DOUT(Y)
);
endmodule

module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
parameter A_WIDTH = 18;
parameter B_WIDTH = 18;
parameter Y_WIDTH = 36;
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;

wire [17:0] soa;
wire [17:0] sob;

MULT18X18 _TECHMAP_REPLACE_ (
.A(A),
.B(B),
.SIA(18'b0),
.SIB(18'b0),
.ASIGN(A_SIGNED),
.BSIGN(B_SIGNED),
.ASEL(1'b0),
.BSEL(1'b0),
.SOA(soa),
.SOB(sob),
.DOUT(Y)
);
endmodule

module \$__MUL36X36 (input [35:0] A, input [35:0] B, output [71:0] Y);
parameter A_WIDTH = 36;
parameter B_WIDTH = 36;
parameter Y_WIDTH = 72;
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;

MULT36X36 _TECHMAP_REPLACE_ (
.A(A),
.B(B),
.ASIGN(A_SIGNED),
.BSIGN(B_SIGNED),
.DOUT(Y)
);
endmodule
45 changes: 44 additions & 1 deletion techlibs/gowin/synth_gowin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,16 @@ struct SynthGowinPass : public ScriptPass
log(" The following families are supported:\n");
log(" 'gw1n', 'gw2a', 'gw5a'.\n");
log("\n");
log(" -nodsp\n");
log(" do not infer DSP multipliers.\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
log("\n");
}

string top_opt, vout_file, json_file, family;
bool retime, nobram, nolutram, flatten, nodffe, nowidelut, abc9, noiopads, noalu, no_rw_check;
bool retime, nobram, nolutram, flatten, nodffe, nowidelut, abc9, noiopads, noalu, no_rw_check, nodsp;

void clear_flags() override
{
Expand All @@ -115,6 +118,7 @@ struct SynthGowinPass : public ScriptPass
noiopads = false;
noalu = false;
no_rw_check = false;
nodsp = false;
}

void execute(std::vector<std::string> args, RTLIL::Design *design) override
Expand Down Expand Up @@ -193,6 +197,10 @@ struct SynthGowinPass : public ScriptPass
no_rw_check = true;
continue;
}
if (args[argidx] == "-nodsp") {
nodsp = true;
continue;
}
break;
}
extra_args(args, argidx, design);
Expand All @@ -208,6 +216,24 @@ struct SynthGowinPass : public ScriptPass
log_pop();
}

// DSP mapping rules for mul2dsp
struct DSPRule {
int a_maxwidth;
int b_maxwidth;
int a_minwidth;
int b_minwidth;
std::string prim;
};

// gw1n and gw2a
const std::vector<DSPRule> dsp_rules = {
{36, 36, 18, 18, "$__MUL36X36"},
{18, 18, 10, 4, "$__MUL18X18"},
{18, 18, 4, 10, "$__MUL18X18"},
{ 9, 9, 4, 4, "$__MUL9X9"},
};
// TODO: gw5a (MULT12X12, MULT27x36)

void script() override
{
std::string no_rw_check_opt = "";
Expand All @@ -233,6 +259,23 @@ struct SynthGowinPass : public ScriptPass

if (check_label("coarse"))
{
if (help_mode)
{
run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp)");
run("techmap -map +/gowin/dsp_map.v [...]", "(unless -nodsp)");
} else if (!nodsp) {
if (family == "gw1n" || family == "gw2a")
{
for (const auto &rule : dsp_rules)
{
run(stringf("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=%d -D DSP_B_MAXWIDTH=%d -D DSP_A_MINWIDTH=%d -D DSP_B_MINWIDTH=%d -D DSP_NAME=%s",
rule.a_maxwidth, rule.b_maxwidth, rule.a_minwidth, rule.b_minwidth, rule.prim.c_str()));
run("chtype -set $mul t:$__soft_mul");
}
run("techmap -map +/gowin/dsp_map.v");
}
}

run("synth -run coarse" + no_rw_check_opt);
}

Expand Down
47 changes: 47 additions & 0 deletions tests/arch/gowin/mul_gw1n.ys
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
read_verilog ../common/mul.v
chparam -set X_WIDTH 8 -set Y_WIDTH 8 -set A_WIDTH 16
hierarchy -top top
proc
# equivalence checking is somewhat slow (and missing simulation models)
synth_gowin -family gw1n

cd top # Constrain all select calls below inside the top module
select -assert-count 1 t:MULT9X9
# XXX: Whats's `top/x_IBUF_I_O_MULT9X9_A_A_GND_G` ??
# select -assert-none t:IBUF t:OBUF t:MULT9X9 %% t:* %D

design -reset
read_verilog ../common/mul.v
chparam -set X_WIDTH 16 -set Y_WIDTH 16 -set A_WIDTH 32
hierarchy -top top
proc
synth_gowin -family gw1n
cd top # Constrain all select calls below inside the top module
select -assert-count 1 t:MULT18X18
# XXX: top/x_IBUF_I_O_MULT18X18_A_A_GND_G ???
# select -assert-none t:IBUF t:OBUF t:MULT18X18 %% t:* %D


design -reset
read_verilog ../common/mul.v
chparam -set X_WIDTH 32 -set Y_WIDTH 32 -set A_WIDTH 64
hierarchy -top top
proc
# equivalence checking is too slow here
synth_gowin
cd top # Constrain all select calls below inside the top module
select -assert-count 1 t:MULT36X36
# XXX: top/x_IBUF_I_O_MULT36X36_A_A_GND_G
# select -assert-none t:IBUF t:OBUF t:MULT36X36 %% t:* %D

# TODO: We end up with two 18x18 multipliers
# design -reset
# read_verilog ../common/mul.v
# chparam -set X_WIDTH 32 -set Y_WIDTH 16 -set A_WIDTH 48
# hierarchy -top top
# proc
# # equivalence checking is too slow here
# synth_gowin
# cd top # Constrain all select calls below inside the top module
# select -assert-count 2 t:MULT18X18
# select -assert-none t:IBUF t:OBUF t:MULT36X36 %% t:* %D
47 changes: 47 additions & 0 deletions tests/arch/gowin/mul_gw2a.ys
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
read_verilog ../common/mul.v
chparam -set X_WIDTH 8 -set Y_WIDTH 8 -set A_WIDTH 16
hierarchy -top top
proc
# equivalence checking is somewhat slow (and missing simulation models)
synth_gowin -family gw2a

cd top # Constrain all select calls below inside the top module
select -assert-count 1 t:MULT9X9
# XXX: Whats's `top/x_IBUF_I_O_MULT9X9_A_A_GND_G` ??
# select -assert-none t:IBUF t:OBUF t:MULT9X9 %% t:* %D

design -reset
read_verilog ../common/mul.v
chparam -set X_WIDTH 16 -set Y_WIDTH 16 -set A_WIDTH 32
hierarchy -top top
proc
synth_gowin -family gw2a
cd top # Constrain all select calls below inside the top module
select -assert-count 1 t:MULT18X18
# XXX: top/x_IBUF_I_O_MULT18X18_A_A_GND_G ???
# select -assert-none t:IBUF t:OBUF t:MULT18X18 %% t:* %D


design -reset
read_verilog ../common/mul.v
chparam -set X_WIDTH 32 -set Y_WIDTH 32 -set A_WIDTH 64
hierarchy -top top
proc
# equivalence checking is too slow here
synth_gowin -family gw2a
cd top # Constrain all select calls below inside the top module
select -assert-count 1 t:MULT36X36
# XXX: top/x_IBUF_I_O_MULT36X36_A_A_GND_G
# select -assert-none t:IBUF t:OBUF t:MULT36X36 %% t:* %D

# TODO: We end up with two 18x18 multipliers
# design -reset
# read_verilog ../common/mul.v
# chparam -set X_WIDTH 32 -set Y_WIDTH 16 -set A_WIDTH 48
# hierarchy -top top
# proc
# # equivalence checking is too slow here
# synth_gowin -family gw2a
# cd top # Constrain all select calls below inside the top module
# select -assert-count 2 t:MULT18X18
# select -assert-none t:IBUF t:OBUF t:MULT36X36 %% t:* %D
Loading