diff --git a/libraries/base/common_mult/tb/vhdl/tb_tb_common_complex_mult.vhd b/libraries/base/common_mult/tb/vhdl/tb_tb_common_complex_mult.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..74d40c08438dc590daabef91fe1508d1c5cbd40e
--- /dev/null
+++ b/libraries/base/common_mult/tb/vhdl/tb_tb_common_complex_mult.vhd
@@ -0,0 +1,58 @@
+-- --------------------------------------------------------------------------
+-- Copyright 2020
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+-- --------------------------------------------------------------------------
+
+-- --------------------------------------------------------------------------
+-- Author: E. Kooistra
+-- Purpose: Multi tb for variants of common_complex_mult
+-- Description:
+-- Usage:
+--   > as 3
+--   > run -all
+-- --------------------------------------------------------------------------
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+
+ENTITY tb_tb_common_complex_mult IS
+END tb_tb_common_complex_mult;
+
+ARCHITECTURE tb OF tb_tb_common_complex_mult IS
+  SIGNAL tb_end : STD_LOGIC := '0';  -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
+BEGIN
+  -- g_variant          : STRING := "IP";
+  -- g_in_dat_w         : NATURAL := 4;
+  -- g_conjugate_b      : BOOLEAN := FALSE;   -- When FALSE p = a * b, else p = a * conj(b)
+  -- g_pipeline_input   : NATURAL := 1;
+  -- g_pipeline_product : NATURAL := 0;
+  -- g_pipeline_adder   : NATURAL := 1;
+  -- g_pipeline_output  : NATURAL := 1
+
+  
+  -- IP variants
+  u_ip_18b      : ENTITY work.tb_common_complex_mult GENERIC MAP ("IP", 18, FALSE, 1, 0, 1, 1);
+  --u_ip_27b      : ENTITY work.tb_common_complex_mult GENERIC MAP ("IP", 27, FALSE, 1, 0, 1, 1);
+  u_ip_18b_conj : ENTITY work.tb_common_complex_mult GENERIC MAP ("IP", 18,  TRUE, 1, 0, 1, 1);
+  --u_ip_27b_conj : ENTITY work.tb_common_complex_mult GENERIC MAP ("IP", 27,  TRUE, 1, 0, 1, 1);
+
+  -- RTL variants
+  u_rtl_18b      : ENTITY work.tb_common_complex_mult GENERIC MAP ("RTL", 18, FALSE, 1, 0, 1, 1);
+  u_rtl_27b      : ENTITY work.tb_common_complex_mult GENERIC MAP ("RTL", 27, FALSE, 1, 0, 1, 1);
+  u_rtl_18b_conj : ENTITY work.tb_common_complex_mult GENERIC MAP ("RTL", 18,  TRUE, 1, 0, 1, 1);
+  u_rtl_27b_conj : ENTITY work.tb_common_complex_mult GENERIC MAP ("RTL", 27,  TRUE, 1, 0, 1, 1);
+
+END tb;
diff --git a/libraries/technology/mult/tech_complex_mult.vhd b/libraries/technology/mult/tech_complex_mult.vhd
index bdaa07ad2df9bde03f94a4dd6c555db47fbe33fd..f7a1b26ad1fbf8a016938d6576485bef2b5ecef3 100644
--- a/libraries/technology/mult/tech_complex_mult.vhd
+++ b/libraries/technology/mult/tech_complex_mult.vhd
@@ -18,6 +18,41 @@
 -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
 --
 -------------------------------------------------------------------------------
+--
+-- Author : E. Kooistra
+-- Purpose : Wrapper for complex multiplier IP
+-- Decription :
+--
+--   Calculate complex product:
+--
+--     (ar + j*ai) * (br + j*bi) = (ar*br - ai*bi) + j *(ar*bi + ai*br)
+--                               =  pr             + j * pi
+--
+--   Assume IP is generated for complex product width for pr, pi of:
+--
+--     c_dsp_prod_w = 2*c_dsp_dat_w.
+--
+--   It is not necessary to support product width 2*c_dsp_dat_w + 1,
+--   because this +1 bit is only needed for pi in case ar = ai = br = bi
+--   = min, where
+--
+--     min = -2**(c_dsp_dat_w-1)
+--     max =  2**(c_dsp_dat_w-1) - 1.
+--
+--   The largest value for pi = min**2 + min**2.
+--   The largest value for pr = min**2 - min*max < largest pi.
+--
+--   The largest pi = 2 * min**2 = 2**(c_dsp_dat_w-1), so it just does not
+--   fit in c_dsp_prod_w, but largest pi - 1 = 2**(c_dsp_dat_w-1) - 1 does
+--   fit, so all other input values fit. In DSP systems the input value
+--   (min + j*min) typically never occurs.
+--
+--   Example: g_in_a_w = 3 bit:
+--            --> min = -4
+--                c_dsp_prod_w = 6
+--            --> largest pi = 32
+--            --> largest pi - 1 = 31 = 2**(c_dsp_prod_w-1) - 1
+--
 
 LIBRARY IEEE, common_lib, technology_lib;
 USE IEEE.std_logic_1164.ALL;
@@ -38,8 +73,6 @@ LIBRARY ip_arria10_complex_mult_rtl_canonical_lib;
 
 ENTITY tech_complex_mult IS
   GENERIC (
-    g_sim              : BOOLEAN := TRUE;
-    g_sim_level        : NATURAL := 0; -- 0: Simulate variant passed via g_variant for given g_technology
     g_technology       : NATURAL  := c_tech_select_default;
     g_variant          : STRING := "IP";
     g_in_a_w           : POSITIVE;
@@ -66,14 +99,8 @@ END tech_complex_mult;
 
 ARCHITECTURE str of tech_complex_mult is 
 
-  -- Force to maximum 18 bit width, because:
-  -- . the ip_stratixiv_complex_mult is generated for 18b inputs and 36b output and then uses 4 real multipliers and no additional registers
-  -- . if one input   > 18b then another IP needs to be regenerated and that will use  8 real multipliers and some extra LUTs and registers
-  -- . if both inputs > 18b then another IP needs to be regenerated and that will use 16 real multipliers and some extra LUTs and registers
-  -- . if the output is set to 18b+18b + 1b =37b to account for the sum then another IP needs to be regenerated and that will use some extra registers
-  -- ==> for inputs <= 18b this ip_stratixiv_complex_mult is appropriate and it can not be made parametrisable to fit also inputs > 18b.
-  CONSTANT c_dsp_dat_w    : NATURAL  := 18;
-  CONSTANT c_dsp_prod_w   : NATURAL  := 2*c_dsp_dat_w;
+  CONSTANT c_dsp_dat_w   : NATURAL := sel_a_b(g_in_a_w <= c_dsp_mult_18_w, c_dsp_mult_18_w, c_dsp_mult_27_w);  -- g_in_a_w = g_in_b_w
+  CONSTANT c_dsp_prod_w  : NATURAL  := 2*c_dsp_dat_w;
   
   SIGNAL ar        : STD_LOGIC_VECTOR(c_dsp_dat_w-1 DOWNTO 0);
   SIGNAL ai        : STD_LOGIC_VECTOR(c_dsp_dat_w-1 DOWNTO 0);
@@ -82,244 +109,253 @@ ARCHITECTURE str of tech_complex_mult is
   SIGNAL mult_re   : STD_LOGIC_VECTOR(c_dsp_prod_w-1 DOWNTO 0);
   SIGNAL mult_im   : STD_LOGIC_VECTOR(c_dsp_prod_w-1 DOWNTO 0);
 
-  -- sim_model=1
-  SIGNAL result_re_undelayed : STD_LOGIC_VECTOR(g_in_b_w+g_in_a_w-1 DOWNTO 0);
-  SIGNAL result_im_undelayed : STD_LOGIC_VECTOR(g_in_b_w+g_in_a_w-1 DOWNTO 0);
-
-begin
+BEGIN
 
-  gen_ip_stratixiv_ip : IF (g_sim=FALSE OR (g_sim=TRUE AND g_sim_level=0)) AND (g_technology=c_tech_stratixiv AND g_variant="IP") GENERATE
+  -----------------------------------------------------------------------------
+  -- IP variants for <= 18 bit
+  -----------------------------------------------------------------------------
 
+  gen_ip_stratixiv_ip : IF g_variant="IP" AND g_technology=c_tech_stratixiv AND c_dsp_dat_w <= c_dsp_mult_18_w 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);
+    ar <= RESIZE_SVEC(in_ar, c_dsp_mult_18_w);
+    ai <= RESIZE_SVEC(in_ai, c_dsp_mult_18_w);
+    br <= RESIZE_SVEC(in_br, c_dsp_mult_18_w);
+    bi <= RESIZE_SVEC(in_bi, c_dsp_mult_18_w) WHEN g_conjugate_b=FALSE ELSE TO_SVEC(-TO_SINT(in_bi), c_dsp_mult_18_w);
 
     u0 : ip_stratixiv_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
-         );
+      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_stratixiv_rtl : IF (g_sim=FALSE OR (g_sim=TRUE AND g_sim_level=0)) AND (g_technology=c_tech_stratixiv AND g_variant="RTL") GENERATE
-    u0 : ip_stratixiv_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;
-
-  gen_ip_arria10_ip : IF (g_sim=FALSE OR (g_sim=TRUE AND g_sim_level=0)) AND (g_technology=c_tech_arria10 AND g_variant="IP") GENERATE
-
+  gen_ip_arria10_ip : IF g_variant="IP" AND g_technology=c_tech_arria10 AND c_dsp_dat_w <= c_dsp_mult_18_w 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);
+    ar <= RESIZE_SVEC(in_ar, c_dsp_mult_18_w);
+    ai <= RESIZE_SVEC(in_ai, c_dsp_mult_18_w);
+    br <= RESIZE_SVEC(in_br, c_dsp_mult_18_w);
+    bi <= RESIZE_SVEC(in_bi, c_dsp_mult_18_w) WHEN g_conjugate_b=FALSE ELSE TO_SVEC(-TO_SINT(in_bi), c_dsp_mult_18_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
-         );
+      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;
 
-  -- RTL variant is the same for unb2, unb2a and unb2b
-  gen_ip_arria10_rtl : IF (g_sim=FALSE OR (g_sim=TRUE AND g_sim_level=0)) AND 
-      ((g_technology=c_tech_arria10 OR g_technology=c_tech_arria10_e3sge3 OR g_technology=c_tech_arria10_e1sg OR g_technology=c_tech_arria10_e2sg) 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;
+  gen_ip_arria10_e1sg_ip : IF g_variant="IP" AND g_technology=c_tech_arria10_e1sg AND c_dsp_dat_w <= c_dsp_mult_18_w GENERATE
+    -- Adapt DSP input widths
+    ar <= RESIZE_SVEC(in_ar, c_dsp_mult_18_w);
+    ai <= RESIZE_SVEC(in_ai, c_dsp_mult_18_w);
+    br <= RESIZE_SVEC(in_br, c_dsp_mult_18_w);
+    bi <= RESIZE_SVEC(in_bi, c_dsp_mult_18_w) WHEN g_conjugate_b=FALSE ELSE TO_SVEC(-TO_SINT(in_bi), c_dsp_mult_18_w);
 
-  gen_ip_arria10_rtl_canonical : IF (g_sim=FALSE OR (g_sim=TRUE AND g_sim_level=0)) AND 
-      ((g_technology=c_tech_arria10 OR g_technology=c_tech_arria10_e3sge3 OR g_technology=c_tech_arria10_e1sg OR g_technology=c_tech_arria10_e2sg) AND g_variant="RTL_C") GENERATE
-    u0 : ip_arria10_complex_mult_rtl_canonical
-  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, -- NOT SUPPORTED
-    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
+    u0 : ip_arria10_e1sg_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
     );
-  END GENERATE;
-
 
-  gen_ip_arria10_e1sg_ip : IF (g_sim=FALSE OR (g_sim=TRUE AND g_sim_level=0)) AND (g_technology=c_tech_arria10_e1sg AND g_variant="IP") GENERATE
+    -- 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_e2sg_ip : IF g_variant="IP" AND g_technology=c_tech_arria10_e2sg AND c_dsp_dat_w <= c_dsp_mult_18_w 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);
+    ar <= RESIZE_SVEC(in_ar, c_dsp_mult_18_w);
+    ai <= RESIZE_SVEC(in_ai, c_dsp_mult_18_w);
+    br <= RESIZE_SVEC(in_br, c_dsp_mult_18_w);
+    bi <= RESIZE_SVEC(in_bi, c_dsp_mult_18_w) WHEN g_conjugate_b=FALSE ELSE TO_SVEC(-TO_SINT(in_bi), c_dsp_mult_18_w);
 
-
-    u0 : ip_arria10_e1sg_complex_mult
+    u0 : ip_arria10_e2sg_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
-         );
+      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_e2sg_ip : IF (g_sim=FALSE OR (g_sim=TRUE AND g_sim_level=0)) AND (g_technology=c_tech_arria10_e2sg AND g_variant="IP") GENERATE
 
+  -----------------------------------------------------------------------------
+  -- IP variants for > 18 bit and <= 27 bit
+  -----------------------------------------------------------------------------
+
+  gen_ip_arria10_e1sg_ip_27b : IF g_variant="IP" AND g_technology=c_tech_arria10_e1sg AND c_dsp_dat_w > c_dsp_mult_18_w AND c_dsp_dat_w <= c_dsp_mult_27_w 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);
+    ar <= RESIZE_SVEC(in_ar, c_dsp_mult_27_w);
+    ai <= RESIZE_SVEC(in_ai, c_dsp_mult_27_w);
+    br <= RESIZE_SVEC(in_br, c_dsp_mult_27_w);
+    bi <= RESIZE_SVEC(in_bi, c_dsp_mult_27_w) WHEN g_conjugate_b=FALSE ELSE TO_SVEC(-TO_SINT(in_bi), c_dsp_mult_27_w);
+
+    --u0 : ip_arria10_e1sg_complex_mult_27b
+    --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;
 
-    u0 : ip_arria10_e2sg_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
-         );
+  gen_ip_arria10_e2sg_ip_27b : IF g_variant="IP" AND g_technology=c_tech_arria10_e2sg AND c_dsp_dat_w > c_dsp_mult_18_w AND c_dsp_dat_w <= c_dsp_mult_27_w GENERATE
+    -- Adapt DSP input widths
+    ar <= RESIZE_SVEC(in_ar, c_dsp_mult_27_w);
+    ai <= RESIZE_SVEC(in_ai, c_dsp_mult_27_w);
+    br <= RESIZE_SVEC(in_br, c_dsp_mult_27_w);
+    bi <= RESIZE_SVEC(in_bi, c_dsp_mult_27_w) WHEN g_conjugate_b=FALSE ELSE TO_SVEC(-TO_SINT(in_bi), c_dsp_mult_27_w);
+
+    --u0 : ip_arria10_e2sg_complex_mult_27b
+    --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;
 
-  -------------------------------------------------------------------------------
-  -- Model: forward concatenated inputs to the 'result' output
-  -- 
-  -- Example:
-  --                                    ______ 
-  -- Input B.real (in_br) = 0x1111 --> |      |
-  --        .imag (in_bi) = 0xBBBB --> |      |
-  --                                   | mult | --> Output result.real = 0x00000000
-  -- Input A.real (in_ar) = 0x0000 --> |      |                  .imag = 0xBBBBAAAA
-  --        .imag (in_ai) = 0xAAAA --> |______|
-  -- 
-  -- Note: this model is synthsizable as well.
-  -- 
-  -------------------------------------------------------------------------------
-  gen_sim_level_1 : IF g_sim=TRUE AND g_sim_level=1 GENERATE --FIXME: g_sim required? This is synthesizable.
-
-    result_re_undelayed <= in_br & in_ar;
-    result_im_undelayed <= in_bi & in_ai;
-
-    u_common_pipeline_re : entity common_lib.common_pipeline
-    generic map (
-      g_pipeline  => 3,
-      g_in_dat_w  => g_in_b_w+g_in_a_w,
-      g_out_dat_w => g_out_p_w
+  -----------------------------------------------------------------------------
+  -- RTL variants that can infer multipliers for a technology, fits all widths
+  -----------------------------------------------------------------------------
+  gen_ip_stratixiv_rtl : IF g_variant="RTL" AND g_technology=c_tech_stratixiv GENERATE
+    u0 : ip_stratixiv_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 (
-      clk     => clk,
-      in_dat  => result_re_undelayed,
-      out_dat => result_re
+    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;
 
-    u_common_pipeline_im : entity common_lib.common_pipeline
-    generic map (
-      g_pipeline  => 3,
-      g_in_dat_w  => g_in_b_w+g_in_a_w,
-      g_out_dat_w => g_out_p_w
+  -- RTL variant is the same for unb2, unb2a and unb2b
+  gen_ip_arria10_rtl : IF g_variant="RTL" AND (g_technology=c_tech_arria10 OR
+                                               g_technology=c_tech_arria10_e3sge3 OR
+                                               g_technology=c_tech_arria10_e1sg OR
+                                               g_technology=c_tech_arria10_e2sg) 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 (
-      clk     => clk,
-      in_dat  => result_im_undelayed,
-      out_dat => result_im
+    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;
+
+  -- RTL variant is the same for unb2, unb2a and unb2b
+  gen_ip_arria10_rtl_canonical : IF g_variant="RTL_C" AND (g_technology=c_tech_arria10 OR
+                                                           g_technology=c_tech_arria10_e3sge3 OR
+                                                           g_technology=c_tech_arria10_e1sg OR
+                                                           g_technology=c_tech_arria10_e2sg) GENERATE
+    -- support g_conjugate_b
+    bi <= in_bi WHEN g_conjugate_b=FALSE ELSE TO_SVEC(-TO_SINT(in_bi), g_in_b_w);
 
+    u0 : ip_arria10_complex_mult_rtl_canonical
+    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_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      => bi,
+      result_re  => result_re,
+      result_im  => result_im
+    );
   END GENERATE;
 
 end str;