


library ieee;




use ieee.std_logic_1164.all;




use ieee.numeric_std.all;








library work;




use work.common.all;








library unisim;




use unisim.vcomponents.all;








 Signed 33b x 33b multiplier giving 64bit product, with no addend.








entity multiply_32s is




port (




clk : in std_logic;




stall : in std_ulogic;








m_in : in MultiplyInputType;




m_out : out MultiplyOutputType




);




end entity multiply_32s;








architecture behaviour of multiply_32s is




signal clocken : std_ulogic;




signal data1 : std_ulogic_vector(52 downto 0);




signal data2 : std_ulogic_vector(34 downto 0);




signal m00_p, m01_p : std_ulogic_vector(47 downto 0);




signal m00_pc : std_ulogic_vector(47 downto 0);




signal m10_p, m11_p : std_ulogic_vector(47 downto 0);




signal m10_pc : std_ulogic_vector(47 downto 0);




signal p0_pat, p0_patb : std_ulogic;




signal p1_pat, p1_patb : std_ulogic;




signal product_lo : std_ulogic_vector(22 downto 0);








begin




 sign extend if signed




data1(31 downto 0) <= m_in.data1(31 downto 0);




data1(52 downto 32) <= (others => m_in.is_signed and m_in.data1(31));




data2(31 downto 0) <= m_in.data2(31 downto 0);




data2(34 downto 32) <= (others => m_in.is_signed and m_in.data2(31));








clocken <= m_in.valid and not stall;








m00: DSP48E1




generic map (




ACASCREG => 0,




ALUMODEREG => 0,




AREG => 0,




BCASCREG => 0,




BREG => 0,




CARRYINREG => 0,




CARRYINSELREG => 0,




CREG => 0,




INMODEREG => 0,




MREG => 0,




OPMODEREG => 0,




PREG => 0




)




port map (




A => "0000000" & data1(22 downto 0),




ACIN => (others => '0'),




ALUMODE => "0000",




B => '0' & data2(16 downto 0),




BCIN => (others => '0'),




C => (others => '0'),




CARRYCASCIN => '0',




CARRYIN => '0',




CARRYINSEL => "000",




CEA1 => '0',




CEA2 => '0',




CEAD => '0',




CEALUMODE => '0',




CEB1 => '0',




CEB2 => '0',




CEC => '0',




CECARRYIN => '0',




CECTRL => '0',




CED => '0',




CEINMODE => '0',




CEM => '0',




CEP => '0',




CLK => clk,




D => (others => '0'),




INMODE => "00000",




MULTSIGNIN => '0',




OPMODE => "0110101",




P => m00_p,




PCIN => (others => '0'),




PCOUT => m00_pc,




RSTA => '0',




RSTALLCARRYIN => '0',




RSTALUMODE => '0',




RSTB => '0',




RSTC => '0',




RSTCTRL => '0',




RSTD => '0',




RSTINMODE => '0',




RSTM => '0',




RSTP => '0'




);








m01: DSP48E1




generic map (




ACASCREG => 0,




ALUMODEREG => 0,




AREG => 0,




BCASCREG => 0,




BREG => 0,




CARRYINREG => 0,




CARRYINSELREG => 0,




CREG => 0,




INMODEREG => 0,




MREG => 0,




OPMODEREG => 0,




PREG => 0




)




port map (




A => "0000000" & data1(22 downto 0),




ACIN => (others => '0'),




ALUMODE => "0000",




B => data2(34 downto 17),




BCIN => (others => '0'),




C => (others => '0'),




CARRYCASCIN => '0',




CARRYIN => '0',




CARRYINSEL => "000",




CEA1 => '0',




CEA2 => '0',




CEAD => '0',




CEALUMODE => '0',




CEB1 => '0',




CEB2 => '0',




CEC => '0',




CECARRYIN => '0',




CECTRL => '0',




CED => '0',




CEINMODE => '0',




CEM => '0',




CEP => '0',




CLK => clk,




D => (others => '0'),




INMODE => "00000",




MULTSIGNIN => '0',




OPMODE => "1010101",




P => m01_p,




PCIN => m00_pc,




RSTA => '0',




RSTALLCARRYIN => '0',




RSTALUMODE => '0',




RSTB => '0',




RSTC => '0',




RSTCTRL => '0',




RSTD => '0',




RSTINMODE => '0',




RSTM => '0',




RSTP => '0'




);








m10: DSP48E1




generic map (




ACASCREG => 0,




ALUMODEREG => 0,




AREG => 0,




BCASCREG => 0,




BREG => 0,




CARRYINREG => 0,




CARRYINSELREG => 0,




CREG => 1,




INMODEREG => 0,




MASK => x"fffffffe00ff",




OPMODEREG => 0,




PREG => 0,




USE_PATTERN_DETECT => "PATDET"




)




port map (




A => data1(52 downto 23),




ACIN => (others => '0'),




ALUMODE => "0000",




B => '0' & data2(16 downto 0),




BCIN => (others => '0'),




C => std_ulogic_vector(resize(signed(m01_p(38 downto 6)), 48)),




CARRYCASCIN => '0',




CARRYIN => '0',




CARRYINSEL => "000",




CEA1 => '0',




CEA2 => '0',




CEAD => '0',




CEALUMODE => '0',




CEB1 => '0',




CEB2 => '0',




CEC => clocken,




CECARRYIN => '0',




CECTRL => '0',




CED => '0',




CEINMODE => '0',




CEM => clocken,




CEP => '0',




CLK => clk,




D => (others => '0'),




INMODE => "00000",




MULTSIGNIN => '0',




OPMODE => "0110101",




P => m10_p,




PATTERNDETECT => p0_pat,




PATTERNBDETECT => p0_patb,




PCIN => (others => '0'),




PCOUT => m10_pc,




RSTA => '0',




RSTALLCARRYIN => '0',




RSTALUMODE => '0',




RSTB => '0',




RSTC => '0',




RSTCTRL => '0',




RSTD => '0',




RSTINMODE => '0',




RSTM => '0',




RSTP => '0'




);








m11: DSP48E1




generic map (




ACASCREG => 0,




ALUMODEREG => 0,




AREG => 0,




BCASCREG => 0,




BREG => 0,




CARRYINREG => 0,




CARRYINSELREG => 0,




CREG => 0,




INMODEREG => 0,




MASK => x"fffffc000000",




OPMODEREG => 0,




PREG => 0,




USE_PATTERN_DETECT => "PATDET"




)




port map (




A => data1(52 downto 23),




ACIN => (others => '0'),




ALUMODE => "0000",




B => data2(34 downto 17),




BCIN => (others => '0'),




C => (others => '0'),




CARRYCASCIN => '0',




CARRYIN => '0',




CARRYINSEL => "000",




CEA1 => '0',




CEA2 => '0',




CEAD => '0',




CEALUMODE => '0',




CEB1 => '0',




CEB2 => '0',




CEC => '0',




CECARRYIN => '0',




CECTRL => '0',




CED => '0',




CEINMODE => '0',




CEM => clocken,




CEP => '0',




CLK => clk,




D => (others => '0'),




INMODE => "00000",




MULTSIGNIN => '0',




OPMODE => "1010101",




P => m11_p,




PATTERNDETECT => p1_pat,




PATTERNBDETECT => p1_patb,




PCIN => m10_pc,




RSTA => '0',




RSTALLCARRYIN => '0',




RSTALUMODE => '0',




RSTB => '0',




RSTC => '0',




RSTCTRL => '0',




RSTD => '0',




RSTINMODE => '0',




RSTM => '0',




RSTP => '0'




);








m_out.result(127 downto 64) <= (others => '0');




m_out.result(63 downto 40) <= m11_p(23 downto 0);




m_out.result(39 downto 23) <= m10_p(16 downto 0);




m_out.result(22 downto 0) <= product_lo;








m_out.overflow <= not ((p0_pat and p1_pat) or (p0_patb and p1_patb));








process(clk)




begin




if rising_edge(clk) and stall = '0' then




m_out.valid <= m_in.valid;




product_lo <= m01_p(5 downto 0) & m00_p(16 downto 0);




end if;




end process;








end architecture behaviour;
