mirror of
https://github.com/YosysHQ/yosys
synced 2025-10-09 17:31:59 +00:00
Merge 5ad9e4cacc
into a80462f27f
This commit is contained in:
commit
575b1cde26
5 changed files with 204 additions and 1 deletions
|
@ -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/brams.txt))
|
||||||
$(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams_map.v))
|
$(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/lutrams.txt))
|
||||||
|
$(eval $(call add_share_file,share/gowin,techlibs/gowin/dsp_map.v))
|
||||||
|
|
65
techlibs/gowin/dsp_map.v
Normal file
65
techlibs/gowin/dsp_map.v
Normal file
|
@ -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 [72: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
|
|
@ -91,13 +91,16 @@ struct SynthGowinPass : public ScriptPass
|
||||||
log(" The following families are supported:\n");
|
log(" The following families are supported:\n");
|
||||||
log(" 'gw1n', 'gw2a', 'gw5a'.\n");
|
log(" 'gw1n', 'gw2a', 'gw5a'.\n");
|
||||||
log("\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");
|
log("The following commands are executed by this synthesis command:\n");
|
||||||
help_script();
|
help_script();
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
string top_opt, vout_file, json_file, family;
|
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
|
void clear_flags() override
|
||||||
{
|
{
|
||||||
|
@ -115,6 +118,7 @@ struct SynthGowinPass : public ScriptPass
|
||||||
noiopads = false;
|
noiopads = false;
|
||||||
noalu = false;
|
noalu = false;
|
||||||
no_rw_check = false;
|
no_rw_check = false;
|
||||||
|
nodsp = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
|
@ -193,6 +197,10 @@ struct SynthGowinPass : public ScriptPass
|
||||||
no_rw_check = true;
|
no_rw_check = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-nodsp") {
|
||||||
|
nodsp = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
@ -208,6 +216,24 @@ struct SynthGowinPass : public ScriptPass
|
||||||
log_pop();
|
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
|
void script() override
|
||||||
{
|
{
|
||||||
std::string no_rw_check_opt = "";
|
std::string no_rw_check_opt = "";
|
||||||
|
@ -233,6 +259,23 @@ struct SynthGowinPass : public ScriptPass
|
||||||
|
|
||||||
if (check_label("coarse"))
|
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);
|
run("synth -run coarse" + no_rw_check_opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
47
tests/arch/gowin/mul_gw1n.ys
Normal file
47
tests/arch/gowin/mul_gw1n.ys
Normal file
|
@ -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
tests/arch/gowin/mul_gw2a.ys
Normal file
47
tests/arch/gowin/mul_gw2a.ys
Normal file
|
@ -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…
Add table
Add a link
Reference in a new issue