diff --git a/libraries/technology/ip_arria10/complex_mult/README.txt b/libraries/technology/ip_arria10/complex_mult/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6884ec9c599bf7d01ffed812c8a3a2a9bbb09398
--- /dev/null
+++ b/libraries/technology/ip_arria10/complex_mult/README.txt
@@ -0,0 +1,55 @@
+README.txt for $RADIOHDL/libraries/technology/ip_arria10/complex_mult
+
+1) Porting
+2) IP component
+3) Compilation, simulation and verification
+4) Synthesis
+5) Remarks
+
+
+1) Porting
+
+The complex_mult IP was ported manually from Quartus v11.1 for Stratix IV  to Quartus 15.0 for Arria10 by creating it in Qsys using
+the same parameter settings.
+
+
+2) IP component
+
+The generated IP is not kept in SVN, only the Qsys source file:
+
+  ip_arria10_complex_mult.qsys
+
+Therefore first the IP needs to be generated using:
+
+  ./generate_ip.sh
+  
+
+3) Compilation, simulation and verification
+
+The generated IP also contains a msim_setup.tcl file that was used to manually create:
+
+  compile_ip.tcl
+  
+This compile_ip.tcl is in the hdllib.cfg and gets compiled before the other code.
+
+
+4) Synthesis
+
+No synthesis trials were done, because this will implicitely be done when the IP is used in a design. The QIP file:
+
+  generated/ip_arria10_complex_mult.qip
+
+is included in the hdllib.cfg and contains what is needed to synthesize the IP.
+
+
+5) Remarks
+
+a) Use generated IP specific library clause name
+
+  The generated ip_arria10_<lib_name>.vhd uses an IP specific library name. Therefore the hdllib.cfg uses the IP
+  specific library as library clause name to make it known:
+  
+    hdl_lib_name = ip_arria10_<lib_name>
+    hdl_library_clause_name = ip_arria10_<lib_name>_<ip_specific>
+    
+ 
\ No newline at end of file
diff --git a/libraries/technology/ip_arria10/complex_mult/compile_ip.tcl b/libraries/technology/ip_arria10/complex_mult/compile_ip.tcl
new file mode 100644
index 0000000000000000000000000000000000000000..3605025500e6c982ffd70b0fa128c6ad8f6bef76
--- /dev/null
+++ b/libraries/technology/ip_arria10/complex_mult/compile_ip.tcl
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (C) 2015
+# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+# JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#------------------------------------------------------------------------------
+
+# This file is based on generated file generated/sim/mentor/msim_setup.tcl
+# - the values for modelsim_search_libraries key in the hdllib.cfg follow from altera libraries vmap section in the msim_setup.tcl
+# - vmap for the IP specific libraries and compile all IP source files into those libraries similar as in the msim_setup.tcl
+# - replace QSYS_SIMDIR by IP_DIR
+
+set IP_DIR   "$env(RADIOHDL)/libraries/technology/ip_arria10/complex_mult/generated/sim"
+
+#vlib ./work/         ;# Assume library work already exists
+
+vmap ip_arria10_complex_mult_altmult_complex_150 ./work/
+
+  vlog "$IP_DIR/../altmult_complex_150/sim/ip_arria10_complex_mult_altmult_complex_150_35pzchy.v" -work ip_arria10_complex_mult_altmult_complex_150
+  vcom "$IP_DIR/ip_arria10_complex_mult.vhd"                                                                                                       
diff --git a/libraries/technology/ip_arria10/complex_mult/generate_ip.sh b/libraries/technology/ip_arria10/complex_mult/generate_ip.sh
new file mode 100755
index 0000000000000000000000000000000000000000..32f0f2c0987bdb4e93d39198bb6e34564e13cf27
--- /dev/null
+++ b/libraries/technology/ip_arria10/complex_mult/generate_ip.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 2014                                                        
+# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+# JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>           
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands                             
+#                                                                           
+# This program is free software: you can redistribute it and/or modify      
+# it under the terms of the GNU General Public License as published by      
+# the Free Software Foundation, either version 3 of the License, or         
+# (at your option) any later version.                                       
+#                                                                           
+# This program is distributed in the hope that it will be useful,           
+# but WITHOUT ANY WARRANTY; without even the implied warranty of            
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             
+# GNU General Public License for more details.                              
+#                                                                           
+# You should have received a copy of the GNU General Public License         
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.     
+#
+# -------------------------------------------------------------------------- #
+#
+# Purpose: Generate IP with Qsys
+# Description:
+#   Generate the IP in a separate generated/ subdirectory.
+#
+# Usage:
+#
+#   ./generate_ip.sh
+#
+
+# Tool settings for selected target "unb2" with arria10
+. ${RADIOHDL}/tools/quartus/set_quartus unb2
+
+#qsys-generate --help
+
+# Only generate the source IP
+# - use --synthesis=VHDL to have top level in VHDL similar as with MegaWizard
+qsys-generate ip_arria10_complex_mult.qsys \
+              --synthesis=VHDL \
+              --simulation=VHDL \
+              --output-directory=generated \
+              --allow-mixed-language-simulation
diff --git a/libraries/technology/ip_arria10/complex_mult/hdllib.cfg b/libraries/technology/ip_arria10/complex_mult/hdllib.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..d6aaa13158b29a774e47bf257b8efffcc7e8d5a3
--- /dev/null
+++ b/libraries/technology/ip_arria10/complex_mult/hdllib.cfg
@@ -0,0 +1,16 @@
+hdl_lib_name = ip_arria10_complex_mult
+hdl_library_clause_name = ip_arria10_complex_mult_altmult_complex_150
+hdl_lib_uses_synth = 
+hdl_lib_uses_sim = 
+
+hdl_lib_technology = ip_arria10
+
+modelsim_compile_ip_files =
+    $RADIOHDL/libraries/technology/ip_arria10/complex_mult/compile_ip.tcl
+
+synth_files =
+    
+test_bench_files = 
+
+quartus_qip_files =
+    generated/ip_arria10_complex_mult.qip
diff --git a/libraries/technology/ip_arria10/complex_mult/ip_arria10_complex_mult.qsys b/libraries/technology/ip_arria10/complex_mult/ip_arria10_complex_mult.qsys
new file mode 100644
index 0000000000000000000000000000000000000000..7d4a9cec11f2fee08a1d9f2d86792fb138d7cf6e
--- /dev/null
+++ b/libraries/technology/ip_arria10/complex_mult/ip_arria10_complex_mult.qsys
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<system name="$${FILENAME}">
+ <component
+   name="$${FILENAME}"
+   displayName="$${FILENAME}"
+   version="1.0"
+   description=""
+   tags="INTERNAL_COMPONENT=true"
+   categories="" />
+ <parameter name="bonusData"><![CDATA[bonusData 
+{
+   element $${FILENAME}
+   {
+   }
+   element altmult_complex_0
+   {
+      datum _sortIndex
+      {
+         value = "0";
+         type = "int";
+      }
+   }
+}
+]]></parameter>
+ <parameter name="clockCrossingAdapter" value="HANDSHAKE" />
+ <parameter name="device" value="10AS066H2F34E1SG" />
+ <parameter name="deviceFamily" value="Arria 10" />
+ <parameter name="deviceSpeedGrade" value="1" />
+ <parameter name="fabricMode" value="QSYS" />
+ <parameter name="generateLegacySim" value="false" />
+ <parameter name="generationId" value="0" />
+ <parameter name="globalResetBus" value="false" />
+ <parameter name="hdlLanguage" value="VERILOG" />
+ <parameter name="hideFromIPCatalog" value="true" />
+ <parameter name="lockedInterfaceDefinition" value="" />
+ <parameter name="maxAdditionalLatency" value="1" />
+ <parameter name="projectName" value="" />
+ <parameter name="sopcBorderPoints" value="false" />
+ <parameter name="systemHash" value="0" />
+ <parameter name="testBenchDutName" value="" />
+ <parameter name="timeStamp" value="0" />
+ <parameter name="useTestBenchNamingPattern" value="false" />
+ <instanceScript></instanceScript>
+ <interface
+   name="complex_input"
+   internal="altmult_complex_0.complex_input"
+   type="conduit"
+   dir="end">
+  <port name="dataa_real" internal="dataa_real" />
+  <port name="dataa_imag" internal="dataa_imag" />
+  <port name="datab_real" internal="datab_real" />
+  <port name="datab_imag" internal="datab_imag" />
+  <port name="clock" internal="clock" />
+  <port name="aclr" internal="aclr" />
+  <port name="ena" internal="ena" />
+ </interface>
+ <interface
+   name="complex_output"
+   internal="altmult_complex_0.complex_output"
+   type="conduit"
+   dir="end">
+  <port name="result_real" internal="result_real" />
+  <port name="result_imag" internal="result_imag" />
+ </interface>
+ <module
+   name="altmult_complex_0"
+   kind="altmult_complex"
+   version="15.0"
+   enabled="1"
+   autoexport="1">
+  <parameter name="CBX_AUTO_BLACKBOX" value="ALL" />
+  <parameter name="DEVICE_FAMILY" value="Arria 10" />
+  <parameter name="GUI_DYNAMIC_COMPLEX" value="false" />
+  <parameter name="GUI_USE_ACLR" value="true" />
+  <parameter name="GUI_USE_CLKEN" value="true" />
+  <parameter name="IMPLEMENTATION_STYLE" value="AUTO" />
+  <parameter name="PIPELINE" value="3" />
+  <parameter name="REPRESENTATION_A" value="1" />
+  <parameter name="REPRESENTATION_B" value="1" />
+  <parameter name="WIDTH_A" value="18" />
+  <parameter name="WIDTH_B" value="18" />
+  <parameter name="WIDTH_RESULT" value="36" />
+ </module>
+ <interconnectRequirement for="$system" name="qsys_mm.clockCrossingAdapter" value="HANDSHAKE" />
+ <interconnectRequirement for="$system" name="qsys_mm.enableEccProtection" value="FALSE" />
+ <interconnectRequirement for="$system" name="qsys_mm.insertDefaultSlave" value="FALSE" />
+ <interconnectRequirement for="$system" name="qsys_mm.maxAdditionalLatency" value="1" />
+</system>
diff --git a/libraries/technology/ip_arria10/complex_mult_rtl/hdllib.cfg b/libraries/technology/ip_arria10/complex_mult_rtl/hdllib.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..e001e9caee5365c4b340ed56e617043bae7005f8
--- /dev/null
+++ b/libraries/technology/ip_arria10/complex_mult_rtl/hdllib.cfg
@@ -0,0 +1,11 @@
+hdl_lib_name = ip_arria10_complex_mult_rtl	
+hdl_library_clause_name = ip_arria10_complex_mult_rtl_lib
+hdl_lib_uses_synth = 
+hdl_lib_uses_sim = 
+
+hdl_lib_technology = ip_arria10
+
+synth_files =
+    ip_arria10_complex_mult_rtl.vhd
+    
+test_bench_files =
diff --git a/libraries/technology/ip_arria10/complex_mult_rtl/ip_arria10_complex_mult_rtl.vhd b/libraries/technology/ip_arria10/complex_mult_rtl/ip_arria10_complex_mult_rtl.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..5d480da7a8781275957ba261ac3468669cb15264
--- /dev/null
+++ b/libraries/technology/ip_arria10/complex_mult_rtl/ip_arria10_complex_mult_rtl.vhd
@@ -0,0 +1,260 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2009
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+
+--
+-- Function: Signed complex multiply
+--   p = a * b       when g_conjugate_b = FALSE
+--     = (ar + j ai) * (br + j bi)
+--     =  ar*br - ai*bi + j ( ar*bi + ai*br)
+--
+--   p = a * conj(b) when g_conjugate_b = TRUE
+--     = (ar + j ai) * (br - j bi)
+--     =  ar*br + ai*bi + j (-ar*bi + ai*br)
+--
+-- Architectures:
+-- . rtl          : uses RTL to have all registers in one clocked process
+--
+
+ENTITY ip_arria10_complex_mult_rtl IS
+  GENERIC (
+    g_in_a_w           : POSITIVE;
+    g_in_b_w           : POSITIVE;
+    g_out_p_w          : POSITIVE;          -- default use g_out_p_w = g_in_a_w+g_in_b_w = c_prod_w
+    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 ip_arria10_complex_mult_rtl;
+
+ARCHITECTURE str OF ip_arria10_complex_mult_rtl IS
+
+  FUNCTION RESIZE_NUM(s : SIGNED; w : NATURAL) RETURN SIGNED IS
+  BEGIN
+    -- extend sign bit or keep LS part
+    IF w>s'LENGTH THEN
+      RETURN RESIZE(s, w);                    -- extend sign bit
+    ELSE
+      RETURN SIGNED(RESIZE(UNSIGNED(s), w));  -- keep LSbits (= vec[w-1:0])
+    END IF;
+  END;
+
+  CONSTANT c_prod_w     : NATURAL := g_in_a_w+g_in_b_w;
+  CONSTANT c_sum_w      : NATURAL := c_prod_w+1;
+
+--  CONSTANT c_re_add_sub : STRING := sel_a_b(g_conjugate_b, "ADD", "SUB");
+--  CONSTANT c_im_add_sub : STRING := sel_a_b(g_conjugate_b, "SUB", "ADD");
+
+  -- registers
+  SIGNAL reg_ar         : SIGNED(g_in_a_w-1 DOWNTO 0);
+  SIGNAL reg_ai         : SIGNED(g_in_a_w-1 DOWNTO 0);
+  SIGNAL reg_br         : SIGNED(g_in_b_w-1 DOWNTO 0);
+  SIGNAL reg_bi         : SIGNED(g_in_b_w-1 DOWNTO 0);
+  SIGNAL reg_prod_ar_br : SIGNED(c_prod_w-1 DOWNTO 0);  -- re
+  SIGNAL reg_prod_ai_bi : SIGNED(c_prod_w-1 DOWNTO 0);
+  SIGNAL reg_prod_ai_br : SIGNED(c_prod_w-1 DOWNTO 0);  -- im
+  SIGNAL reg_prod_ar_bi : SIGNED(c_prod_w-1 DOWNTO 0);
+  SIGNAL reg_sum_re     : SIGNED(c_sum_w-1 DOWNTO 0);
+  SIGNAL reg_sum_im     : SIGNED(c_sum_w-1 DOWNTO 0);
+  SIGNAL reg_result_re  : SIGNED(g_out_p_w-1 DOWNTO 0);
+  SIGNAL reg_result_im  : SIGNED(g_out_p_w-1 DOWNTO 0);
+
+  -- combinatorial
+  SIGNAL nxt_ar         : SIGNED(g_in_a_w-1 DOWNTO 0);
+  SIGNAL nxt_ai         : SIGNED(g_in_a_w-1 DOWNTO 0);
+  SIGNAL nxt_br         : SIGNED(g_in_b_w-1 DOWNTO 0);
+  SIGNAL nxt_bi         : SIGNED(g_in_b_w-1 DOWNTO 0);
+  SIGNAL nxt_prod_ar_br : SIGNED(c_prod_w-1 DOWNTO 0);  -- re
+  SIGNAL nxt_prod_ai_bi : SIGNED(c_prod_w-1 DOWNTO 0);
+  SIGNAL nxt_prod_ai_br : SIGNED(c_prod_w-1 DOWNTO 0);  -- im
+  SIGNAL nxt_prod_ar_bi : SIGNED(c_prod_w-1 DOWNTO 0);
+  SIGNAL nxt_sum_re     : SIGNED(c_sum_w-1 DOWNTO 0);
+  SIGNAL nxt_sum_im     : SIGNED(c_sum_w-1 DOWNTO 0);
+  SIGNAL nxt_result_re  : SIGNED(g_out_p_w-1 DOWNTO 0);
+  SIGNAL nxt_result_im  : SIGNED(g_out_p_w-1 DOWNTO 0);
+
+  -- the active signals
+  SIGNAL ar             : SIGNED(g_in_a_w-1 DOWNTO 0);
+  SIGNAL ai             : SIGNED(g_in_a_w-1 DOWNTO 0);
+  SIGNAL br             : SIGNED(g_in_b_w-1 DOWNTO 0);
+  SIGNAL bi             : SIGNED(g_in_b_w-1 DOWNTO 0);
+  SIGNAL prod_ar_br     : SIGNED(c_prod_w-1 DOWNTO 0);  -- re
+  SIGNAL prod_ai_bi     : SIGNED(c_prod_w-1 DOWNTO 0);
+  SIGNAL prod_ai_br     : SIGNED(c_prod_w-1 DOWNTO 0);  -- im
+  SIGNAL prod_ar_bi     : SIGNED(c_prod_w-1 DOWNTO 0);
+  SIGNAL sum_re         : SIGNED(c_sum_w-1 DOWNTO 0);
+  SIGNAL sum_im         : SIGNED(c_sum_w-1 DOWNTO 0);
+
+BEGIN
+
+  ------------------------------------------------------------------------------
+  -- Registers
+  ------------------------------------------------------------------------------
+
+  -- Put all potential registers in a single process for optimal DSP inferrence
+  -- Use rst only if it is supported by the DSP primitive, else leave it at '0'
+  p_reg : PROCESS (rst, clk)
+  BEGIN
+    IF rising_edge(clk) THEN
+      IF rst='1' THEN
+        reg_ar         <= (OTHERS=>'0');
+        reg_ai         <= (OTHERS=>'0');
+        reg_br         <= (OTHERS=>'0');
+        reg_bi         <= (OTHERS=>'0');
+        reg_prod_ar_br <= (OTHERS=>'0');
+        reg_prod_ai_bi <= (OTHERS=>'0');
+        reg_prod_ai_br <= (OTHERS=>'0');
+        reg_prod_ar_bi <= (OTHERS=>'0');
+        reg_sum_re     <= (OTHERS=>'0');
+        reg_sum_im     <= (OTHERS=>'0');
+        reg_result_re  <= (OTHERS=>'0');
+        reg_result_im  <= (OTHERS=>'0');
+      ELSIF clken='1' THEN
+        reg_ar         <= nxt_ar;          -- inputs
+        reg_ai         <= nxt_ai;
+        reg_br         <= nxt_br;
+        reg_bi         <= nxt_bi;
+        reg_prod_ar_br <= nxt_prod_ar_br;  -- products for re
+        reg_prod_ai_bi <= nxt_prod_ai_bi;
+        reg_prod_ai_br <= nxt_prod_ai_br;  -- products for im
+        reg_prod_ar_bi <= nxt_prod_ar_bi;
+        reg_sum_re     <= nxt_sum_re;      -- sum
+        reg_sum_im     <= nxt_sum_im;
+        reg_result_re  <= nxt_result_re;   -- result sum after optional register stage
+        reg_result_im  <= nxt_result_im;
+      END IF;
+    END IF;
+  END PROCESS;
+
+  ------------------------------------------------------------------------------
+  -- Inputs
+  ------------------------------------------------------------------------------
+
+  nxt_ar <= SIGNED(in_ar);
+  nxt_ai <= SIGNED(in_ai);
+  nxt_br <= SIGNED(in_br);
+  nxt_bi <= SIGNED(in_bi);
+
+  no_input_reg : IF g_pipeline_input=0 GENERATE   -- wired
+    ar <= nxt_ar;
+    ai <= nxt_ai;
+    br <= nxt_br;
+    bi <= nxt_bi;
+  END GENERATE;
+
+  gen_input_reg : IF g_pipeline_input>0 GENERATE  -- register input
+    ar <= reg_ar;
+    ai <= reg_ai;
+    br <= reg_br;
+    bi <= reg_bi;
+  END GENERATE;
+
+
+  ------------------------------------------------------------------------------
+  -- Products
+  ------------------------------------------------------------------------------
+
+  nxt_prod_ar_br <= ar * br;  -- products for re
+  nxt_prod_ai_bi <= ai * bi;
+  nxt_prod_ai_br <= ai * br;  -- products for im
+  nxt_prod_ar_bi <= ar * bi;
+
+  no_product_reg : IF g_pipeline_product=0 GENERATE   -- wired
+    prod_ar_br <= nxt_prod_ar_br;
+    prod_ai_bi <= nxt_prod_ai_bi;
+    prod_ai_br <= nxt_prod_ai_br;
+    prod_ar_bi <= nxt_prod_ar_bi;
+  END GENERATE;
+  gen_product_reg : IF g_pipeline_product>0 GENERATE  -- register
+    prod_ar_br <= reg_prod_ar_br;
+    prod_ai_bi <= reg_prod_ai_bi;
+    prod_ai_br <= reg_prod_ai_br;
+    prod_ar_bi <= reg_prod_ar_bi;
+  END GENERATE;
+
+
+  ------------------------------------------------------------------------------
+  -- Sum
+  ------------------------------------------------------------------------------
+
+  -- Re
+  -- . "ADD" for a*conj(b) : ar*br + ai*bi
+  -- . "SUB" for a*b       : ar*br - ai*bi
+  gen_re_add : IF g_conjugate_b GENERATE
+    nxt_sum_re <= RESIZE_NUM(prod_ar_br, c_sum_w) + prod_ai_bi;
+  END GENERATE;
+  gen_re_sub : IF NOT g_conjugate_b GENERATE
+    nxt_sum_re <= RESIZE_NUM(prod_ar_br, c_sum_w) - prod_ai_bi;
+  END GENERATE;
+
+  -- Im
+  -- . "ADD" for a*b       : ai*br + ar*bi
+  -- . "SUB" for a*conj(b) : ai*br - ar*bi
+  gen_im_add : IF NOT g_conjugate_b GENERATE
+    nxt_sum_im <= RESIZE_NUM(prod_ai_br, c_sum_w) + prod_ar_bi;
+  END GENERATE;
+  gen_im_sub : IF g_conjugate_b GENERATE
+    nxt_sum_im <= RESIZE_NUM(prod_ai_br, c_sum_w) - prod_ar_bi;
+  END GENERATE;
+
+
+  no_adder_reg : IF g_pipeline_adder=0 GENERATE   -- wired
+    sum_re <= nxt_sum_re;
+    sum_im <= nxt_sum_im;
+  END GENERATE;
+  gen_adder_reg : IF g_pipeline_adder>0 GENERATE  -- register
+    sum_re <= reg_sum_re;
+    sum_im <= reg_sum_im;
+  END GENERATE;
+
+  ------------------------------------------------------------------------------
+  -- Result sum after optional rounding
+  ------------------------------------------------------------------------------
+
+  nxt_result_re <= RESIZE_NUM(sum_re, g_out_p_w);
+  nxt_result_im <= RESIZE_NUM(sum_im, g_out_p_w);
+
+  no_result_reg : IF g_pipeline_output=0 GENERATE   -- wired
+    result_re <= STD_LOGIC_VECTOR(nxt_result_re);
+    result_im <= STD_LOGIC_VECTOR(nxt_result_im);
+  END GENERATE;
+  gen_result_reg : IF g_pipeline_output>0 GENERATE  -- register
+    result_re <= STD_LOGIC_VECTOR(reg_result_re);
+    result_im <= STD_LOGIC_VECTOR(reg_result_im);
+  END GENERATE;
+
+END ARCHITECTURE;