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

Subversion Repositories g729a_codec

[/] [g729a_codec/] [trunk/] [VHDL/] [G729A_asip_spc.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
-- G.729a ASIP Sub-Program Controller
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_CODEC_INTF_PKG.all;
39
 
40
entity G729A_ASIP_SPC is
41
  generic(
42
    SIMULATION_ONLY : std_logic := '1'
43
  );
44
  port(
45
    CLK_i : in std_logic;
46
    RST_i : in std_logic;
47
    STRT_i : in std_logic;
48
    OPS_i : in std_logic_vector(3-1 downto 0);
49
    A_BSY_i : in std_logic;
50
    D_BSY_i : in std_logic;
51
 
52
    SADR_o : out unsigned(ALEN-1 downto 0);
53
    A_STRT_o : out std_logic;
54
    A_DMAE_o : out std_logic;
55
    A_ADR_o : out unsigned(ALEN-1 downto 0);
56
    D_STRT_o : out std_logic;
57
    D_WE_o : out std_logic;
58
    ASEL_o : out std_logic_vector(3-1 downto 0);
59
    BLEN_o : out natural range 0 to 2048-1;
60
    BSY_o : out std_logic;
61
    STS_o : out std_logic_vector(3-1 downto 0);
62
    CHKE_o : out std_logic
63
  );
64
end G729A_ASIP_SPC;
65
 
66
architecture ARC of G729A_ASIP_SPC is
67
 
68
  -- sub-program starting addresses
69
 
70
  constant INIT_DEC : natural := 2412;
71
  constant DECOD_LD8A_LOOPINIT : natural := 2971;
72
  constant DECOD_LD8A_LOOPUPDT : natural := 3001;
73
  constant DECOD_LD8A_LOOPEND : natural := 3005;
74
  constant DECOD_LD8A_LOOPBODY : natural := 3015;
75
  constant MAIN_DEC1 : natural := 3361;
76
  constant MAIN_DEC3 : natural := 3374;
77
  constant INIT_COD : natural := 3455;
78
  constant MAIN_COD1 : natural := 8459;
79
  constant BIG_LOOP_INIT : natural := 5140;
80
  constant BIG_LOOP_UPDT : natural := 5146;
81
  constant BIG_LOOP : natural := 5155;
82
  constant UPDATE : natural := 5495;
83
  constant MAIN_COD3 : natural := 8644;
84
  constant DATA_IN : natural := 7645;
85
  constant DEC_DATA_IN : natural := 8695;
86
  constant COD_DATA_OUT : natural := 8663;
87
  constant DEC_DATA_OUT : natural := 8679;
88
  constant STATE_IN : natural := 8719;
89
  constant STATE_OUT : natural := 8743;
90
 
91
  -- operation  I/O type
92
 
93
  constant IO_NONE : std_logic_vector(2-1 downto 0) := "00";
94
  constant IO_READ : std_logic_vector(2-1 downto 0) := "01";
95
  constant IO_WRITE : std_logic_vector(2-1 downto 0) := "10";
96
 
97 3 madsilicon
  constant MAX_IO_COUNT : natural := 2048;
98
 
99 2 madsilicon
  -- sequencer "instruction" type
100
 
101
  type PROG_T is record
102
    -- sub-program starting address
103
    SADR : natural range 0 to 65536-1;
104
    -- I/O mode selector
105
    IO_MODE : std_logic_vector(2-1 downto 0);
106
    -- number of words to transfer when in read/write mode
107 3 madsilicon
    IO_COUNT : natural range 0 to MAX_IO_COUNT-1;
108 2 madsilicon
    -- I/O address selector
109
    IO_ASEL : std_logic_vector(3-1 downto 0);
110
    -- halt when sub-program ends
111
    HALT : std_logic;
112
  end record;
113
 
114
  -- sequencer "program" type
115
 
116
  type PROG_SEQ_T is array (integer range <>) of PROG_T;
117
 
118
  -- sequencer "program" list
119
 
120
  -- The following sub-programs are available:
121
  -- a) "init only" initializes channel state.
122
  -- b) "restore state" restore channel state from ext. memory.
123
  -- c) "run decoding only" performs encoding/decoding of a single packet,
124
  -- and save channel state to ext. memory.
125
  -- d) "run encoding only" performs encoding/decoding of a single packet,
126
  -- and save channel state to ext. memory.
127
  -- e) "run" performs encoding/decoding of a single packet,
128
  -- and save channel state to ext. memory.
129
  -- f) "save state" save channel state to ext. memory.
130
  --
131
  -- Sub-programs "a" and "b" are mutually exclusive: "a" must
132
  -- be used before encoding/decoding the first packet of a  
133
  -- conversation, while "b" must be used on following packets.
134
 
135 3 madsilicon
  constant MAX_PROG : natural := 40;
136
 
137
  constant PROG_SEQ_q : PROG_SEQ_T(0 to MAX_PROG-1) := (
138 2 madsilicon
    --
139
    -- "init only" sub-program
140
    --
141
    (INIT_DEC,IO_NONE,0,"000",'0'),
142
    (INIT_COD,IO_NONE,0,"000",'1'),
143
    --
144
    -- "restore state" sub-program
145
    --
146
    (STATE_IN,IO_WRITE,1679,"100",'1'), -- write-in channel state
147
    --
148
    -- "run decoding-only" sub-program
149
    --
150
    (DEC_DATA_IN,IO_WRITE,5,"010",'0'), -- write-in encoded frame
151
    (MAIN_DEC1,IO_NONE,0,"000",'0'),
152
    (DECOD_LD8A_LOOPINIT,IO_NONE,0,"000",'0'),
153
    (DECOD_LD8A_LOOPBODY,IO_NONE,0,"000",'0'),
154
    (DECOD_LD8A_LOOPUPDT,IO_NONE,0,"000",'0'),
155
    (DECOD_LD8A_LOOPBODY,IO_NONE,0,"000",'0'),
156
    (DECOD_LD8A_LOOPEND,IO_NONE,0,"000",'0'),
157
    (MAIN_DEC3,IO_NONE,0,"000",'0'),
158
    (DEC_DATA_OUT,IO_READ,80,"011",'1'), -- read-out output samples
159
    --
160
    -- "run encoding-only" sub-program
161
    --
162
    (DATA_IN,IO_WRITE,80,"000",'0'), -- write-in input samples
163
    (MAIN_COD1,IO_NONE,0,"000",'0'),
164
    (BIG_LOOP_INIT,IO_NONE,0,"000",'0'),
165
    (BIG_LOOP,IO_NONE,0,"000",'0'),
166
    (BIG_LOOP_UPDT,IO_NONE,0,"000",'0'),
167
    (BIG_LOOP,IO_NONE,0,"000",'0'),
168
    (UPDATE,IO_NONE,0,"000",'0'),
169
    (MAIN_COD3,IO_NONE,0,"000",'0'),
170
    (COD_DATA_OUT,IO_READ,5,"001",'1'), -- read-out encoded frame
171
    --
172
    -- "run" sub-program
173
    --
174
    (DEC_DATA_IN,IO_WRITE,5,"010",'0'), -- write-in encoded frame
175
    (MAIN_DEC1,IO_NONE,0,"000",'0'),
176
    (DECOD_LD8A_LOOPINIT,IO_NONE,0,"000",'0'),
177
    (DECOD_LD8A_LOOPBODY,IO_NONE,0,"000",'0'),
178
    (DECOD_LD8A_LOOPUPDT,IO_NONE,0,"000",'0'),
179
    (DECOD_LD8A_LOOPBODY,IO_NONE,0,"000",'0'),
180
    (DECOD_LD8A_LOOPEND,IO_NONE,0,"000",'0'),
181
    (MAIN_DEC3,IO_NONE,0,"000",'0'),
182
    (DEC_DATA_OUT,IO_READ,80,"011",'0'), -- read-out output samples
183
    (DATA_IN,IO_WRITE,80,"000",'0'), -- write-in input samples
184
    (MAIN_COD1,IO_NONE,0,"000",'0'),
185
    (BIG_LOOP_INIT,IO_NONE,0,"000",'0'),
186
    (BIG_LOOP,IO_NONE,0,"000",'0'),
187
    (BIG_LOOP_UPDT,IO_NONE,0,"000",'0'),
188
    (BIG_LOOP,IO_NONE,0,"000",'0'),
189
    (UPDATE,IO_NONE,0,"000",'0'),
190
    (MAIN_COD3,IO_NONE,0,"000",'0'),
191
    (COD_DATA_OUT,IO_READ,5,"001",'1'), -- read-out encoded frame
192
    --
193
    -- "save state" sub-program
194
    --
195
    (STATE_OUT,IO_READ,1679,"100",'1') -- read-out channel state
196
  );
197
 
198
  -- ASIP memory data-in/out and state buffers address
199
  constant STATE_ADR : natural := 0;
200
  constant DEC_SADR : natural := 1692; -- dec_datain
201
  constant DEC_DADR : natural := 1547; -- dec_synth
202
  constant COD_SADR : natural := 160; -- new_speech
203
  constant COD_DADR : natural := 1692; -- dec_datain
204
 
205
  -- Controller state type
206
 
207
  type TEST_STATE_T is (
208
    TS_IDLE,
209
    TS_NEXT,
210
    TS_WAIT1,
211
    TS_READ,
212
    TS_WRITE,
213
    TS_RUN,
214
    TS_WAIT2,
215
    TS_WAIT3,
216
    TS_WAIT4,
217
    TS_WAIT5,
218
    TS_WAIT6
219
  );
220
 
221
  signal TS,TS_q : TEST_STATE_T;
222 3 madsilicon
  signal PROG_CNT_q : natural range 0 to MAX_PROG-1;
223
  signal PROG_FIRST : natural range 0 to MAX_PROG-1;
224 2 madsilicon
  signal PROG_NEXT : std_logic;
225
  signal PROG_LAST : std_logic;
226
  signal IO_MODE : std_logic_vector(2-1 downto 0);
227 3 madsilicon
  signal IO_COUNT : natural range 0 to MAX_IO_COUNT-1;
228 2 madsilicon
  signal IO_ASEL : std_logic_vector(3-1 downto 0);
229
  signal A_STRT,A_STRT_q : std_logic;
230
  signal D_STRT,D_STRT_q : std_logic;
231
  signal BSY,BSY_q : std_logic;
232
  signal D_WE : std_logic;
233
  signal A_DMAE : std_logic;
234
  signal A_ADR : unsigned(ALEN-1 downto 0);
235
  signal PROG_SUB : PROG_T;
236
  signal STS,STS_q : std_logic_vector(3-1 downto 0);
237
 
238
begin
239
 
240
  ---------------------------------------------------
241
  -- Control FSM
242
  ---------------------------------------------------
243
 
244
  process(CLK_i)
245
  begin
246
    if(CLK_i = '1' and CLK_i'event) then
247
      if(RST_i = '1') then
248
        TS_q <= TS_IDLE;
249
        A_STRT_q <= '0';
250
        D_STRT_q <= '0';
251
        BSY_q <= '0';
252
        STS_q <= STS_IDLE;
253
      else
254
        TS_q <= TS;
255
        A_STRT_q <= A_STRT;
256
        D_STRT_q <= D_STRT;
257
        BSY_q <= BSY;
258
        STS_q <= STS;
259
      end if;
260
    end if;
261
  end process;
262
 
263
  process(TS_q,STRT_i,A_BSY_i,PROG_LAST,D_BSY_i,IO_MODE,IO_ASEL)
264
  begin
265
 
266
    A_STRT <= '0';
267
    D_STRT <= '0';
268
    PROG_NEXT <= '0';
269
    BSY <= '1';
270
    STS <= STS_IDLE;
271
 
272
    case TS_q is
273
 
274
      -- wait for a new packet to be processed
275
      when TS_IDLE =>
276
        if(STRT_i = '1') then
277
          TS <= TS_WAIT4;
278
        else
279
          -- do nothing
280
          BSY <= '0';
281
          TS <= TS_IDLE;
282
        end if;
283
 
284
      -- 1-cycle delay to init. sub-program counter
285
      when TS_WAIT4 =>
286
        TS <= TS_WAIT5;
287
 
288
      -- 1-cycle delay to read sub-prog. ROM
289
      when TS_WAIT5 =>
290
        -- check if first sub-prog. is of I/O-type
291
        if(IO_MODE /= IO_NONE) then
292
           -- start avalon data port operations
293
           D_STRT <= '1';
294
        else
295
          -- start ASIP execution
296
          A_STRT <= '1';
297
        end if;
298
        TS <= TS_WAIT1;
299
 
300
      -- start next sub-program execution
301
      when TS_NEXT =>
302
        if(IO_MODE /= IO_NONE) then
303
           -- start avalon data port operations
304
           D_STRT <= '1';
305
        else
306
          -- start ASIP execution
307
          A_STRT <= '1';
308
        end if;
309
        TS <= TS_WAIT1;
310
 
311
      -- it takes one cycle to get info about
312
      -- sub-program to be executed, so that
313
      -- checks are delayed to TS_WAIT1 state.
314
 
315
      -- check I/O mode
316
      when TS_WAIT1 =>
317
        if(IO_MODE = IO_READ) then
318
          -- sub-program is of READ type
319
          TS <= TS_READ;
320
        elsif(IO_MODE = IO_WRITE) then
321
          -- sub-program is of WRITE type
322
          TS <= TS_WRITE;
323
        else
324
          -- sub-program is if computing type
325
          TS <= TS_WAIT3;
326
        end if;
327
 
328
      when TS_WAIT3 =>
329
        TS <= TS_RUN;
330
 
331
      -- read data out of ASIP memory
332
      when TS_READ =>
333
        if(D_BSY_i = '0') then
334
          TS <= TS_WAIT2;
335
        else
336
          if(IO_ASEL = "001") then
337
            STS <= STS_COD_DOUT;
338
          elsif(IO_ASEL = "011") then
339
            STS <= STS_DEC_DOUT;
340
          else
341
            STS <= STS_STT_DOUT;
342
          end if;
343
          TS <= TS_READ;
344
        end if;
345
 
346
      -- write data into ASIP memory
347
      when TS_WRITE =>
348
        if(D_BSY_i = '0') then
349
          TS <= TS_WAIT2;
350
        else
351
          if(IO_ASEL = "000") then
352
            STS <= STS_COD_DIN;
353
          elsif(IO_ASEL = "010") then
354
            STS <= STS_DEC_DIN;
355
          else
356
            STS <= STS_STT_DIN;
357
          end if;
358
          TS <= TS_WRITE;
359
        end if;
360
 
361
      -- run sub-program not performing I/O
362
      when TS_RUN =>
363
        if(A_BSY_i = '0') then
364
          TS <= TS_WAIT2;
365
        else
366
          STS <= STS_PRUN;
367
          TS <= TS_RUN;
368
        end if;
369
 
370
      when TS_WAIT2 =>
371
        PROG_NEXT <= '1';
372
        if(PROG_LAST = '1') then
373
          TS <= TS_IDLE;
374
        else
375
          TS <= TS_WAIT6;
376
        end if;
377
 
378
      when TS_WAIT6 =>
379
        TS <= TS_NEXT;
380
 
381
    end case;
382
  end process;
383
 
384
  ---------------------------------------------------
385
  -- Program sequencer
386
  ---------------------------------------------------
387
 
388
  -- index of first sub-program to be executed
389
  -- (used to initialize sub-program counter).
390
 
391
  process(OPS_i)
392
  begin
393
    case OPS_i is
394
      when INIT => PROG_FIRST <= 0;
395
      when RUND => PROG_FIRST <= 3;
396
      when RUNC => PROG_FIRST <= 12;
397
      when RUNF => PROG_FIRST <= 21;
398
      when SAVS => PROG_FIRST <= 39;
399
      when others => PROG_FIRST <= 2;
400
    end case;
401
  end process;
402
 
403
  -- sub-program counter
404
  process(CLK_i)
405
  begin
406
    if(CLK_i = '1' and CLK_i'event) then
407
      if(RST_i = '1') then
408
        PROG_CNT_q <= 0;
409
      elsif(STRT_i = '1') then
410
        PROG_CNT_q <= PROG_FIRST;
411
      elsif(PROG_NEXT = '1' and PROG_LAST = '0') then
412
        PROG_CNT_q <= PROG_CNT_q + 1;
413
      end if;
414
    end if;
415
  end process;
416
 
417
  -- "program" memory is used as a sync. ROM indexed
418
  -- by sub-program counter.
419
 
420
  process(CLK_i)
421
  begin
422
    if(CLK_i = '1' and CLK_i'event) then
423
      PROG_SUB <= PROG_SEQ_q(PROG_CNT_q);
424
    end if;
425
  end process;
426
 
427
  -- extract sub-program info
428
 
429
  process(PROG_SUB)
430
  begin
431
    SADR_o <= to_unsigned(PROG_SUB.SADR,ALEN);
432
    IO_MODE <= PROG_SUB.IO_MODE;
433
    IO_COUNT <= PROG_SUB.IO_COUNT;
434
    IO_ASEL <= PROG_SUB.IO_ASEL;
435
    PROG_LAST <= PROG_SUB.HALT;
436
    if(PROG_SUB.IO_MODE = IO_WRITE) then
437
      D_WE <= '1';
438
    else
439
      D_WE <= '0';
440
    end if;
441
    if(PROG_SUB.IO_MODE /= IO_NONE) then
442
      A_DMAE <= '1';
443
    else
444
      A_DMAE <= '0';
445
    end if;
446
  end process;
447
 
448
  -- burst length (for ASIP DMA operations)
449
  BLEN_o <= IO_COUNT;
450
 
451
  -- address selector (for ASIP DMA operations)
452
  ASEL_o <= IO_ASEL;
453
 
454
  -- check enable flag (for ASIP)
455
  CHKE_o <= SIMULATION_ONLY when (IO_MODE = IO_NONE) else '0';
456
 
457
  D_WE_o <= D_WE;
458
 
459
  -- DMA-enable flag
460
  A_DMAE_o <= A_DMAE;
461
 
462
  -- select source/destination (ASIP memory) address for DMA transfers
463
  process(PROG_SUB)
464
    variable N : natural;
465
  begin
466
    case PROG_SUB.IO_ASEL is
467
      when "000" => N := COD_SADR;
468
      when "001" => N := COD_DADR;
469
      when "010" => N := DEC_SADR;
470
      when "011" => N := DEC_DADR;
471
      when others =>  N := STATE_ADR;
472
    end case;
473
    A_ADR <= to_unsigned(N,ALEN);
474
  end process;
475
 
476
  ---------------------------------------------------
477
  -- outputs
478
  ---------------------------------------------------
479
 
480
  A_STRT_o <= A_STRT_q;
481
  A_ADR_o <= A_ADR;
482
  D_STRT_o <= D_STRT_q;
483
  BSY_o <= BSY_q;
484
  STS_o <= STS_q;
485
 
486
end ARC;

powered by: WebSVN 2.1.0

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