OpenCores
URL https://opencores.org/ocsvn/g729a_codec/g729a_codec/trunk

Subversion Repositories g729a_codec

[/] [g729a_codec/] [trunk/] [VHDL/] [G729A_asip_addsub_pipeb.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 madsilicon
-----------------------------------------------------------------
2
--                                                             --
3
-----------------------------------------------------------------
4
--                                                             --
5
-- Copyright (C) 2013 Stefano Tonello                          --
6
--                                                             --
7
-- This source file may be used and distributed without        --
8
-- restriction provided that this copyright statement is not   --
9
-- removed from the file and that any derivative work contains --
10
-- the original copyright notice and the associated disclaimer.--
11
--                                                             --
12
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY         --
13
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   --
14
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   --
15
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      --
16
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         --
17
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    --
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   --
19
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        --
20
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  --
21
-- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  --
22
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  --
23
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         --
24
-- POSSIBILITY OF SUCH DAMAGE.                                 --
25
--                                                             --
26
-----------------------------------------------------------------
27
 
28
---------------------------------------------------------
29
-- Pipe-B adder/subtractor
30
---------------------------------------------------------
31
 
32
library IEEE;
33
use IEEE.std_logic_1164.all;
34
use IEEE.numeric_std.all;
35
 
36
library WORK;
37
use WORK.G729A_ASIP_PKG.all;
38
use WORK.G729A_ASIP_BASIC_PKG.all;
39
use WORK.G729A_ASIP_ARITH_PKG.all;
40
 
41
entity G729A_ASIP_ADDSUB_PIPEB is
42
  port(
43
    OPA_i : in LDWORD_T;
44
    OPB_i : in LDWORD_T;
45
    CTRL_i : in ADD_CTRL;
46
 
47
    RES_o : out LDWORD_T;
48
    OVF_o : out std_logic
49
  );
50
end G729A_ASIP_ADDSUB_PIPEB;
51
 
52
architecture ARC of G729A_ASIP_ADDSUB_PIPEB is
53
 
54
  component G729A_ASIP_ADDER_F is
55
    generic(
56
      LEN1 : integer := 16;
57
      LEN2 : integer := 16
58
    );
59
    port(
60
      OPA_i : in signed(LEN1+LEN2-1 downto 0);
61
      OPB_i : in signed(LEN1+LEN2-1 downto 0);
62
      CI_i : in std_logic;
63
 
64
      SUM_o : out signed(LEN1+LEN2-1 downto 0)
65
    );
66
  end component;
67
 
68
  function EXTS(S : signed; L : natural) return signed is
69
    variable XS : signed(L-1 downto 0);
70
  begin
71
    XS(S'HIGH downto 0) := S;
72
    XS(L-1 downto S'HIGH+1) := (others => S(S'HIGH));
73
    return(XS);
74
  end function;
75
 
76 3 madsilicon
  signal IOPA,IOPB,SUM : LDWORD_T;
77
  signal CI : std_logic;
78 2 madsilicon
 
79
begin
80
 
81
  -- adder operands selection
82
  process(CTRL_i,OPB_i,OPA_i)
83
  begin
84
    case CTRL_i is
85
      when AC_ABS|AC_NEG =>
86
        -- tmp = -opa_i
87
        IOPA <= not(EXTS(OPA_i(SDLEN-1 downto 0),LDLEN));
88 3 madsilicon
        IOPB <= (others => '0');
89
        CI <= '1';
90 2 madsilicon
      when AC_LABS|AC_LNEG =>
91
        -- tmp = -opa_i
92
        IOPA <= not(OPA_i);
93 3 madsilicon
        IOPB <= (others => '0');
94
        CI <= '1';
95 2 madsilicon
      --when AC_ADD =>
96
      --  -- tmp = opa_i + opb_i
97
      --  IOPA <= EXTS(OPA_i(SDLEN-1 downto 0),LDLEN);
98
      --  IOPB <= EXTS(OPB_i(SDLEN-1 downto 0),LDLEN);
99 3 madsilicon
      --  CI <= '0';
100 2 madsilicon
      when AC_LADD =>
101
        -- tmp = opa_i + opb_i
102
        IOPA <= OPA_i;
103
        IOPB <= OPB_i;
104 3 madsilicon
        CI <= '0';
105 2 madsilicon
      --when AC_SUB =>
106
      --  -- tmp = opa_i - opb_i
107
      --  IOPA <= EXTS(OPA_i(SDLEN-1 downto 0),LDLEN);
108
      --  IOPB <= not(EXTS(OPB_i(SDLEN-1 downto 0),LDLEN));
109 3 madsilicon
      --  CI <= '1';
110 2 madsilicon
      when AC_LSUB =>
111
        -- tmp = opa_i - opb_i
112
        IOPA <= OPA_i;
113
        IOPB <= not(OPB_i);
114 3 madsilicon
        CI <= '1';
115 2 madsilicon
      when AC_LEXT =>
116
        -- tmp = opa_i - (opa_i(31:16)<<16)
117
        IOPA <= OPA_i;
118
        IOPB <= not(OPA_i(LDLEN-1 downto SDLEN) & to_signed(0,SDLEN));
119 3 madsilicon
        CI <= '1';
120 2 madsilicon
      when others => -- RND
121
        -- tmp = opa_i + 0x00008000 
122
        IOPA <= OPA_i;
123
        IOPB <= (SDLEN-1 => '1',others => '0');
124 3 madsilicon
        CI <= '0';
125 2 madsilicon
      --when AC_INC =>
126
      --  -- tmp = opa_i + 1 
127
      --  IOPA <= EXTS(OPA_i(SDLEN-1 downto 0),LDLEN);
128
      --  IOPB <= (0 => '1',others => '0');
129 3 madsilicon
      --  CI <= '0';
130 2 madsilicon
      --when others => -- DEC
131
      --  -- tmp = opa_i - 1 
132
      --  IOPA <= EXTS(OPA_i(SDLEN-1 downto 0),LDLEN);
133
      --  IOPB <= (others => '1');
134 3 madsilicon
      --  CI <= '0';
135 2 madsilicon
    end case;
136
  end process;
137
 
138
  -- adder
139
 
140
  U_ADDF : G729A_ASIP_ADDER_F
141
    generic map(
142
      LEN1 => SDLEN,
143
      LEN2 => SDLEN
144
    )
145
    port map(
146
      OPA_i => IOPA,
147
      OPB_i => IOPB,
148 3 madsilicon
      CI_i => CI,
149 2 madsilicon
      SUM_o => SUM
150
    );
151
 
152
  -- result and overflow flag generation
153
  process(CTRL_i,OPA_i,OPB_i,SUM)
154
    variable SA,LSA,LSB,IOVF : std_logic;
155
    variable IRES,TMP : LDWORD_T;
156
  begin
157
 
158
    SA := OPA_i(SDLEN-1);
159
    LSA := OPA_i(LDLEN-1);
160
    LSB := OPB_i(LDLEN-1);
161
 
162
    case CTRL_i is
163
 
164
      when AC_ABS =>
165
        -- IRES upper half is set to all-0
166
        IRES(LDLEN-1 downto SDLEN) := (others => '0');
167
        -- overflow flag is unchanged
168
        IOVF := '0';
169
        -- check if input is min. signed integer
170
        if(OPA_i(SDLEN-1 downto 0) = MIN_16) then
171
          IRES(SDLEN-1 downto 0) := MAX_16;
172
        elsif(SA = '1') then
173
          IRES(SDLEN-1 downto 0) := SUM(SDLEN-1 downto 0);
174
        else
175
          IRES(SDLEN-1 downto 0) := OPA_i(SDLEN-1 downto 0);
176
        end if;
177
 
178
      --when AC_ADD =>
179
      --  -- IRES upper half is set to all-0
180
      --  IRES(LDLEN-1 downto SDLEN) := (others => '0');
181
      --  sature(SUM,IRES(SDLEN-1 downto 0),IOVF);
182
 
183
      when AC_NEG =>
184
        -- IRES upper half is set to all-0
185
        IRES(LDLEN-1 downto SDLEN) := (others => '0');
186
        if(OPA_i(SDLEN-1 downto 0) = MIN_16) then
187
          IRES(SDLEN-1 downto 0) := MAX_16;
188
        else
189
          IRES(SDLEN-1 downto 0) := SUM(SDLEN-1 downto 0);
190
        end if;
191
        IOVF := '0';
192
 
193
      --when AC_SUB =>
194
      --  -- IRES upper half is set to all-0
195
      --  IRES(LDLEN-1 downto SDLEN) := (others => '0');
196
      --  sature(SUM,IRES(SDLEN-1 downto 0),IOVF);
197
 
198
      when AC_LABS =>
199
        if(OPB_i = MIN_32) then
200
          IRES := MAX_32;
201
        elsif(LSA = '1') then
202
          IRES := SUM;
203
        else
204
          IRES := OPA_i;
205
        end if;
206
        IOVF := '0';
207
 
208
      when AC_LADD =>
209
        L_add_sub(SUM,'1',LSA,LSB,IRES,IOVF);
210
 
211
      when AC_LSUB =>
212
        L_add_sub(SUM,'0',LSA,LSB,IRES,IOVF);
213
 
214
      when AC_LNEG =>
215
        if(OPA_i = MIN_32) then
216
          IRES := MAX_32;
217
        else
218
          IRES := SUM;
219
        end if;
220
        IOVF := '0';
221
 
222
      when AC_LEXT =>
223
        IRES(LDLEN-1 downto SDLEN) := OPA_i(LDLEN-1 downto SDLEN);
224
        IRES(SDLEN-1 downto 0) := SUM(SDLEN downto 1);
225
        IOVF := '0';
226
 
227
      when others => -- AC_RND
228
        L_add_sub(SUM,'1',LSA,'0',TMP,IOVF);
229
        IRES(LDLEN-1 downto SDLEN) := (others => '0'); --TMP(LDLEN-1));
230
        IRES(SDLEN-1 downto 0) := TMP(LDLEN-1 downto SDLEN);
231
 
232
      --when others => -- AC_NIL
233
      --  IRES := SUM;
234
      --  IOVF := '0';
235
 
236
    end case;
237
 
238
    RES_o <= IRES;
239
    OVF_o <= IOVF;
240
 
241
  end process;
242
 
243
end ARC;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.