diff --git a/libraries/base/common_mult/hdllib.cfg b/libraries/base/common_mult/hdllib.cfg index dc273fac62de7772338c60f206e0944e3a54d04a..1f94ac98d096cf3ff0dc7537f500e77628de5037 100644 --- a/libraries/base/common_mult/hdllib.cfg +++ b/libraries/base/common_mult/hdllib.cfg @@ -6,6 +6,7 @@ hdl_lib_technology = synth_files = src/vhdl/common_mult.vhd + src/vhdl/common_mult_add.vhd # two input multiply and add, copied from LOFAR1 RSP src/vhdl/common_mult_add2.vhd src/vhdl/common_mult_add4.vhd src/vhdl/common_complex_mult.vhd diff --git a/libraries/base/common_mult/src/vhdl/common_mult_add.vhd b/libraries/base/common_mult/src/vhdl/common_mult_add.vhd new file mode 100644 index 0000000000000000000000000000000000000000..4cc9afe95c3676786b0eda051b081e925049610c --- /dev/null +++ b/libraries/base/common_mult/src/vhdl/common_mult_add.vhd @@ -0,0 +1,104 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2011 +-- 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/>. +-- +------------------------------------------------------------------------------- + +-- Copied from LOFAR1 RSP/common by Eric Kooistra on 13 Jan 2021 to use with pfs + +-- Function: Add or subtract of two products a0b0 and a1b1 +-- +-- result = in_a0*in_b0 + in_a1*in_b1 when g_add_sub = "ADD" +-- result = in_a0*in_b0 - in_a1*in_b1 when g_add_sub = "SUB" +-- +-- out_dat = RESIZE(result) +-- +-- Architectures: +-- . rtl : uses RTL to have all registers in one clocked process +-- . virtex : uses Coregen component for the two multipliers and an adder in RTL +-- + +LIBRARY ieee, common_lib; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; +USE common_lib.common_pkg.ALL; + +ENTITY common_mult_add IS + GENERIC ( + g_in_a_w : POSITIVE; + g_in_b_w : POSITIVE; + g_out_dat_w : POSITIVE; + g_add_sub : STRING := "ADD"; + g_pipeline : INTEGER := 3 + ); + PORT ( + clk : IN STD_LOGIC; + rst : IN STD_LOGIC := '0'; + in_a0 : IN STD_LOGIC_VECTOR(g_in_a_w-1 DOWNTO 0); + in_a1 : IN STD_LOGIC_VECTOR(g_in_a_w-1 DOWNTO 0); + in_b0 : IN STD_LOGIC_VECTOR(g_in_b_w-1 DOWNTO 0); + in_b1 : IN STD_LOGIC_VECTOR(g_in_b_w-1 DOWNTO 0); + out_dat : OUT STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0) + ); +BEGIN + -- ASSERT g_pipeline=3 + -- REPORT "pipeline value not supported" + -- SEVERITY FAILURE; +END common_mult_add; + + +ARCHITECTURE rtl OF common_mult_add IS + + CONSTANT c_prod_w : NATURAL := g_in_a_w+g_in_b_w; + CONSTANT c_sum_w : NATURAL := c_prod_w+1; + + SIGNAL in_a0_p : STD_LOGIC_VECTOR(g_in_a_w-1 DOWNTO 0); + SIGNAL in_b0_p : STD_LOGIC_VECTOR(g_in_b_w-1 DOWNTO 0); + SIGNAL in_a1_p : STD_LOGIC_VECTOR(g_in_a_w-1 DOWNTO 0); + SIGNAL in_b1_p : STD_LOGIC_VECTOR(g_in_b_w-1 DOWNTO 0); + SIGNAL prod0 : SIGNED(c_prod_w-1 DOWNTO 0); + SIGNAL prod1 : SIGNED(c_prod_w-1 DOWNTO 0); + SIGNAL result : SIGNED(c_sum_w-1 DOWNTO 0); + SIGNAL nxt_result : SIGNED(c_sum_w-1 DOWNTO 0); + +BEGIN + + out_dat <= STD_LOGIC_VECTOR(RESIZE(result, out_dat'LENGTH)); + + p_clk : PROCESS (clk) + BEGIN + IF rising_edge(clk) THEN + in_a0_p <= in_a0; + in_b0_p <= in_b0; + in_a1_p <= in_a1; + in_b1_p <= in_b1; + prod0 <= SIGNED(in_a0_p) * SIGNED(in_b0_p); + prod1 <= SIGNED(in_a1_p) * SIGNED(in_b1_p); + result <= nxt_result; + END IF; + END PROCESS; + + gen_add : IF g_add_sub = "ADD" GENERATE + nxt_result <= RESIZE(prod0, c_sum_w) + prod1; + END GENERATE; + + gen_sub : IF g_add_sub = "SUB" GENERATE + nxt_result <= RESIZE(prod0, c_sum_w) - prod1; + END GENERATE; + +END rtl;