mirror of https://github.com/YosysHQ/yosys.git
intel_alm: Add multiply signedness to cells
Quartus assumes unsigned multiplication by default, breaking signed multiplies, so add an input signedness parameter to the MISTRAL_MUL* cells to propagate to Quartus' <family>_mac cells.
This commit is contained in:
parent
4f2b78e19a
commit
1a07b330f8
|
@ -1,3 +1,5 @@
|
|||
`default_nettype none
|
||||
|
||||
module __MUL27X27(A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 1;
|
||||
|
|
|
@ -1,38 +1,83 @@
|
|||
(* abc9_box *)
|
||||
module MISTRAL_MUL27X27(input [26:0] A, input [26:0] B, output [53:0] Y);
|
||||
|
||||
parameter A_SIGNED = 1;
|
||||
parameter B_SIGNED = 1;
|
||||
|
||||
// TODO: Cyclone 10 GX timings; the below are for Cyclone V
|
||||
specify
|
||||
(A *> Y) = 3732;
|
||||
(B *> Y) = 3928;
|
||||
endspecify
|
||||
|
||||
assign Y = $signed(A) * $signed(B);
|
||||
wire [53:0] A_, B_;
|
||||
|
||||
if (A_SIGNED)
|
||||
assign A_ = $signed(A);
|
||||
else
|
||||
assign A_ = $unsigned(A);
|
||||
|
||||
if (B_SIGNED)
|
||||
assign B_ = $signed(B);
|
||||
else
|
||||
assign B_ = $unsigned(B);
|
||||
|
||||
assign Y = A_ * B_;
|
||||
|
||||
endmodule
|
||||
|
||||
(* abc9_box *)
|
||||
module MISTRAL_MUL18X18(input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||
|
||||
parameter A_SIGNED = 1;
|
||||
parameter B_SIGNED = 1;
|
||||
|
||||
// TODO: Cyclone 10 GX timings; the below are for Cyclone V
|
||||
specify
|
||||
(A *> Y) = 3180;
|
||||
(B *> Y) = 3982;
|
||||
endspecify
|
||||
|
||||
assign Y = $signed(A) * $signed(B);
|
||||
wire [35:0] A_, B_;
|
||||
|
||||
if (A_SIGNED)
|
||||
assign A_ = $signed(A);
|
||||
else
|
||||
assign A_ = $unsigned(A);
|
||||
|
||||
if (B_SIGNED)
|
||||
assign B_ = $signed(B);
|
||||
else
|
||||
assign B_ = $unsigned(B);
|
||||
|
||||
assign Y = A_ * B_;
|
||||
|
||||
endmodule
|
||||
|
||||
(* abc9_box *)
|
||||
module MISTRAL_MUL9X9(input [8:0] A, input [8:0] B, output [17:0] Y);
|
||||
|
||||
parameter A_SIGNED = 1;
|
||||
parameter B_SIGNED = 1;
|
||||
|
||||
// TODO: Cyclone 10 GX timings; the below are for Cyclone V
|
||||
specify
|
||||
(A *> Y) = 2818;
|
||||
(B *> Y) = 3051;
|
||||
endspecify
|
||||
|
||||
assign Y = $signed(A) * $signed(B);
|
||||
wire [17:0] A_, B_;
|
||||
|
||||
if (A_SIGNED)
|
||||
assign A_ = $signed(A);
|
||||
else
|
||||
assign A_ = $unsigned(A);
|
||||
|
||||
if (B_SIGNED)
|
||||
assign B_ = $signed(B);
|
||||
else
|
||||
assign B_ = $unsigned(B);
|
||||
|
||||
assign Y = A_ * B_;
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -565,7 +565,9 @@ endmodule
|
|||
module cyclonev_mac(ax, ay, resulta);
|
||||
|
||||
parameter ax_width = 9;
|
||||
parameter signed_max = "true";
|
||||
parameter ay_scan_in_width = 9;
|
||||
parameter signed_may = "true";
|
||||
parameter result_a_width = 18;
|
||||
parameter operation_mode = "M9x9";
|
||||
|
||||
|
@ -579,7 +581,9 @@ endmodule
|
|||
module cyclone10gx_mac(ax, ay, resulta);
|
||||
|
||||
parameter ax_width = 18;
|
||||
parameter signed_max = "true";
|
||||
parameter ay_scan_in_width = 18;
|
||||
parameter signed_may = "true";
|
||||
parameter result_a_width = 36;
|
||||
parameter operation_mode = "M18X18_FULL";
|
||||
|
||||
|
|
|
@ -174,20 +174,62 @@ endmodule
|
|||
|
||||
module MISTRAL_MUL27X27(input [26:0] A, B, output [53:0] Y);
|
||||
|
||||
`MAC #(.ax_width(27), .ay_scan_in_width(27), .result_a_width(54), .operation_mode("M27x27")) _TECHMAP_REPLACE_ (.ax(A), .ay(B), .resulta(Y));
|
||||
parameter A_SIGNED = 1;
|
||||
parameter B_SIGNED = 1;
|
||||
|
||||
`MAC #(
|
||||
.ax_width(27),
|
||||
.signed_max(A_SIGNED ? "true" : "false"),
|
||||
.ay_scan_in_width(27),
|
||||
.signed_may(B_SIGNED ? "true" : "false"),
|
||||
.result_a_width(54),
|
||||
.operation_mode("M27x27")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.ax(A),
|
||||
.ay(B),
|
||||
.resulta(Y)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_MUL18X18(input [17:0] A, B, output [35:0] Y);
|
||||
|
||||
`MAC #(.ax_width(18), .ay_scan_in_width(18), .result_a_width(36), .operation_mode("M18x18_FULL")) _TECHMAP_REPLACE_ (.ax(B), .ay(A), .resulta(Y));
|
||||
parameter A_SIGNED = 1;
|
||||
parameter B_SIGNED = 1;
|
||||
|
||||
`MAC #(
|
||||
.ax_width(18),
|
||||
.signed_max(A_SIGNED ? "true" : "false"),
|
||||
.ay_scan_in_width(18),
|
||||
.signed_may(B_SIGNED ? "true" : "false"),
|
||||
.result_a_width(36),
|
||||
.operation_mode("M18x18_FULL")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.ax(A),
|
||||
.ay(B),
|
||||
.resulta(Y)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_MUL9X9(input [8:0] A, B, output [17:0] Y);
|
||||
|
||||
`MAC #(.ax_width(9), .ay_scan_in_width(9), .result_a_width(18), .operation_mode("M9x9")) _TECHMAP_REPLACE_ (.ax(A), .ay(B), .resulta(Y));
|
||||
parameter A_SIGNED = 1;
|
||||
parameter B_SIGNED = 1;
|
||||
|
||||
`MAC #(
|
||||
.ax_width(9),
|
||||
.signed_max(A_SIGNED ? "true" : "false"),
|
||||
.ay_scan_in_width(9),
|
||||
.signed_may(B_SIGNED ? "true" : "false"),
|
||||
.result_a_width(18),
|
||||
.operation_mode("M9x9")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.ax(A),
|
||||
.ay(B),
|
||||
.resulta(Y)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -214,15 +214,15 @@ struct SynthIntelALMPass : public ScriptPass {
|
|||
run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp)");
|
||||
} else if (!nodsp) {
|
||||
// Cyclone V supports 9x9 multiplication, Cyclone 10 GX does not.
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=19 -D DSP_B_MINWIDTH=19 -D DSP_SIGNEDONLY -D DSP_NAME=__MUL27X27");
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=19 -D DSP_B_MINWIDTH=19 -D DSP_NAME=__MUL27X27");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
if (family_opt == "cyclonev") {
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=10 -D DSP_SIGNEDONLY -D DSP_NAME=__MUL18X18");
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=10 -D DSP_NAME=__MUL18X18");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=9 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_SIGNEDONLY -D DSP_NAME=__MUL9X9");
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=9 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL9X9");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
} else if (family_opt == "cyclone10gx") {
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_SIGNEDONLY -D DSP_NAME=__MUL18X18");
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL18X18");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
module top
|
||||
#(parameter X_WIDTH=6, Y_WIDTH=6, A_WIDTH=12)
|
||||
(
|
||||
input [5:0] x,
|
||||
input [5:0] y,
|
||||
input [X_WIDTH-1:0] x,
|
||||
input [Y_WIDTH-1:0] y,
|
||||
|
||||
output [11:0] A,
|
||||
output [A_WIDTH-1:0] A,
|
||||
);
|
||||
assign A = x * y;
|
||||
endmodule
|
||||
|
|
|
@ -1,23 +1,60 @@
|
|||
read_verilog ../common/mul.v
|
||||
chparam -set X_WIDTH 8 -set Y_WIDTH 8 -set A_WIDTH 16
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
|
||||
stat
|
||||
|
||||
select -assert-count 1 t:MISTRAL_MUL9X9
|
||||
select -assert-none t:MISTRAL_MUL9X9 %% t:* %D
|
||||
|
||||
# Cyclone 10 GX does not have 9x9 multipliers.
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/mul.v
|
||||
chparam -set X_WIDTH 17 -set Y_WIDTH 17 -set A_WIDTH 34
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
|
||||
select -assert-count 1 t:MISTRAL_MUL18X18
|
||||
select -assert-none t:MISTRAL_MUL18X18 %% t:* %D
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/mul.v
|
||||
chparam -set X_WIDTH 17 -set Y_WIDTH 17 -set A_WIDTH 34
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
|
||||
# Cyclone 10 GX does not have 9x9 multipliers, so we use 18x18.
|
||||
select -assert-count 1 t:MISTRAL_MUL18X18
|
||||
select -assert-none t:MISTRAL_MUL18X18 %% t:* %D
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/mul.v
|
||||
chparam -set X_WIDTH 26 -set Y_WIDTH 26 -set A_WIDTH 52
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
|
||||
select -assert-count 1 t:MISTRAL_MUL27X27
|
||||
select -assert-none t:MISTRAL_MUL27X27 %% t:* %D
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/mul.v
|
||||
chparam -set X_WIDTH 26 -set Y_WIDTH 26 -set A_WIDTH 52
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
|
||||
select -assert-count 1 t:MISTRAL_MUL27X27
|
||||
select -assert-none t:MISTRAL_MUL27X27 %% t:* %D
|
||||
|
|
Loading…
Reference in New Issue