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

Subversion Repositories g729a_codec

[/] [g729a_codec/] [trunk/] [VHDL/] [G729A_asip_pipe_b.vhd] - Blame information for rev 2

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
-- G.729A ASIP pipeline-B
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
use WORK.G729A_ASIP_OP_PKG.all;
41
 
42
entity G729A_ASIP_PIPE_B is
43
  port(
44
    CLK_i : in std_logic;
45
    OP_i :  in ALU_OP_T;
46
    OPA_i : in LDWORD_T;
47
    OPB_i : in LDWORD_T;
48
    OVF_i : in std_logic;
49
    ACC_i : in LDWORD_T;
50
 
51
    RES_o : out LDWORD_T;
52
    OVF_o : out std_logic
53
  );
54
end G729A_ASIP_PIPE_B;
55
 
56
architecture ARC of G729A_ASIP_PIPE_B is
57
 
58
  constant MUL_OVFVAL : LDWORD_T := hex_to_signed("40000000",LDLEN);
59
  constant ZERO16 : SDWORD_T := (others => '0');
60
 
61
  constant OP_ADD : natural := 0;
62
  constant OP_SUB : natural := 1;
63
  constant OP_MUL : natural := 2;
64
  constant OP_MOV : natural := 3;
65
  constant OP_LOAD : natural := 4;
66
  constant OP_LMAC : natural := 5;
67
  constant OP_LMSU : natural := 6;
68
 
69
  component G729A_ASIP_ADDER is
70
    generic(
71
      WIDTH : integer := 16
72
    );
73
    port(
74
      OPA_i : in signed(WIDTH-1 downto 0);
75
      OPB_i : in signed(WIDTH-1 downto 0);
76
      CI_i : in std_logic;
77
 
78
      SUM_o : out signed(WIDTH-1 downto 0)
79
    );
80
  end component;
81
 
82
  component G729A_ASIP_ADDER_F is
83
    generic(
84
      LEN1 : integer := 16;
85
      LEN2 : integer := 16
86
    );
87
    port(
88
      OPA_i : in signed(LEN1+LEN2-1 downto 0);
89
      OPB_i : in signed(LEN1+LEN2-1 downto 0);
90
      CI_i : in std_logic;
91
 
92
      SUM_o : out signed(LEN1+LEN2-1 downto 0)
93
    );
94
  end component;
95
 
96
  component G729A_ASIP_ADDSUB_PIPEB is
97
    port(
98
      CTRL_i : in ADD_CTRL;
99
      OPA_i : in LDWORD_T;
100
      OPB_i : in LDWORD_T;
101
 
102
      RES_o : out LDWORD_T;
103
      OVF_o : out std_logic
104
    );
105
  end component;
106
 
107
  component G729A_ASIP_MULU_PIPEB is
108
    port(
109
      CLK_i : in std_logic;
110
      CTRL_i : in MUL_CTRL;
111
      OPA_i : in LDWORD_T;
112
      OPB_i : in LDWORD_T;
113
 
114
      RES_o : out LDWORD_T;
115
      OVF_o : out std_logic
116
    );
117
  end component;
118
 
119
  component G729A_ASIP_SHFT is
120
    port(
121
      CTRL_i : in SHF_CTRL;
122
      SI_i : in LDWORD_T;
123
      SHFT_i : in SDWORD_T; --LONG_SHIFT_OVF_T;
124
 
125
      SO_o : out LDWORD_T;
126
      OVF_o : out std_logic
127
    );
128
  end component;
129
 
130
  component G729A_ASIP_LOGIC is
131
    port(
132
      CTRL_i : in LOG_CTRL;
133
      OPA_i : in LDWORD_T;
134
      OPB_i : in LDWORD_T;
135
 
136
      RES_o : out LDWORD_T
137
    );
138
  end component;
139
 
140
  -- check for overflow in addition/subtraction
141
  function overflow(
142
    SA : std_logic;
143
    SGNA : std_logic;
144
    SGNB : std_logic;
145
    SGNR : std_logic
146
  ) return std_logic is
147
  variable OVF : std_logic;
148
  begin
149
    -- overflow flag
150
    if(SA = '0') then
151
      -- addition
152
      if(SGNR = '1') then
153
        OVF := not(SGNA or SGNB);
154
      else
155
        OVF := (SGNA and SGNB);
156
      end if;
157
    else
158
      -- subtraction
159
      if(SGNR = '1') then
160
        OVF := (not(SGNA) and SGNB);
161
      else
162
        OVF := (SGNA and not(SGNB));
163
      end if;
164
    end if;
165
    return(OVF);
166
  end function;
167
 
168
  function to_unsigned(S : signed) return unsigned is
169
    variable U : unsigned(S'HIGH downto S'LOW);
170
  begin
171
    for i in S'HIGH downto S'LOW loop
172
      U(i) := S(i);
173
    end loop;
174
    return(U);
175
  end function;
176
 
177
  function to_signed(U : unsigned) return signed is
178
    variable S : signed(U'HIGH downto U'LOW);
179
  begin
180
    for i in U'HIGH downto U'LOW loop
181
      S(i) := U(i);
182
    end loop;
183
    return(S);
184
  end function;
185
 
186
  signal OP_q :  ALU_OP_T;
187
  signal OPA_q : LDWORD_T;
188
  signal OPB_q : LDWORD_T;
189
  signal OVF,ADD_OVF,MUL_OVF,SHF_OVF : std_logic;
190
  signal ADD_OVF_q,SHF_OVF_q : std_logic;
191
  signal RES,ADD_RES,MUL_RES,SHF_RES,LOG_RES : LDWORD_T;
192
  signal ADD_RES_q,SHF_RES_q,LOG_RES_q : LDWORD_T;
193
  signal AC : ADD_CTRL;
194
  signal MC : MUL_CTRL;
195
  signal SC : SHF_CTRL;
196
  signal LC : LOG_CTRL;
197
  signal ADD_SEL,MUL_SEL,SHF_SEL,LOG_SEL : std_logic;
198
  signal ADD_SEL_q,MUL_SEL_q,SHF_SEL_q,LOG_SEL_q : std_logic;
199
  signal SHFT : LONG_SHIFT_OVF_T;
200
 
201
begin
202
 
203
  ------------------------------------
204
  -- Add/subtract unit operation selection
205
  ------------------------------------
206
 
207
  process(OP_i)
208
  begin
209
    ADD_SEL <= '1';
210
    case OP_i is
211
      when ALU_ABS =>
212
        AC <= AC_ABS;
213
      --when ALU_ADD =>
214
      --  AC <= AC_ADD;
215
      when ALU_NEG =>
216
        AC <= AC_NEG;
217
      --when ALU_SUB =>
218
      --  AC <= AC_SUB;
219
      when ALU_LABS =>
220
        AC <= AC_LABS;
221
      when ALU_LADD =>
222
        AC <= AC_LADD;
223
      when ALU_LNEG =>
224
        AC <= AC_LNEG;
225
      when ALU_LSUB =>
226
        AC <= AC_LSUB;
227
      when ALU_LEXT =>
228
        AC <= AC_LEXT;
229
      when ALU_RND =>
230
        AC <= AC_RND;
231
      --when ALU_INC =>
232
      --  ADD_SEL <= '0'; -- ALU result is load data
233
      --  AC <= AC_INC;
234
      --when ALU_DEC =>
235
      --  ADD_SEL <= '0'; -- ALU result is load data
236
      -- -AC <= AC_DEC;
237
      when others =>
238
        ADD_SEL <= '0';
239
        AC <= AC_NIL;
240
    end case;
241
  end process;
242
 
243
  ------------------------------------
244
  -- Multiply unit operation selection
245
  ------------------------------------
246
 
247
  process(OP_i)
248
  begin
249
    MUL_SEL <= '1';
250
    case OP_i is
251
      --when ALU_MUL =>
252
      --  MC <= MC_MUL;
253
      when ALU_LMUL =>
254
        MC <= MC_LMUL;
255
      when ALU_MULA =>
256
        MC <= MC_MULA;
257
      when ALU_MULR =>
258
        MC <= MC_MULR;
259
      --when ALU_LMAC =>
260
      --  MC <= MC_LMAC;
261
      --when ALU_LMSU =>
262
      --  MC <= MC_LMSU;
263
      when ALU_M3216 =>
264
        MC <= MC_M3216;
265
      when others =>
266
        MUL_SEL <= '0';
267
        MC <= MC_NIL;
268
    end case;
269
  end process;
270
 
271
  ------------------------------------
272
  -- Shift/normalize unit operation selection
273
  ------------------------------------
274
 
275
  process(OP_i)
276
  begin
277
    SHF_SEL <= '1';
278
    case OP_i is
279
      when ALU_SHL =>
280
        SC <= SC_SHL;
281
      when ALU_SHR =>
282
        SC <= SC_SHR;
283
      when ALU_LSHL =>
284
        SC <= SC_LSHL;
285
      when ALU_LSHR =>
286
        SC <= SC_LSHR;
287
      when ALU_NRMS =>
288
        SC <= SC_NRMS;
289
      when ALU_NRML =>
290
        SC <= SC_NRML;
291
      when others =>
292
        SHF_SEL <= '0';
293
        SC <= SC_NIL;
294
    end case;
295
  end process;
296
 
297
  ------------------------------------
298
  -- Logic unit operation selection
299
  ------------------------------------
300
 
301
  process(OP_i)
302
  begin
303
    LOG_SEL <= '1';
304
    case OP_i is
305
      when ALU_AND =>
306
        LC <= LC_AND;
307
      when ALU_OR =>
308
        LC <= LC_OR;
309
      when others =>
310
        LOG_SEL <= '0';
311
        LC <= LC_NIL;
312
    end case;
313
  end process;
314
 
315
  ------------------------------------
316
  -- Add/Subtract unit
317
  ------------------------------------
318
 
319
  U_ADD : G729A_ASIP_ADDSUB_PIPEB
320
    port map(
321
      CTRL_i => AC,
322
      OPA_i => OPA_i,
323
      OPB_i => OPB_i,
324
 
325
      RES_o => ADD_RES,
326
      OVF_o => ADD_OVF
327
    );
328
 
329
  -- pipe register
330
  process(CLK_i)
331
  begin
332
    if(CLK_i = '1' and CLK_i'event) then
333
      ADD_RES_q <= ADD_RES;
334
      ADD_OVF_q <= ADD_OVF;
335
      ADD_SEL_q <= ADD_SEL;
336
    end if;
337
  end process;
338
 
339
  ------------------------------------
340
  -- Multiply unit
341
  ------------------------------------
342
 
343
  U_MUL : G729A_ASIP_MULU_PIPEB
344
    port map(
345
      CLK_i => CLK_i,
346
      CTRL_i  => MC,
347
      OPA_i => OPA_i,
348
      OPB_i => OPB_i,
349
 
350
      RES_o => MUL_RES,
351
      OVF_o => MUL_OVF
352
    );
353
 
354
  -- pipe register
355
  process(CLK_i)
356
  begin
357
    if(CLK_i = '1' and CLK_i'event) then
358
      MUL_SEL_q <= MUL_SEL;
359
    end if;
360
  end process;
361
 
362
  ------------------------------------
363
  -- Shift/Normalize unit
364
  ------------------------------------
365
 
366
  U_SHF : G729A_ASIP_SHFT
367
    port map(
368
      CTRL_i => SC,
369
      SI_i => OPA_i,
370
      SHFT_i => OPB_i(SDLEN-1 downto 0),
371
 
372
      SO_o => SHF_RES,
373
      OVF_o => SHF_OVF
374
    );
375
 
376
  -- pipe register
377
  process(CLK_i)
378
  begin
379
    if(CLK_i = '1' and CLK_i'event) then
380
      SHF_RES_q <= SHF_RES;
381
      SHF_OVF_q <= SHF_OVF;
382
      SHF_SEL_q <= SHF_SEL;
383
    end if;
384
  end process;
385
 
386
  ------------------------------------
387
  -- Logic unit
388
  ------------------------------------
389
 
390
  U_LOG : G729A_ASIP_LOGIC
391
    port map(
392
      CTRL_i => LC,
393
      OPA_i => OPA_i,
394
      OPB_i => OPB_i,
395
 
396
      RES_o => LOG_RES
397
    );
398
 
399
  -- pipe register
400
  process(CLK_i)
401
  begin
402
    if(CLK_i = '1' and CLK_i'event) then
403
      LOG_RES_q <= LOG_RES;
404
      LOG_SEL_q <= LOG_SEL;
405
    end if;
406
  end process;
407
 
408
  ------------------------------------
409
  -- output flags and result mux
410
  ------------------------------------
411
 
412
  -- pipe register
413
  process(CLK_i)
414
  begin
415
    if(CLK_i = '1' and CLK_i'event) then
416
      OPA_q <= OPA_i;
417
      OPB_q <= OPB_i;
418
      OP_q <= OP_i;
419
    end if;
420
  end process;
421
 
422
  -- This encoding allows to set relative priority among the
423
  -- functional unit according to timing requirements.
424
 
425
  process(OP_q,ADD_SEL_q,ADD_RES_q,ADD_OVF_q,MUL_SEL_q,MUL_RES,MUL_OVF,
426
    SHF_SEL_q,SHF_RES_q,SHF_OVF_q,LOG_SEL_q,LOG_RES_q,OPA_q,OPB_q,ACC_i,OVF_i)
427
    variable ZERO_PAD : SDWORD_T := (others => '0');
428
  begin
429
    if(MUL_SEL_q = '1') then
430
      RES <= MUL_RES;
431
      OVF <= MUL_OVF;
432
    elsif(ADD_SEL_q = '1') then
433
      RES <= ADD_RES_q;
434
      OVF <= ADD_OVF_q;
435
    elsif(SHF_SEL_q = '1') then
436
      RES <= SHF_RES_q;
437
      OVF <= SHF_OVF_q;
438
    elsif(LOG_SEL_q = '1') then
439
      RES <= LOG_RES_q;
440
      OVF <= '0';
441
    elsif(OP_q = ALU_MOVA) then
442
      RES <= OPA_q;
443
      OVF <= '0';
444
    elsif(OP_q = ALU_MOVB) then
445
      RES <= OPB_q;
446
      OVF <= '0';
447
    elsif(OP_q = ALU_RACC) then
448
      RES <= ACC_i;
449
      OVF <= '0';
450
    else -- ALU_OVF
451
      RES <= (0 => OVF_i,others => '0');
452
      OVF <= '0';
453
    end if;
454
  end process;
455
 
456
  -- "main" result
457
  RES_o <= RES;
458
 
459
  -- overflow flag
460
  OVF_o <= OVF;
461
 
462
end ARC;

powered by: WebSVN 2.1.0

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