aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/intel_alm
diff options
context:
space:
mode:
authorDan Ravensloft <dan.ravensloft@gmail.com>2020-08-26 18:44:48 +0100
committerMarcelina Koƛcielnicka <mwk@0x04.net>2020-08-26 22:50:16 +0200
commit1a07b330f8220ce441cabce2b21633a12434229a (patch)
tree4c564ecf2f8ae5585c90756151ad7d15381f5400 /techlibs/intel_alm
parent4f2b78e19af3a2d342efe9780e220282b7a3a046 (diff)
downloadyosys-1a07b330f8220ce441cabce2b21633a12434229a.tar.gz
yosys-1a07b330f8220ce441cabce2b21633a12434229a.tar.bz2
yosys-1a07b330f8220ce441cabce2b21633a12434229a.zip
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.
Diffstat (limited to 'techlibs/intel_alm')
-rw-r--r--techlibs/intel_alm/common/dsp_map.v2
-rw-r--r--techlibs/intel_alm/common/dsp_sim.v51
-rw-r--r--techlibs/intel_alm/common/megafunction_bb.v4
-rw-r--r--techlibs/intel_alm/common/quartus_rename.v48
-rw-r--r--techlibs/intel_alm/synth_intel_alm.cc8
5 files changed, 103 insertions, 10 deletions
diff --git a/techlibs/intel_alm/common/dsp_map.v b/techlibs/intel_alm/common/dsp_map.v
index d1bc25e65..e12e777a4 100644
--- a/techlibs/intel_alm/common/dsp_map.v
+++ b/techlibs/intel_alm/common/dsp_map.v
@@ -1,3 +1,5 @@
+`default_nettype none
+
module __MUL27X27(A, B, Y);
parameter A_SIGNED = 1;
diff --git a/techlibs/intel_alm/common/dsp_sim.v b/techlibs/intel_alm/common/dsp_sim.v
index 45fdebb3f..bdb6d18d5 100644
--- a/techlibs/intel_alm/common/dsp_sim.v
+++ b/techlibs/intel_alm/common/dsp_sim.v
@@ -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
diff --git a/techlibs/intel_alm/common/megafunction_bb.v b/techlibs/intel_alm/common/megafunction_bb.v
index 530e44054..874f293b1 100644
--- a/techlibs/intel_alm/common/megafunction_bb.v
+++ b/techlibs/intel_alm/common/megafunction_bb.v
@@ -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";
diff --git a/techlibs/intel_alm/common/quartus_rename.v b/techlibs/intel_alm/common/quartus_rename.v
index 9bc532ca2..3b4628675 100644
--- a/techlibs/intel_alm/common/quartus_rename.v
+++ b/techlibs/intel_alm/common/quartus_rename.v
@@ -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
diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc
index 7ab50ef8f..faa405df7 100644
--- a/techlibs/intel_alm/synth_intel_alm.cc
+++ b/techlibs/intel_alm/synth_intel_alm.cc
@@ -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");
}
}