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

Subversion Repositories ima_adpcm_encoder

[/] [ima_adpcm_encoder/] [trunk/] [tb_IMA_ADPCM_top.vhd] - Blame information for rev 9

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 galland
----------------------------------------------------------------------------------
2
-- Company:       VISENGI S.L. (www.visengi.com)
3
-- Engineer:      Victor Lopez Lorenzo (victor.lopez (at) visengi (dot) com)
4
-- 
5
-- Create Date:    19:34:36 04/November/2008
6
-- Project Name:   IMA ADPCM Encoder
7
-- Tool versions:  Xilinx ISE 9.2i
8
-- Description: 
9
--
10
-- Description: This project features a full-hardware sound compressor using the well known algorithm IMA ADPCM.
11
--              The core acts as a slave WISHBONE device. The output is perfectly compatible with any sound player
12
--              with the IMA ADPCM codec (included by default in every Windows). Includes a testbench that takes
13
--              an uncompressed PCM 16 bits Mono WAV file and outputs an IMA ADPCM compressed WAV file.
14
--              Compression ratio is fixed for IMA-ADPCM, being 4:1.
15
--
16
--
17 7 galland
-- LICENSE TERMS: GNU GENERAL PUBLIC LICENSE Version 3
18
--
19
--     That is you may use it only in NON-COMMERCIAL projects.
20
--     You are only required to include in the copyrights/about section 
21
--     that your system contains a "IMA ADPCM Encoder (C) VISENGI S.L. under GPL license"
22 6 galland
--     This holds also in the case where you modify the core, as the resulting core
23
--     would be a derived work.
24
--     Also, we would like to know if you use this core in a project of yours, just an email will do.
25
--
26 7 galland
--    Please take good note of the disclaimer section of the GPL license, as we don't
27 6 galland
--    take any responsability for anything that this core does.
28
----------------------------------------------------------------------------------
29
 
30
LIBRARY ieee;
31
USE ieee.std_logic_1164.ALL;
32
USE ieee.std_logic_unsigned.all;
33
USE ieee.std_logic_arith.all;
34
use ieee.numeric_std.all;
35
 
36
ENTITY tb_IMA_ADPCM_top_vhd IS
37
END tb_IMA_ADPCM_top_vhd;
38
 
39
ARCHITECTURE behavior OF tb_IMA_ADPCM_top_vhd IS
40
 
41
        -- Component Declaration for the Unit Under Test (UUT)
42
        COMPONENT IMA_ADPCM_top
43
        PORT(
44
                wb_clk_i : IN std_logic;
45
                wb_rst_i : IN std_logic;
46
                wb_cyc_i : IN std_logic;
47
                wb_stb_i : IN std_logic;
48
                wb_we_i : IN std_logic;
49
                wb_adr_i : IN std_logic_vector(1 downto 0);
50
                wb_dat_i : IN std_logic_vector(15 downto 0);
51
                wb_dat_o : OUT std_logic_vector(15 downto 0);
52
                wb_ack_o : OUT std_logic
53
                );
54
        END COMPONENT;
55
 
56
        --Inputs
57
        SIGNAL wb_clk_i :  std_logic := '0';
58
        SIGNAL wb_rst_i :  std_logic := '0';
59
        SIGNAL wb_cyc_i :  std_logic := '0';
60
        SIGNAL wb_stb_i :  std_logic := '0';
61
        SIGNAL wb_we_i :  std_logic := '0';
62
        SIGNAL wb_adr_i :  std_logic_vector(1 downto 0) := (others=>'0');
63
        SIGNAL wb_dat_i :  std_logic_vector(15 downto 0) := (others=>'0');
64
 
65
        --Outputs
66
        SIGNAL wb_dat_o :  std_logic_vector(15 downto 0);
67
        SIGNAL wb_ack_o :  std_logic;
68
 
69
 
70
   type ByteFileType is file of character;
71
   file infile : ByteFileType open read_mode is "input.wav";
72
   file outfile : ByteFileType open write_mode is "output.wav";
73
 
74
   signal bytes, bytesout : std_logic_vector(23 downto 0);
75
 
76
   signal SamplesPerSec : std_logic_vector(15 downto 0);
77
   signal SecondsToCompress : std_logic_vector(31 downto 0);
78
BEGIN
79
 
80
        -- Instantiate the Unit Under Test (UUT)
81
        uut: IMA_ADPCM_top PORT MAP(
82
                wb_clk_i => wb_clk_i,
83
                wb_rst_i => wb_rst_i,
84
                wb_cyc_i => wb_cyc_i,
85
                wb_stb_i => wb_stb_i,
86
                wb_we_i => wb_we_i,
87
                wb_adr_i => wb_adr_i,
88
                wb_dat_i => wb_dat_i,
89
                wb_dat_o => wb_dat_o,
90
                wb_ack_o => wb_ack_o
91
        );
92
 
93
   wb_rst_i <= '1', '0' after 40 ns; --active high reset
94
 
95
        Clocking : process --50 MHz -> T = 20 ns
96
        begin
97
                wb_clk_i <= '1'; wait for 20 ns;
98
                wb_clk_i <= '0'; wait for 20 ns;
99
        end process;
100
 
101
 
102
 
103
 
104
   Control_Compressor : process (wb_clk_i, wb_rst_i)
105
      variable byte : character;
106
      variable WaitACK, EndSignaled : std_logic;
107
      variable State : integer;
108
      variable data : std_logic_vector(15 downto 0);
109
      variable DataBytes : std_logic_vector(31 downto 0);
110
   begin
111
      if (wb_rst_i = '1') then
112
         bytes <= (others => '0');
113
         bytesout <= (others => '0');
114
         State := 0;
115
         WaitACK := '0';
116
         EndSignaled := '0';
117
         wb_cyc_i <= '0';
118
         wb_stb_i <= '0';
119
         wb_we_i <= '0';
120
         wb_adr_i <= (others => '0');
121
         wb_dat_i <= (others => '0');
122
         data := (others => '0');
123
      elsif (wb_clk_i = '1' and wb_clk_i'event) then
124
         if (WaitACK = '1') then
125
            if (wb_ack_o = '1') then
126
               wb_cyc_i <= '0'; wb_stb_i <= '0'; wb_we_i <= '0';
127
               data := wb_dat_o; WaitACK := '0';
128
            end if;
129
         end if;
130
 
131
         if (WaitACK = '0') then
132
            case State is
133
               when 0 =>
134
                  --read the WAV header in search of SamplesPerSecond (bytes 19h and 18h in little endian)
135
                  --and DataBytes (bytes 39h,38h,37h,36h in little endian) to get SecondsToCompress as DataBytes/2/SamplesPerSecond
136
                  for i in 0 to 57 loop --PCM header has 58 bytes
137
                     read(infile, byte);
138
                     case i is
139
                        when 25 => --x"19" => --MSB of SamplesPerSecond
140
                           SamplesPerSec(15 downto 8) <= conv_std_logic_vector(character'pos(byte),8);
141
                        when 24 => --x"18" => --LSB of SamplesPerSecond
142
                           SamplesPerSec(7 downto 0) <= conv_std_logic_vector(character'pos(byte),8);
143
 
144
                        when 7 => --x"39" => --1stMSB of DataBytes
145
                           DataBytes(31 downto 24) := conv_std_logic_vector(character'pos(byte),8);
146
                        when 6 => --x"38" => --2ndMSB of DataBytes
147
                           DataBytes(23 downto 16) := conv_std_logic_vector(character'pos(byte),8);
148
                        when 5 => --x"37" => --3rdMSB of DataBytes
149
                           DataBytes(15 downto 8) := conv_std_logic_vector(character'pos(byte),8);
150
                        when 4 => --x"36" => --4thMSB of DataBytes
151
                           DataBytes(7 downto 0) := conv_std_logic_vector(character'pos(byte),8);
152
                        when others =>
153
                           null;
154
                     end case;
155
                  end loop;
156
                  EndSignaled := '0';
157
                  bytes <= (others => '0');
158
                  bytesout <= (others => '0');
159
                  DataBytes := DataBytes - x"32"; --with fmt18 and fact4 chunks
160
                  State := State + 1;
161
               when 1 =>
162
                  SecondsToCompress <= conv_std_logic_vector((conv_integer(DataBytes)/conv_integer(SamplesPerSec))/2,32);
163
                  wb_adr_i <= "01"; wb_dat_i <= SamplesPerSec; wb_we_i <= '1'; WaitACK := '1';
164
                  State := State + 1;
165
               when 2 =>
166
                  wb_adr_i <= "10"; wb_dat_i <= SecondsToCompress(15 downto 0); wb_we_i <= '1'; WaitACK := '1';
167
                  State := State + 1;
168
               when 3 =>
169
                  wb_adr_i <= "00"; wb_dat_i <= x"8000"; wb_we_i <= '1'; WaitACK := '1';
170
                  State := State + 1;
171
               when 4 =>
172
                  wb_adr_i <= "00"; wb_we_i <= '0'; WaitACK := '1'; State := State + 1;
173
               when 5 =>
174
                  if (data(15) = '0') then --compression end
175
                     File_Close(infile); --finished
176
                     report "Input bytes = " & integer'image(conv_integer(bytes)) & " at time " & time'image(now);
177
                     report "Output bytes = " & integer'image(conv_integer(bytesout)) & " at time " & time'image(now);
178
                     File_Close(outfile); --finished
179
                     report "-----------> Compression Finished OK!" severity FAILURE; --everything went fine, it's just to stop the simulation
180
                  else
181
                     if (data(0) = '1') then --output word ready
182
                        wb_adr_i <= "11"; wb_we_i <= '0'; WaitACK := '1';
183
                        State := 15; --write word
184
                     elsif (data(1) = '1' and EndSignaled = '0') then --ready for new input sample AND haven't reached the input file's EOF?
185
                        if (bytes < DataBytes(23 downto 0) and not endfile(infile)) then
186
                           --send two bytes to the WAV compressor
187
                           read(infile,byte); --1st byte ----> goes in LSBs!!! (little endian)
188
                           wb_dat_i(7 downto 0) <= conv_std_logic_vector(character'pos(byte),8);
189
                           read(infile,byte); --2nd byte
190
                           wb_dat_i(15 downto 8) <= conv_std_logic_vector(character'pos(byte),8);
191
                           bytes <= bytes + x"2";
192
                           wb_adr_i <= "11"; wb_we_i <= '1'; WaitACK := '1'; State := State - 1;
193
                        else --already sent the number of bytes indicated in PCM WAV header
194
                           wb_adr_i <= "00"; wb_dat_i <= x"0000"; wb_we_i <= '1'; WaitACK := '1'; --signal finish compression
195
                           EndSignaled := '1'; State := State - 1; --there will be still bytes to write but don't get in here again (EndSignaled='1')
196
                        end if;
197
                     else
198
                        wb_adr_i <= "00"; wb_we_i <= '0'; WaitACK := '1'; --read again and stay in this state
199
                     end if;
200
                  end if;
201
 
202
 
203
               when 15 => --write word
204
                  write(outfile, character'val(conv_integer(data(15 downto 8))));
205
                  write(outfile, character'val(conv_integer(data(7 downto 0))));
206
                  bytesout <= bytesout + x"2";
207
                  wb_adr_i <= "00"; wb_we_i <= '0'; WaitACK := '1'; State := 5; --go back and continue
208
 
209
               when others =>
210
                  State := 0;
211
            end case;
212
         end if;
213
         if (WaitACK = '1') then wb_cyc_i <= '1'; wb_stb_i <= '1'; end if;
214
      end if;
215
   end process Control_Compressor;
216
 
217
END;

powered by: WebSVN 2.1.0

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