-- altera vhdl_input_version vhdl_2008
-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html)

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity mult is
        generic (
            PIPELINE_STAGES : natural := 1;
            DATAA_WIDTH     : natural;
            DATAB_WIDTH     : natural;
            DATAB_CONST     : boolean := FALSE
        );
        port (
            clk     : in std_logic;
            reset   : in std_logic;
            dataa   : in std_logic_vector(DATAA_WIDTH-1 downto 0);
            datab   : in std_logic_vector(DATAB_WIDTH-1 downto 0);
            result  : out std_logic_vector(DATAA_WIDTH+DATAB_WIDTH-1 downto 0)
        );
end entity;

architecture arch of mult is
    
    type PIPELINE_STAGE_ARRAY is array (0 to PIPELINE_STAGES-1) of std_logic_vector(DATAA_WIDTH+DATAB_WIDTH-1 downto 0);
    
    signal pipeline : PIPELINE_STAGE_ARRAY := (others => (others => '0'));
    
begin
    
    assert (PIPELINE_STAGES >= 1) report "MULT has to have at least 1 pipeline stage" severity FAILURE;
    
    result  <= pipeline(PIPELINE_STAGES-1);
    
    sync_prc : process(clk)
    begin
        if rising_edge(clk) then
            if (reset = '1') then
                pipeline    <= (others => (others => '0'));
            else
                pipeline(0) <= std_logic_vector(unsigned(dataa) * unsigned(datab));
                if (PIPELINE_STAGES > 1) then
                    for i in 1 to PIPELINE_STAGES-1 loop
                        pipeline(i) <= pipeline(i-1);
                    end loop;
                end if;
            end if;
        end if;
    end process;

end architecture;