2024-12-01 22:58:28 +08:00

405 lines
12 KiB
VHDL

-------------------------------------------------------------------------------
-- Copyright (c) 1995/2015 Xilinx, Inc.
-- All Right Reserved.
-------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor : Xilinx
-- \ \ \/ Version : 2015.3
-- \ \ Description : Xilinx Functional Simulation Library Component
-- / / Macro for DSP48
-- /___/ /\ Filename : ADDSUB_MACRO.vhd
-- \ \ / \
-- \___\/\___\
--
-- Revision:
-- 06/06/08 - Initial version.
-- 04/18/11 - 652098 - Fix for latency 0
-- 10/27/14 - Added missing ALUMODEREG (CR 827820).
-- 04/09/15 - 852167 - align with verilog
-- End Revision
----- CELL ADDSUB_MACRO -----
library IEEE;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
library UNISIM;
use UNISIM.vcomponents.all;
library STD;
use STD.TEXTIO.ALL;
entity ADDSUB_MACRO is
generic (
DEVICE : string := "VIRTEX5";
LATENCY : integer := 2;
STYLE : string := "DSP";
WIDTH : integer := 48;
WIDTH_B : integer := 48;
WIDTH_RESULT : integer := 48;
MODEL_TYPE : integer := 0;
VERBOSITY : integer := 0
);
port (
CARRYOUT : out std_logic;
RESULT : out std_logic_vector(WIDTH-1 downto 0);
A : in std_logic_vector(WIDTH-1 downto 0);
ADD_SUB : in std_logic;
B : in std_logic_vector(WIDTH-1 downto 0);
CARRYIN : in std_logic;
CE : in std_logic;
CLK : in std_logic;
RST : in std_logic
);
end entity ADDSUB_MACRO;
architecture addsub of ADDSUB_MACRO is
function CheckDevice (
device : in string
) return boolean is
variable func_val : boolean;
variable Message : LINE;
begin
if (DEVICE = "VIRTEX5" or DEVICE = "VIRTEX6" or DEVICE = "SPARTAN6" or DEVICE = "7SERIES") then
func_val := true;
else
func_val := false;
write( Message, STRING'("Illegal value of Attribute DEVICE : ") );
write( Message, DEVICE);
write( Message, STRING'(". Legal values of this attribute are ") );
write( Message, STRING'(" VIRTEX5, VIRTEX6, SPARTAN6, 7SERIES. ") );
ASSERT FALSE REPORT Message.ALL SEVERITY Failure;
DEALLOCATE (Message);
end if;
return func_val;
end;
function CheckStyle (
style : in string
) return boolean is
variable func_val : boolean;
variable Message : LINE;
begin
if (style = "AUTO" or style = "DSP" ) then
func_val := true;
else
func_val := false;
write( Message, STRING'("Illegal value of Attribute STYLE : ") );
write ( Message, STYLE);
write( Message, STRING'(". Legal values of this attribute are ") );
write( Message, STRING'(" AUTO, DSP ") );
ASSERT FALSE REPORT Message.ALL SEVERITY Failure;
DEALLOCATE (Message);
end if;
return func_val;
end;
function CheckLatency (
lat : in integer
) return boolean is
variable func_val : boolean;
variable Message : LINE;
begin
if (LATENCY = 0 or LATENCY = 1 or LATENCY = 2) then
func_val := true;
else
func_val := false;
write( Message, STRING'("Illegal value of Attribute LATENCY : ") );
write ( Message, LATENCY);
write( Message, STRING'(". Legal values of this attribute are ") );
write( Message, STRING'(" 0, 1, 2. ") );
ASSERT FALSE REPORT Message.ALL SEVERITY Failure;
DEALLOCATE (Message);
end if;
return func_val;
end;
function CheckWidth (
width : in integer
) return boolean is
variable func_val : boolean;
variable Message : LINE;
begin
if (width > 0 and width <= 48 ) then
func_val := true;
else
func_val := false;
write( Message, STRING'("Illegal value of Attribute WIDTH : ") );
write ( Message, WIDTH);
write( Message, STRING'(". Legal values of this attribute are ") );
write( Message, STRING'(" 1 to 48 ") );
ASSERT FALSE REPORT Message.ALL SEVERITY Failure;
DEALLOCATE (Message);
end if;
return func_val;
end;
function GetABREG_IN (
latency : in integer
) return integer is
variable func_width : integer;
begin
if (LATENCY = 2 ) then
func_width := 1;
else
func_width := 0;
end if;
return func_width;
end;
function GetPREG_IN (
latency : in integer
) return integer is
variable func_width : integer;
variable Message : LINE;
begin
if (LATENCY = 1 or LATENCY = 2 ) then
func_width := 1;
else
func_width := 0;
end if;
return func_width;
end;
--Signal Declarations:
signal ALUMODE_IN : std_logic_vector(3 downto 0);
signal OPMODEST_IN : std_logic_vector(7 downto 0);
signal A_IN : std_logic_vector(47 downto 0) := "000000000000000000000000000000000000000000000000";
signal B_IN : std_logic_vector(47 downto 0) := "000000000000000000000000000000000000000000000000";
signal A_INST : std_logic_vector(17 downto 0) := "000000000000000000";
signal RESULT_OUT : std_logic_vector(47 downto 0) := "000000000000000000000000000000000000000000000000";
signal CARRYOUT_OUT : std_logic_vector(3 downto 0);
signal CARRYOUTST : std_logic;
signal CARRYIN_IN : std_logic;
constant ChkDevice : boolean := CheckDevice(DEVICE);
constant ChkStyle : boolean := CheckStyle(STYLE);
constant ChkWidth : boolean := CheckWidth(WIDTH);
constant ChkLatency : boolean := CheckLatency(LATENCY);
constant AREG_IN : integer := GetABREG_IN(LATENCY);
constant ALUMODEREG_IN : integer := GetABREG_IN(LATENCY);
constant BREG_IN : integer := GetABREG_IN(LATENCY);
constant CREG_IN : integer := GetABREG_IN(LATENCY);
constant PREG_IN : integer := GetPREG_IN(LATENCY);
-- Architecture Section: instantiation
begin
ALUMODE_IN <= "00" & (not ADD_SUB) & (not ADD_SUB);
CARRYIN_IN <= CARRYIN when (WIDTH = 48) else '0';
OPMODEST_IN <= (not ADD_SUB) & (not ADD_SUB) & "001111";
add48 : if (WIDTH = 48) generate
begin
A_IN <= A;
B_IN <= B;
end generate add48;
add : if (WIDTH < 48) generate
begin
A_IN(47 downto (47-(WIDTH-1))) <= A;
A_IN((47-WIDTH)) <= ADD_SUB;
sa: for i in (47-(WIDTH+1)) downto 0 generate
A_IN(i) <= '0';
end generate;
B_IN(47 downto (47-(WIDTH-1))) <= B;
B_IN((47-WIDTH)) <= CARRYIN;
sb: for i in (47-(WIDTH+1)) downto 0 generate
B_IN(i) <= '0';
end generate;
end generate add;
A_INST <= "000000" & A_IN(47 downto 36);
RESULT <= RESULT_OUT(47 downto (47-(WIDTH-1)));
c1: if (DEVICE = "VIRTEX5" or DEVICE = "VIRTEX6" or DEVICE = "7SERIES") generate
CARRYOUT <= CARRYOUT_OUT(3);
end generate c1;
-- begin s1
c2: if (DEVICE = "SPARTAN6") generate
CARRYOUT <= CARRYOUTST;
end generate c2;
-- end s1
-- begin generate virtex5
v5 : if DEVICE = "VIRTEX5" generate
begin
DSP48_1: DSP48E
generic map (
ACASCREG => AREG_IN,
ALUMODEREG => ALUMODEREG_IN,
AREG => AREG_IN,
BCASCREG => BREG_IN,
BREG => BREG_IN,
CREG => CREG_IN,
PREG => PREG_IN,
USE_MULT => "NONE")
port map (
ACOUT => open,
BCOUT => open,
CARRYCASCOUT => open,
CARRYOUT => CARRYOUT_OUT(3 downto 0),
MULTSIGNOUT => open,
OVERFLOW => open,
P => RESULT_OUT,
PATTERNBDETECT => open,
PATTERNDETECT => open,
PCOUT => open,
UNDERFLOW => open,
A => B_IN(47 downto 18),
ACIN => "000000000000000000000000000000",
ALUMODE => ALUMODE_IN,
B => B_IN(17 downto 0),
BCIN => "000000000000000000",
C => A_IN,
CARRYCASCIN => '0',
CARRYIN => CARRYIN_IN,
CARRYINSEL => "000",
CEA1 => CE,
CEA2 => CE,
CEALUMODE => CE,
CEB1 => CE,
CEB2 => CE,
CEC => CE,
CECARRYIN => CE,
CECTRL => CE,
CEM => '0',
CEMULTCARRYIN => '0',
CEP => CE,
CLK => CLK,
MULTSIGNIN => '0',
OPMODE => "0110011",
PCIN => "000000000000000000000000000000000000000000000000",
RSTA => RST,
RSTALLCARRYIN => RST,
RSTALUMODE => RST,
RSTB => RST,
RSTC => RST,
RSTCTRL => RST,
RSTM => RST,
RSTP => RST
);
end generate v5;
-- end generate virtex5
-- begin generate virtex6
bl : if (DEVICE = "VIRTEX6" or DEVICE = "7SERIES") generate
begin
DSP48_2: DSP48E1
generic map (
ACASCREG => AREG_IN,
AREG => AREG_IN,
ADREG => 0,
ALUMODEREG => ALUMODEREG_IN,
BCASCREG => BREG_IN,
BREG => BREG_IN,
CREG => CREG_IN,
DREG => 0,
MREG => 0,
PREG => PREG_IN,
USE_MULT => "NONE")
port map (
ACOUT => open,
BCOUT => open,
CARRYCASCOUT => open,
CARRYOUT => CARRYOUT_OUT,
MULTSIGNOUT => open,
OVERFLOW => open,
P => RESULT_OUT,
PATTERNBDETECT => open,
PATTERNDETECT => open,
PCOUT => open,
UNDERFLOW => open,
A => B_IN(47 downto 18),
ACIN => "000000000000000000000000000000",
ALUMODE => ALUMODE_IN,
B => B_IN(17 downto 0),
BCIN => "000000000000000000",
C => A_IN,
CARRYCASCIN => '0',
CARRYIN => CARRYIN_IN,
CARRYINSEL => "000",
CEA1 => CE,
CEA2 => CE,
CEAD => '0',
CEALUMODE => CE,
CEB1 => CE,
CEB2 => CE,
CEC => CE,
CECARRYIN => CE,
CECTRL => CE,
CED => '0',
CEINMODE => '0',
CEM => '0',
CEP => CE,
CLK => CLK,
D => "0000000000000000000000000",
INMODE => "00000",
MULTSIGNIN => '0',
OPMODE => "0110011",
PCIN => "000000000000000000000000000000000000000000000000",
RSTA => RST,
RSTALLCARRYIN => RST,
RSTALUMODE => RST,
RSTB => RST,
RSTC => RST,
RSTCTRL => RST,
RSTD => RST,
RSTINMODE => RST,
RSTM => RST,
RSTP => RST
);
end generate bl;
-- end generate virtex6
-- begin generate spartan6
st : if DEVICE = "SPARTAN6" generate
begin
DSP48_3: DSP48A1
generic map (
A1REG => AREG_IN,
B1REG => BREG_IN,
CREG => CREG_IN,
PREG => PREG_IN )
port map (
BCOUT => open,
CARRYOUT => CARRYOUTST,
CARRYOUTF => open,
M => open,
P => RESULT_OUT,
PCOUT => open,
A => A_IN(35 downto 18),
B => A_IN(17 downto 0),
C => B_IN,
CARRYIN => CARRYIN_IN,
CEA => CE,
CEB => CE,
CEC => CE,
CECARRYIN => CE,
CED => CE,
CEM => '0',
CEOPMODE => CE,
CEP => CE,
CLK => CLK,
D => A_INST,
OPMODE => OPMODEST_IN,
PCIN => "000000000000000000000000000000000000000000000000",
RSTA => RST,
RSTB => RST,
RSTC => RST,
RSTCARRYIN => RST,
RSTD => RST,
RSTM => RST,
RSTOPMODE => RST,
RSTP => RST
);
end generate st;
-- end generate spartan6
end addsub;