From 78ab02613536626242a1f1b0e81bb49e9421a868 Mon Sep 17 00:00:00 2001
From: Zanting <zanting>
Date: Wed, 18 Nov 2015 11:18:06 +0000
Subject: [PATCH] Added Arria 10 multiplier components

---
 libraries/technology/mult/hdllib.cfg          |   3 +
 .../technology/mult/tech_complex_mult.vhd     |  57 ++++++++++
 libraries/technology/mult/tech_mult.vhd       |  44 ++++++++
 .../mult/tech_mult_component_pkg.vhd          | 101 +++++++++++++++++-
 4 files changed, 200 insertions(+), 5 deletions(-)

diff --git a/libraries/technology/mult/hdllib.cfg b/libraries/technology/mult/hdllib.cfg
index 5fb5ca03e3..f68c58c85c 100644
--- a/libraries/technology/mult/hdllib.cfg
+++ b/libraries/technology/mult/hdllib.cfg
@@ -3,6 +3,9 @@ hdl_library_clause_name = tech_mult_lib
 hdl_lib_uses_synth = common
                      technology
                      ip_stratixiv_mult
+                     ip_arria10_mult
+                     ip_arria10_complex_mult
+                     ip_arria10_complex_mult_rtl
 hdl_lib_uses_sim = 
 
 hdl_lib_technology = 
diff --git a/libraries/technology/mult/tech_complex_mult.vhd b/libraries/technology/mult/tech_complex_mult.vhd
index a22307f35b..6c7908a007 100644
--- a/libraries/technology/mult/tech_complex_mult.vhd
+++ b/libraries/technology/mult/tech_complex_mult.vhd
@@ -28,6 +28,10 @@ USE work.tech_mult_component_pkg.ALL;
 
 -- Declare IP libraries to ensure default binding in simulation. The IP library clause is ignored by synthesis.
 LIBRARY ip_stratixiv_mult_lib;
+--LIBRARY ip_arria10_mult_lib;
+--LIBRARY ip_arria10_mult_rtl_lib;
+LIBRARY ip_arria10_complex_mult_altmult_complex_150;
+LIBRARY ip_arria10_complex_mult_rtl_lib;
 
 
 ENTITY tech_complex_mult IS
@@ -128,5 +132,58 @@ begin
     );
   END GENERATE;
 
+  gen_ip_arria10_ip : IF (g_technology=c_tech_arria10 AND g_variant="IP") GENERATE
+
+    -- Adapt DSP input widths
+    ar <= RESIZE_SVEC(in_ar, c_dsp_dat_w);
+    ai <= RESIZE_SVEC(in_ai, c_dsp_dat_w);
+    br <= RESIZE_SVEC(in_br, c_dsp_dat_w);
+    bi <= RESIZE_SVEC(in_bi, c_dsp_dat_w) WHEN g_conjugate_b=FALSE ELSE TO_SVEC(-TO_SINT(in_bi), c_dsp_dat_w);
+
+    u0 : ip_arria10_complex_mult
+    PORT MAP (
+         aclr        => rst,
+         clock       => clk,
+         dataa_imag  => ai,
+         dataa_real  => ar,
+         datab_imag  => bi,
+         datab_real  => br,
+         ena         => clken,
+         result_imag => mult_im,
+         result_real => mult_re
+         );
+
+    -- Back to true input widths and then resize for output width
+    result_re <= RESIZE_SVEC(mult_re, g_out_p_w);
+    result_im <= RESIZE_SVEC(mult_im, g_out_p_w);
+
+  END GENERATE;
+
+  gen_ip_arria10_rtl : IF (g_technology=c_tech_arria10 AND g_variant="RTL") GENERATE
+    u0 : ip_arria10_complex_mult_rtl
+  GENERIC MAP(
+    g_in_a_w           => g_in_a_w,
+    g_in_b_w           => g_in_b_w,
+    g_out_p_w          => g_out_p_w,
+    g_conjugate_b      => g_conjugate_b,
+    g_pipeline_input   => g_pipeline_input,
+    g_pipeline_product => g_pipeline_product,
+    g_pipeline_adder   => g_pipeline_adder,
+    g_pipeline_output  => g_pipeline_output
+  )
+  PORT MAP(
+    rst        => rst,
+    clk        => clk,
+    clken      => clken,
+    in_ar      => in_ar,
+    in_ai      => in_ai,
+    in_br      => in_br,
+    in_bi      => in_bi,
+    result_re  => result_re,
+    result_im  => result_im
+    );
+  END GENERATE;
+
+
 end str;
 
diff --git a/libraries/technology/mult/tech_mult.vhd b/libraries/technology/mult/tech_mult.vhd
index 505ba49caa..f1e57fa0cc 100644
--- a/libraries/technology/mult/tech_mult.vhd
+++ b/libraries/technology/mult/tech_mult.vhd
@@ -28,6 +28,7 @@ USE work.tech_mult_component_pkg.ALL;
 
 -- Declare IP libraries to ensure default binding in simulation. The IP library clause is ignored by synthesis.
 LIBRARY ip_stratixiv_mult_lib;
+LIBRARY ip_arria10_mult_lib;
 
 
 ENTITY tech_mult IS
@@ -106,6 +107,49 @@ begin
     );
   END GENERATE;
 
+  gen_ip_arria10_ip : IF (g_technology=c_tech_arria10 AND g_variant="IP") GENERATE
+    u0 : ip_arria10_mult
+  GENERIC MAP(
+    g_in_a_w           => g_in_a_w,
+    g_in_b_w           => g_in_b_w,
+    g_out_p_w          => g_out_p_w,
+    g_nof_mult         => g_nof_mult,
+    g_pipeline_input   => g_pipeline_input,
+    g_pipeline_product => g_pipeline_product,
+    g_pipeline_output  => g_pipeline_output,
+    g_representation   => g_representation
+  )
+  PORT MAP(
+    clk        => clk,
+    clken      => clken,
+    in_a       => in_a,
+    in_b       => in_b,
+    out_p      => prod
+    );
+  END GENERATE;
+   
+  gen_ip_arria10_rtl : IF (g_technology=c_tech_arria10 AND g_variant="RTL") GENERATE
+    u0 : ip_arria10_mult_rtl
+  GENERIC MAP(
+    g_in_a_w           => g_in_a_w,
+    g_in_b_w           => g_in_b_w,
+    g_out_p_w          => g_out_p_w,
+    g_nof_mult         => g_nof_mult,
+    g_pipeline_input   => g_pipeline_input,
+    g_pipeline_product => g_pipeline_product,
+    g_pipeline_output  => g_pipeline_output,
+    g_representation   => g_representation
+  )
+  PORT MAP(
+    rst        => rst,
+    clk        => clk,
+    clken      => clken,
+    in_a       => in_a,
+    in_b       => in_b,
+    out_p      => prod
+    );
+  END GENERATE;
+
   gen_trunk : FOR I IN 0 TO g_nof_mult-1 GENERATE
   -- Truncate MSbits, also for signed (common_pkg.vhd for explanation of RESIZE_SVEC)
     out_p((I+1)*g_out_p_w-1 DOWNTO I*g_out_p_w) <= RESIZE_SVEC(prod((I+1)*c_prod_w-1 DOWNTO I*c_prod_w), g_out_p_w) WHEN g_representation="SIGNED" ELSE
diff --git a/libraries/technology/mult/tech_mult_component_pkg.vhd b/libraries/technology/mult/tech_mult_component_pkg.vhd
index efb07cd0a9..f3e4e4b2d9 100644
--- a/libraries/technology/mult/tech_mult_component_pkg.vhd
+++ b/libraries/technology/mult/tech_mult_component_pkg.vhd
@@ -72,6 +72,55 @@ PACKAGE tech_mult_component_pkg IS
   );
   END COMPONENT;
 
+  -----------------------------------------------------------------------------
+  -- mult arria 10 ip component
+  -----------------------------------------------------------------------------
+
+  COMPONENT ip_arria10_mult IS 
+  GENERIC (
+    g_in_a_w           : POSITIVE := 18;      -- Width of the data A port
+    g_in_b_w           : POSITIVE := 18;      -- Width of the data B port
+    g_out_p_w          : POSITIVE := 36;      -- Width of the result port
+    g_nof_mult         : POSITIVE := 1;       -- using 2 for 18x18, 4 for 9x9 may yield better results when inferring * is used
+    g_pipeline_input   : NATURAL  := 1;        -- 0 or 1
+    g_pipeline_product : NATURAL  := 1;        -- 0 or 1
+    g_pipeline_output  : NATURAL  := 1;        -- >= 0
+    g_representation   : STRING   := "SIGNED"   -- or "UNSIGNED"
+  );
+  PORT (
+    clk        : IN  STD_LOGIC;
+    clken      : IN  STD_LOGIC := '1';
+    in_a       : IN  STD_LOGIC_VECTOR(g_nof_mult*g_in_a_w-1 DOWNTO 0);
+    in_b       : IN  STD_LOGIC_VECTOR(g_nof_mult*g_in_b_w-1 DOWNTO 0);
+    out_p      : OUT STD_LOGIC_VECTOR(g_nof_mult*(g_in_a_w+g_in_b_w)-1 DOWNTO 0)
+  );
+  END COMPONENT;
+
+  -----------------------------------------------------------------------------
+  -- mult arria 10 rtl component
+  -----------------------------------------------------------------------------
+
+  COMPONENT ip_arria10_mult_rtl IS 
+  GENERIC (
+    g_in_a_w           : POSITIVE := 18;
+    g_in_b_w           : POSITIVE := 18;
+    g_out_p_w          : POSITIVE := 36;      -- c_prod_w = g_in_a_w+g_in_b_w, use smaller g_out_p_w to truncate MSbits, or larger g_out_p_w to extend MSbits
+    g_nof_mult         : POSITIVE := 1;       -- using 2 for 18x18, 4 for 9x9 may yield better results when inferring * is used
+    g_pipeline_input   : NATURAL  := 1;        -- 0 or 1
+    g_pipeline_product : NATURAL  := 1;        -- 0 or 1
+    g_pipeline_output  : NATURAL  := 1;        -- >= 0
+    g_representation   : STRING   := "SIGNED"   -- or "UNSIGNED"
+  );
+  PORT (
+    rst        : IN  STD_LOGIC;
+    clk        : IN  STD_LOGIC;
+    clken      : IN  STD_LOGIC := '1';
+    in_a       : IN  STD_LOGIC_VECTOR(g_nof_mult*g_in_a_w-1 DOWNTO 0);
+    in_b       : IN  STD_LOGIC_VECTOR(g_nof_mult*g_in_b_w-1 DOWNTO 0);
+    out_p      : OUT STD_LOGIC_VECTOR(g_nof_mult*(g_in_a_w+g_in_b_w)-1 DOWNTO 0)
+  );
+  END COMPONENT;
+
   -----------------------------------------------------------------------------
   -- mult stratixiv ip component
   -----------------------------------------------------------------------------
@@ -94,9 +143,13 @@ PACKAGE tech_mult_component_pkg IS
     in_b       : IN  STD_LOGIC_VECTOR(g_nof_mult*g_in_b_w-1 DOWNTO 0);
     out_p      : OUT STD_LOGIC_VECTOR(g_nof_mult*(g_in_a_w+g_in_b_w)-1 DOWNTO 0)
   );
- END COMPONENT;
+  END COMPONENT;
+
+  -----------------------------------------------------------------------------
+  -- mult stratixiv rtl component
+  -----------------------------------------------------------------------------
 
- COMPONENT ip_stratixiv_mult_rtl IS 
+  COMPONENT ip_stratixiv_mult_rtl IS 
   GENERIC (
     g_in_a_w           : POSITIVE := 18;
     g_in_b_w           : POSITIVE := 18;
@@ -115,14 +168,52 @@ PACKAGE tech_mult_component_pkg IS
     in_b       : IN  STD_LOGIC_VECTOR(g_nof_mult*g_in_b_w-1 DOWNTO 0);
     out_p      : OUT STD_LOGIC_VECTOR(g_nof_mult*(g_in_a_w+g_in_b_w)-1 DOWNTO 0)
   );
- END COMPONENT;
+  END COMPONENT;
 
   -----------------------------------------------------------------------------
   -- arria10 ip component
   -----------------------------------------------------------------------------
- 
+
+  COMPONENT ip_arria10_complex_mult is
+  PORT (
+    dataa_real  : in  std_logic_vector(17 downto 0) := (others => '0'); --  complex_input.dataa_real
+    dataa_imag  : in  std_logic_vector(17 downto 0) := (others => '0'); --               .dataa_imag
+    datab_real  : in  std_logic_vector(17 downto 0) := (others => '0'); --               .datab_real
+    datab_imag  : in  std_logic_vector(17 downto 0) := (others => '0'); --               .datab_imag
+    clock       : in  std_logic                     := '0';             --               .clk
+    aclr        : in  std_logic                     := '0';             --               .aclr
+    ena         : in  std_logic                     := '0';             --               .ena
+    result_real : out std_logic_vector(35 downto 0);                    -- complex_output.result_real
+    result_imag : out std_logic_vector(35 downto 0)                     --               .result_imag
+  );
+  END COMPONENT;
+
   -----------------------------------------------------------------------------
   -- arria10 rtl component
   -----------------------------------------------------------------------------
-  
+
+  COMPONENT ip_arria10_complex_mult_rtl IS
+  GENERIC (
+    g_in_a_w           : POSITIVE := 18;
+    g_in_b_w           : POSITIVE := 18;
+    g_out_p_w          : POSITIVE := 36;
+    g_conjugate_b      : BOOLEAN := FALSE;
+    g_pipeline_input   : NATURAL := 1;      -- 0 or 1
+    g_pipeline_product : NATURAL := 0;      -- 0 or 1
+    g_pipeline_adder   : NATURAL := 1;      -- 0 or 1
+    g_pipeline_output  : NATURAL := 1       -- >= 0
+  );
+  PORT (
+    rst        : IN   STD_LOGIC := '0';
+    clk        : IN   STD_LOGIC;
+    clken      : IN   STD_LOGIC := '1';
+    in_ar      : IN   STD_LOGIC_VECTOR(g_in_a_w-1 DOWNTO 0);
+    in_ai      : IN   STD_LOGIC_VECTOR(g_in_a_w-1 DOWNTO 0);
+    in_br      : IN   STD_LOGIC_VECTOR(g_in_b_w-1 DOWNTO 0);
+    in_bi      : IN   STD_LOGIC_VECTOR(g_in_b_w-1 DOWNTO 0);
+    result_re  : OUT  STD_LOGIC_VECTOR(g_out_p_w-1 DOWNTO 0);
+    result_im  : OUT  STD_LOGIC_VECTOR(g_out_p_w-1 DOWNTO 0)
+  );
+  END COMPONENT;
+
 END tech_mult_component_pkg;
-- 
GitLab