405 lines
12 KiB
VHDL
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;
|
|
|
|
|
|
|