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 2

Go to most recent revision | 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
  constant ZERO : LDWORD_T := to_signed(0,LDLEN);
55
  constant ONE : LDWORD_T := to_signed(1,LDLEN);
56
 
57
  component G729A_ASIP_ADDER_F is
58
    generic(
59
      LEN1 : integer := 16;
60
      LEN2 : integer := 16
61
    );
62
    port(
63
      OPA_i : in signed(LEN1+LEN2-1 downto 0);
64
      OPB_i : in signed(LEN1+LEN2-1 downto 0);
65
      CI_i : in std_logic;
66
 
67
      SUM_o : out signed(LEN1+LEN2-1 downto 0)
68
    );
69
  end component;
70
 
71
  function EXTS(S : signed; L : natural) return signed is
72
    variable XS : signed(L-1 downto 0);
73
  begin
74
    XS(S'HIGH downto 0) := S;
75
    XS(L-1 downto S'HIGH+1) := (others => S(S'HIGH));
76
    return(XS);
77
  end function;
78
 
79
  signal IOPA,IOPB,CI,SUM : LDWORD_T;
80
 
81
begin
82
 
83
  -- adder operands selection
84
  process(CTRL_i,OPB_i,OPA_i)
85
  begin
86
    case CTRL_i is
87
      when AC_ABS|AC_NEG =>
88
        -- tmp = -opa_i
89
        IOPA <= not(EXTS(OPA_i(SDLEN-1 downto 0),LDLEN));
90
        IOPB <= ZERO;
91
        CI <= ONE;
92
      when AC_LABS|AC_LNEG =>
93
        -- tmp = -opa_i
94
        IOPA <= not(OPA_i);
95
        IOPB <= ZERO;
96
        CI <= ONE;
97
      --when AC_ADD =>
98
      --  -- tmp = opa_i + opb_i
99
      --  IOPA <= EXTS(OPA_i(SDLEN-1 downto 0),LDLEN);
100
      --  IOPB <= EXTS(OPB_i(SDLEN-1 downto 0),LDLEN);
101
      --  CI <= ZERO;
102
      when AC_LADD =>
103
        -- tmp = opa_i + opb_i
104
        IOPA <= OPA_i;
105
        IOPB <= OPB_i;
106
        CI <= ZERO;
107
      --when AC_SUB =>
108
      --  -- tmp = opa_i - opb_i
109
      --  IOPA <= EXTS(OPA_i(SDLEN-1 downto 0),LDLEN);
110
      --  IOPB <= not(EXTS(OPB_i(SDLEN-1 downto 0),LDLEN));
111
      --  CI <= ONE;
112
      when AC_LSUB =>
113
        -- tmp = opa_i - opb_i
114
        IOPA <= OPA_i;
115
        IOPB <= not(OPB_i);
116
        CI <= ONE;
117
      when AC_LEXT =>
118
        -- tmp = opa_i - (opa_i(31:16)<<16)
119
        IOPA <= OPA_i;
120
        IOPB <= not(OPA_i(LDLEN-1 downto SDLEN) & to_signed(0,SDLEN));
121
        CI <= ONE;
122
      when others => -- RND
123
        -- tmp = opa_i + 0x00008000 
124
        IOPA <= OPA_i;
125
        IOPB <= (SDLEN-1 => '1',others => '0');
126
        CI <= ZERO;
127
      --when AC_INC =>
128
      --  -- tmp = opa_i + 1 
129
      --  IOPA <= EXTS(OPA_i(SDLEN-1 downto 0),LDLEN);
130
      --  IOPB <= (0 => '1',others => '0');
131
      --  CI <= ZERO;
132
      --when others => -- DEC
133
      --  -- tmp = opa_i - 1 
134
      --  IOPA <= EXTS(OPA_i(SDLEN-1 downto 0),LDLEN);
135
      --  IOPB <= (others => '1');
136
      --  CI <= ZERO;
137
    end case;
138
  end process;
139
 
140
  -- adder
141
 
142
  U_ADDF : G729A_ASIP_ADDER_F
143
    generic map(
144
      LEN1 => SDLEN,
145
      LEN2 => SDLEN
146
    )
147
    port map(
148
      OPA_i => IOPA,
149
      OPB_i => IOPB,
150
      CI_i => CI(0),
151
      SUM_o => SUM
152
    );
153
 
154
  -- result and overflow flag generation
155
  process(CTRL_i,OPA_i,OPB_i,SUM)
156
    variable SA,LSA,LSB,IOVF : std_logic;
157
    variable IRES,TMP : LDWORD_T;
158
  begin
159
 
160
    SA := OPA_i(SDLEN-1);
161
    LSA := OPA_i(LDLEN-1);
162
    LSB := OPB_i(LDLEN-1);
163
 
164
    case CTRL_i is
165
 
166
      when AC_ABS =>
167
        -- IRES upper half is set to all-0
168
        IRES(LDLEN-1 downto SDLEN) := (others => '0');
169
        -- overflow flag is unchanged
170
        IOVF := '0';
171
        -- check if input is min. signed integer
172
        if(OPA_i(SDLEN-1 downto 0) = MIN_16) then
173
          IRES(SDLEN-1 downto 0) := MAX_16;
174
        elsif(SA = '1') then
175
          IRES(SDLEN-1 downto 0) := SUM(SDLEN-1 downto 0);
176
        else
177
          IRES(SDLEN-1 downto 0) := OPA_i(SDLEN-1 downto 0);
178
        end if;
179
 
180
      --when AC_ADD =>
181
      --  -- IRES upper half is set to all-0
182
      --  IRES(LDLEN-1 downto SDLEN) := (others => '0');
183
      --  sature(SUM,IRES(SDLEN-1 downto 0),IOVF);
184
 
185
      when AC_NEG =>
186
        -- IRES upper half is set to all-0
187
        IRES(LDLEN-1 downto SDLEN) := (others => '0');
188
        if(OPA_i(SDLEN-1 downto 0) = MIN_16) then
189
          IRES(SDLEN-1 downto 0) := MAX_16;
190
        else
191
          IRES(SDLEN-1 downto 0) := SUM(SDLEN-1 downto 0);
192
        end if;
193
        IOVF := '0';
194
 
195
      --when AC_SUB =>
196
      --  -- IRES upper half is set to all-0
197
      --  IRES(LDLEN-1 downto SDLEN) := (others => '0');
198
      --  sature(SUM,IRES(SDLEN-1 downto 0),IOVF);
199
 
200
      when AC_LABS =>
201
        if(OPB_i = MIN_32) then
202
          IRES := MAX_32;
203
        elsif(LSA = '1') then
204
          IRES := SUM;
205
        else
206
          IRES := OPA_i;
207
        end if;
208
        IOVF := '0';
209
 
210
      when AC_LADD =>
211
        L_add_sub(SUM,'1',LSA,LSB,IRES,IOVF);
212
 
213
      when AC_LSUB =>
214
        L_add_sub(SUM,'0',LSA,LSB,IRES,IOVF);
215
 
216
      when AC_LNEG =>
217
        if(OPA_i = MIN_32) then
218
          IRES := MAX_32;
219
        else
220
          IRES := SUM;
221
        end if;
222
        IOVF := '0';
223
 
224
      when AC_LEXT =>
225
        IRES(LDLEN-1 downto SDLEN) := OPA_i(LDLEN-1 downto SDLEN);
226
        IRES(SDLEN-1 downto 0) := SUM(SDLEN downto 1);
227
        IOVF := '0';
228
 
229
      when others => -- AC_RND
230
        L_add_sub(SUM,'1',LSA,'0',TMP,IOVF);
231
        IRES(LDLEN-1 downto SDLEN) := (others => '0'); --TMP(LDLEN-1));
232
        IRES(SDLEN-1 downto 0) := TMP(LDLEN-1 downto SDLEN);
233
 
234
      --when others => -- AC_NIL
235
      --  IRES := SUM;
236
      --  IOVF := '0';
237
 
238
    end case;
239
 
240
    RES_o <= IRES;
241
    OVF_o <= IOVF;
242
 
243
  end process;
244
 
245
end ARC;

powered by: WebSVN 2.1.0

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