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

Subversion Repositories ima_adpcm_encoder

[/] [ima_adpcm_encoder/] [trunk/] [IMA_ADPCM_Encode.vhd] - Blame information for rev 8

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 7 galland
-- Create Date:    19:34:36 04/November/2008
6 6 galland
-- 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_ARITH.ALL;
33
use IEEE.STD_LOGIC_UNSIGNED.ALL;
34
 
35
entity IMA_ADPCM_Encode is
36
    Port ( clk : in  STD_LOGIC;
37
           reset : in  STD_LOGIC;
38
 
39
           PredictedValue_o : out std_logic_vector(15 downto 0);
40
           StepIndex_o : out std_logic_vector(6 downto 0);
41
           StateRDY : out std_logic;
42
 
43
                          sample : in std_logic_vector(15 downto 0); --don't change it while sample_rdy='1'
44
           sample_rdy : in std_logic; --lower it only when ADPCM_sample_rdy = '1'
45
                          ADPCM_sample : out std_logic_vector(3 downto 0);
46
           ADPCM_sample_rdy : out std_logic
47
                          );
48
end IMA_ADPCM_Encode;
49
 
50
architecture Behavioral of IMA_ADPCM_Encode is
51
        signal PredictedValue : std_logic_vector(15 downto 0);
52
        signal StepIndex : std_logic_vector(6 downto 0);
53
 
54
        component IMA_adpcm_steptable_rom port(
55
                addr0   : in  STD_LOGIC_VECTOR(6 downto 0);
56
                clk   : in  STD_LOGIC;
57
                datao0: out STD_LOGIC_VECTOR(14 downto 0));
58
        end component;
59
 
60
        signal Step : std_logic_vector(14 downto 0);
61
 
62
        signal comp16b_AbtB : std_logic; --A bigger than B
63
        signal delta, diff : std_logic_vector(15 downto 0);
64
   signal State : integer range 0 to 31;
65
begin
66
        StepTable_ROM : IMA_adpcm_steptable_rom port map (
67
                         addr0 => StepIndex,
68
                         clk   => clk,
69
                         datao0=> Step);
70
 
71
 
72
 
73
        process (reset, clk)
74
      variable AdderSub16 : std_logic_vector(15 downto 0);
75
                variable ADPCM_sample2 : std_logic_vector(3 downto 0);
76
        begin
77
                if (reset = '1') then
78
                        State <= 0;
79
         AdderSub16 := (others => '0');
80
                        ADPCM_sample <= x"0";
81
                        ADPCM_sample2 := x"0";
82
         ADPCM_sample_rdy <= '0';
83
 
84
                        PredictedValue <= (others => '0');
85
                        StepIndex <= (others => '0');
86
         PredictedValue_o <= (others => '0');
87
         StepIndex_o <= (others => '0');
88
         StateRDY <= '0';
89
                        delta <= (others => '0');
90
                        diff <= (others => '0');
91
                        comp16b_AbtB <= '0';
92
                elsif (clk='1' and clk'event) then
93
         ADPCM_sample_rdy <= '0';
94
 
95
                        case State is
96
                                when 0 =>
97
               PredictedValue_o <= PredictedValue; StepIndex_o <= StepIndex; StateRDY <= '1';
98
               if (sample_rdy = '1') then State <= 10; StateRDY <= '0'; end if;
99
                                when 10 => --Signed comparison between A:sample and B:PredictedValue
100
               if (sample(15) = '1' and PredictedValue(15) = '0') then
101
                  comp16b_AbtB <= '0'; --sample<0, Pred>=0
102
               elsif (sample(15) = '0' and PredictedValue(15) = '1') then
103
                  comp16b_AbtB <= '1'; --sample>=0, Pred<0
104
               else --both positives or both negatives --> normal comparison
105
                  if (sample > PredictedValue) then comp16b_AbtB <= '1'; else comp16b_AbtB <= '0'; end if;
106
               end if;
107
                                        State <= State + 1;
108
                                when 11 =>
109
                                        if (comp16b_AbtB = '1') then --it really should be beq but a negative zero is as good as a positive one
110
                                                delta <= sample - PredictedValue;
111
                                                ADPCM_sample2(3) := '0';
112
                                        else
113
                                                delta <= PredictedValue - sample;
114
                                                ADPCM_sample2(3) := '1'; --set the sign (negative)
115
                                        end if;
116
                                        State <= State + 1;
117
 
118
                                when 12 => --we've got the rigth Step now
119
                                        diff <= "0000" & Step(14 downto 3);
120
                                        if (delta > '0' & Step) then comp16b_AbtB <= '1'; else comp16b_AbtB <= '0'; end if;
121
                                        State <= State + 1;
122
                                when 13 =>
123
                                        if (comp16b_AbtB = '1') then --delta > step
124
                                                delta <= delta - ('0' & Step);
125
                                                diff <= diff + ('0' & Step);
126
                                                ADPCM_sample2(2) := '1';
127
                                        else
128
                                                ADPCM_sample2(2) := '0';
129
                                        end if;
130
                                        State <= State + 1;
131
 
132
                                when 14 =>
133
                                        if (delta > "00" & Step(14 downto 1)) then comp16b_AbtB <= '1'; else comp16b_AbtB <= '0'; end if;
134
                                        State <= State + 1;
135
                                when 15 =>
136
                                        if (comp16b_AbtB = '1') then --delta > step
137
                                                delta <= delta - ("00" & Step(14 downto 1));
138
                                                diff <= diff + ("00" & Step(14 downto 1));
139
                                                ADPCM_sample2(1) := '1';
140
                                        else
141
                                                ADPCM_sample2(1) := '0';
142
                                        end if;
143
                                        State <= State + 1;
144
 
145
                                when 16 =>
146
                                        if (delta > "000" & Step(14 downto 2)) then comp16b_AbtB <= '1'; else comp16b_AbtB <= '0'; end if;
147
                                        State <= State + 1;
148
                                when 17 =>
149
                                        if (comp16b_AbtB = '1') then --delta > step
150
                                                diff <= diff + ("000" & Step(14 downto 2));
151
                                                ADPCM_sample2(0) := '1';
152
                                        else
153
                                                ADPCM_sample2(0) := '0';
154
                                        end if;
155
               ADPCM_sample_rdy <= '1';
156
                                        State <= State + 1;
157
 
158
                                when 18 =>
159
                                        if (ADPCM_sample2(3) = '1') then --negative
160
                  AdderSub16 := PredictedValue - diff;
161
                                        else
162
                  AdderSub16 := PredictedValue + diff;
163
                                        end if;
164
 
165
                                        --IMA_ADPCMIndexTable[8] =      -1, -1, -1, -1, 2, 4, 6, 8,
166
                                        case ADPCM_sample2(2 downto 0) is
167
                                                when "111" => StepIndex <= StepIndex + "0001000";
168
                                                when "110" => StepIndex <= StepIndex + "0000110";
169
                                                when "101" => StepIndex <= StepIndex + "0000100";
170
                                                when "100" => StepIndex <= StepIndex + "0000010";
171
                                                when others => StepIndex <= StepIndex - "0000001";
172
                                        end case;
173
                                        State <= State + 1;
174
                                when 19 =>
175
                                        if (StepIndex = "1111111") then
176
                                                StepIndex <= (others => '0');
177
                                        elsif (StepIndex > "1011000") then
178
                                                StepIndex <= "1011000";
179
                                        end if;
180
 
181
               --diff is always positive, it becomes negative if we substract Pred - diff == Pred + (-diff)
182
               --so the sign of diff is marked by ADPCM_sample2(3)
183
               if (PredictedValue(15) = '0' and ADPCM_sample2(3) = '0' and AdderSub16(15) = '1') then --both positives result in negative?
184
                  PredictedValue <= '0' & (14 downto 0 => '1'); --positive overflow -> set biggest positive
185
               elsif (PredictedValue(15) = '1' and ADPCM_sample2(3) = '1' and AdderSub16(15) = '0') then --both negatives result positive?
186
                  PredictedValue <= '1' & (14 downto 0 => '0'); --negative overflow -> set biggest negative
187
               else --one positive, the other negative (overflow not possible)
188
                  PredictedValue <= AdderSub16(15 downto 0);
189
               end if;
190
                                        State <= 0; --go wait for new sample ready
191
 
192
                                when others =>
193
                                        State <= 0;
194
                        end case;
195
                        ADPCM_sample <= ADPCM_sample2;
196
                end if;
197
        end process;
198
 
199
end Behavioral;
200
 

powered by: WebSVN 2.1.0

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