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

powered by: WebSVN 2.1.0

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