You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
295 lines
8.2 KiB
295 lines
8.2 KiB
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 64-bit 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;
|
|
|