SURF  1.0
DspAddSub.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : DspAddSub.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2013-07-12
5 -- Last update: 2013-07-12
6 -------------------------------------------------------------------------------
7 -- Description: Example of VHDL inferred DSP resources for Adder/Subtracter
8 -------------------------------------------------------------------------------
9 -- This file is part of 'SLAC Firmware Standard Library'.
10 -- It is subject to the license terms in the LICENSE.txt file found in the
11 -- top-level directory of this distribution and at:
12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
13 -- No part of 'SLAC Firmware Standard Library', including this file,
14 -- may be copied, modified, propagated, or distributed except according to
15 -- the terms contained in the LICENSE.txt file.
16 -------------------------------------------------------------------------------
17 
18 library ieee;
19 use ieee.std_logic_1164.all;
20 use ieee.std_logic_unsigned.all;
21 use ieee.std_logic_arith.all;
22 
23 use work.StdRtlPkg.all;
24 
25 --! @see entity
26  --! @ingroup xilinx_general
27 entity DspAddSub is
28  generic (
29  TPD_G : time := 1 ns;
30  LATENCY_G : integer range 0 to 2 := 0;
31  -- Port A parameters
32  A_WIDTH_G : integer range 2 to 48 := 2;
33  A_TYPE_G : string := "unsigned";
34  -- Port B parameters
35  B_WIDTH_G : integer range 2 to 48 := 2;
36  B_TYPE_G : string := "unsigned";
37  -- Port S parameters
38  S_WIDTH_G : integer range 2 to 48 := 2;
39  S_TYPE_G : string := "unsigned");
40  port (
41  clk : in sl;
42  add : in sl := '1';
43  a : in slv((A_WIDTH_G-1) downto 0) := (others => '0');
44  b : in slv((B_WIDTH_G-1) downto 0) := (others => '0');
45  s : out slv((S_WIDTH_G-1) downto 0));
46 end DspAddSub;
47 
48 architecture rtl of DspAddSub is
49 
50  -- Constants
51  constant A_FORMAT_C : sl := ite((A_TYPE_G = "signed"), '1', '0');
52  constant B_FORMAT_C : sl := ite((B_TYPE_G = "signed"), '1', '0');
53  constant S_FORMAT_C : sl := ite((S_TYPE_G = "signed"), '1', '0');
54 
55  -- Types
56  type OutputArray is array(0 to LATENCY_G) of slv((S_WIDTH_G-1) downto 0);
57 
58  -- Signals
59  signal aIn : slv((A_WIDTH_G-1) downto 0) := (others => '0');
60  signal bIn : slv((B_WIDTH_G-1) downto 0) := (others => '0');
61  signal sOut : slv((S_WIDTH_G-1) downto 0) := (others => '0');
62  signal qOut : OutputArray := (others => (others => '0'));
63 
64  -- Attribute for XST
65  attribute use_dsp48 : string;
66  attribute use_dsp48 of sOut : signal is "yes";
67 
68 begin
69 
70  -- A_TYPE_G check
71  assert ((A_TYPE_G = "unsigned") or (A_TYPE_G = "signed"))
72  report "A_TYPE_G must be either unsigned or signed"
73  severity failure;
74  -- B_TYPE_G check
75  assert ((B_TYPE_G = "unsigned") or (B_TYPE_G = "signed"))
76  report "B_TYPE_G must be either unsigned or signed"
77  severity failure;
78  -- S_TYPE_G check
79  assert ((S_TYPE_G = "unsigned") or (S_TYPE_G = "signed"))
80  report "S_TYPE_G must be either unsigned or signed"
81  severity failure;
82  -- S_WIDTH_G range check
83  assert ((S_WIDTH_G = A_WIDTH_G) or (S_WIDTH_G = (A_WIDTH_G+1)) or (S_WIDTH_G = B_WIDTH_G) or (S_WIDTH_G = (B_WIDTH_G+1)))
84  report "S_WIDTH_G must be A_WIDTH_G, A_WIDTH_G+1, B_WIDTH_G, or B_WIDTH_G+1"
85  severity failure;
86 
87  --force the input A to be unsigned
88  aIn(A_WIDTH_G-1) <= a(A_WIDTH_G-1) xor A_FORMAT_C;
89  Input_A_Mapping_Gen :
90  for i in 0 to (A_WIDTH_G-2) generate
91  aIn(i) <= a(i);
92  end generate Input_A_Mapping_Gen;
93 
94  --force the input B to be unsigned
95  bIn(B_WIDTH_G-1) <= b(B_WIDTH_G-1) xor B_FORMAT_C;
96  Input_B_Mapping_Gen :
97  for i in 0 to (B_WIDTH_G-2) generate
98  bIn(i) <= b(i);
99  end generate Input_B_Mapping_Gen;
100 
101  -- zero latency DSP48 process
102  process(aIn, add, bIn)
103  begin
104  -- S = A + B
105  if add = '1' then
106  sOut <= aIn + bIn;
107  -- S = A - B
108  else
109  sOut <= aIn - bIn;
110  end if;
111  end process;
112 
113  --convert output S to desired unsigned or signed format
114  qOut(0)(S_WIDTH_G-1) <= sOut(S_WIDTH_G-1) xor S_FORMAT_C;
115  Output_S_Mapping_Gen :
116  for i in 0 to (A_WIDTH_G-2) generate
117  qOut(0)(i) <= sOut(i);
118  end generate Output_S_Mapping_Gen;
119 
120  --check if we need to generate registers
121  Latency_Gen : if LATENCY_G /= 0 generate
122  process(clk)
123  variable i : integer;
124  begin
125  if rising_edge(clk) then
126  for i in 0 to (LATENCY_G-1) loop
127  qOut(i+1) <= qOut(i) after TPD_G;
128  end loop;
129  end if;
130  end process;
131  end generate Latency_Gen;
132 
133  --map the output S with respect to LATENCY_G
134  s <= qOut(LATENCY_G);
135 
136 end rtl;
TPD_Gtime := 1 ns
Definition: DspAddSub.vhd:29
std_logic sl
Definition: StdRtlPkg.vhd:28
_library_ ieeeieee
Definition: DeviceDna.vhd:18
LATENCY_Ginteger range 0 to 2:= 0
Definition: DspAddSub.vhd:30
in clksl
Definition: DspAddSub.vhd:41
S_WIDTH_Ginteger range 2 to 48:= 2
Definition: DspAddSub.vhd:38
in bslv(( B_WIDTH_G- 1) downto 0) :=( others => '0')
Definition: DspAddSub.vhd:44
S_TYPE_Gstring := "unsigned"
Definition: DspAddSub.vhd:39
out sslv(( S_WIDTH_G- 1) downto 0)
Definition: DspAddSub.vhd:45
A_WIDTH_Ginteger range 2 to 48:= 2
Definition: DspAddSub.vhd:32
B_WIDTH_Ginteger range 2 to 48:= 2
Definition: DspAddSub.vhd:35
in aslv(( A_WIDTH_G- 1) downto 0) :=( others => '0')
Definition: DspAddSub.vhd:43
B_TYPE_Gstring := "unsigned"
Definition: DspAddSub.vhd:36
A_TYPE_Gstring := "unsigned"
Definition: DspAddSub.vhd:33
in addsl := '1'
Definition: DspAddSub.vhd:42
std_logic_vector slv
Definition: StdRtlPkg.vhd:29