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

Subversion Repositories ima_adpcm_enc_dec

[/] [ima_adpcm_enc_dec/] [trunk/] [verilog/] [rtl/] [ima_adpcm_dec.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 motilito
//---------------------------------------------------------------------------------------
2
//      Project:        ADPCM Decoder 
3
// 
4
//      Filename:       ima_adpcm_enc.v                 (February 19, 2010)
5
// 
6
//      Author(s):      Moti Litochevski 
7
// 
8
//      Description:
9
//              This module implements the IMA ADPCM audio decoding algorithm. The input ADPCM 
10
//              encoded data is 4 bits wide and is converted to linearly quantized 16 bits 
11
//              samples for every new input. 
12
//              The decoder module implemented here is not compatible to any particular protocol 
13
//              or file format. The module include optional interface to load the decoder 
14
//              internal state which includes the internal predictor sample and step index 
15
//              provided by the encoder. 
16
//
17
//---------------------------------------------------------------------------------------
18
//
19
//      To Do: 
20
//      - 
21
// 
22
//---------------------------------------------------------------------------------------
23
// 
24
//      Copyright (C) 2010 Moti Litochevski 
25
// 
26
//      This source file may be used and distributed without restriction provided that this 
27
//      copyright statement is not removed from the file and that any derivative work 
28
//      contains the original copyright notice and the associated disclaimer.
29
//
30
//      THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 
31
//      INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND 
32
//      FITNESS FOR A PARTICULAR PURPOSE. 
33
// 
34
//---------------------------------------------------------------------------------------
35
 
36
module ima_adpcm_dec
37
(
38
        clock, reset,
39
        inPCM, inValid,
40
        inReady, inPredictSamp,
41
        inStepIndex,  inStateLoad,
42
        outSamp, outValid
43
);
44
//---------------------------------------------------------------------------------------
45
// global inputs 
46
input                   reset;
47
input                   clock;
48
 
49
// input interface 
50
input   [3:0]    inPCM;                  // input PCM nibble 
51
input                   inValid;                // input valid flag 
52
output                  inReady;                // input ready indication 
53
// optional decoder state load 
54
input   [15:0]   inPredictSamp;  // predictor sample load input 
55
input   [6:0]    inStepIndex;    // step index load input 
56
input                   inStateLoad;    // internal state load input control 
57
 
58
// output interface 
59
output  [15:0]   outSamp;                // output sample value 
60
output                  outValid;               // output valid flag 
61
 
62
//---------------------------------------------------------------------------------------
63
// registers output 
64
reg [15:0] outSamp;
65
reg outValid;
66
 
67
// internals 
68
reg [18:0] predictorSamp;
69
wire [18:0] dequantSamp;
70
reg predValid;
71
wire [19:0] prePredSamp;
72
reg [14:0] stepSize;     // unsigned 
73
reg [6:0] stepIndex;     // unsigned 
74
reg [4:0] stepDelta;
75
wire [7:0] preStepIndex;
76
wire [16:0] preOutSamp;
77
 
78
//---------------------------------------------------------------------------------------
79
// module implementation 
80
// main decoder process 
81
always @ (posedge clock or posedge reset)
82
begin
83
        if (reset)
84
        begin
85
                predictorSamp <= 19'b0;
86
                predValid <= 1'b0;
87
        end
88
        else if (inStateLoad)
89
        begin
90
                // load predictor sample value 
91
                predictorSamp <= {inPredictSamp, 3'b0};
92
                // clear the internal delayed flag 
93
                predValid <= 1'b0;
94
        end
95
        else if (inValid)
96
        begin
97
                // check updated predictor sample saturation conditions 
98
                if (prePredSamp[19] && !prePredSamp[18])
99
                        // negative saturation 
100
                        predictorSamp <= {1'b1, 18'b0};
101
                else if (!prePredSamp[19] && prePredSamp[18])
102
                        // positive saturation 
103
                        predictorSamp <= {1'b0, {18{1'b1}}};
104
                else
105
                        // no saturation 
106
                        predictorSamp <= prePredSamp[18:0];
107
 
108
                // sign that predictor value is valid 
109
                predValid <= 1'b1;
110
        end
111
        else
112
                predValid <= 1'b0;
113
end
114
// calculate the de-quantized difference value 
115
assign dequantSamp = (inPCM[2] ? {1'b0, stepSize, 3'b0} : 19'b0) +
116
                     (inPCM[1] ? {2'b0, stepSize, 2'b0} : 19'b0) +
117
                     (inPCM[0] ? {3'b0, stepSize, 1'b0} : 19'b0) +
118
                                 {4'b0, stepSize};
119
// updated predictor output sample 
120
assign prePredSamp = inPCM[3] ? ({predictorSamp[18], predictorSamp} - {1'b0, dequantSamp}) :
121
                                ({predictorSamp[18], predictorSamp} + {1'b0, dequantSamp});
122
 
123
// input interface is busy while updating the step size 
124
assign inReady = ~predValid;
125
 
126
// calculate the output sample before saturation 
127
assign preOutSamp = {predictorSamp[18], predictorSamp[18:3]} + predictorSamp[2];
128
 
129
// output interface 
130
always @ (posedge clock or posedge reset)
131
begin
132
        if (reset)
133
        begin
134
                outSamp <= 16'b0;
135
                outValid <= 1'b0;
136
        end
137
        else if (predValid)
138
        begin
139
                // output is taken from the predictor output with saturation check 
140
                if (!preOutSamp[16] && preOutSamp[15])
141
                        // positive saturation condition 
142
                        outSamp <= {1'b0, {15{1'b1}}};
143
                else if (preOutSamp[16] && !preOutSamp[15])
144
                        // negative saturation condition 
145
                        outSamp <= {1'b1, 15'b0};
146
                else
147
                        outSamp <= preOutSamp[15:0];
148
 
149
                // sign output is valid 
150
                outValid <= 1'b1;
151
        end
152
        else
153
                outValid <= 1'b0;
154
end
155
 
156
// quantizer index adaptation lookup table 
157
always @ (inPCM)
158
begin
159
        case (inPCM[2:0])
160
                3'd0:   stepDelta <= 5'd31;             // = -1 
161
                3'd1:   stepDelta <= 5'd31;             // = -1 
162
                3'd2:   stepDelta <= 5'd31;             // = -1 
163
                3'd3:   stepDelta <= 5'd31;             // = -1 
164
                3'd4:   stepDelta <= 5'd2;              // = +2
165
                3'd5:   stepDelta <= 5'd4;              // = +4
166
                3'd6:   stepDelta <= 5'd6;              // = +6
167
                3'd7:   stepDelta <= 5'd8;              // = +8
168
        endcase
169
end
170
// calculate the new index value before saturation 
171
assign preStepIndex = {1'b0, stepIndex} + {{3{stepDelta[4]}}, stepDelta};
172
 
173
// update the step index with saturation checking 
174
always @ (posedge clock or posedge reset)
175
begin
176
        if (reset)
177
                stepIndex <= 7'b0;
178
        else if (inStateLoad)
179
                stepIndex <= inStepIndex;
180
        else if (inValid)
181
        begin
182
                // check is the updated step value should be saturated 
183
                if (preStepIndex[7])
184
                        stepIndex <= 7'd0;
185
                else if (preStepIndex[6:0] > 7'd88)
186
                        stepIndex <= 7'd88;
187
                else
188
                        stepIndex <= preStepIndex[6:0];
189
        end
190
end
191
 
192
// quantizer step size lookup table 
193
always @ (posedge clock)
194
begin
195
        case (stepIndex)
196
                7'd0:           stepSize <= 15'd7;
197
                7'd1:           stepSize <= 15'd8;
198
                7'd2:           stepSize <= 15'd9;
199
                7'd3:           stepSize <= 15'd10;
200
                7'd4:           stepSize <= 15'd11;
201
                7'd5:           stepSize <= 15'd12;
202
                7'd6:           stepSize <= 15'd13;
203
                7'd7:           stepSize <= 15'd14;
204
                7'd8:           stepSize <= 15'd16;
205
                7'd9:           stepSize <= 15'd17;
206
                7'd10:          stepSize <= 15'd19;
207
                7'd11:          stepSize <= 15'd21;
208
                7'd12:          stepSize <= 15'd23;
209
                7'd13:          stepSize <= 15'd25;
210
                7'd14:          stepSize <= 15'd28;
211
                7'd15:          stepSize <= 15'd31;
212
                7'd16:          stepSize <= 15'd34;
213
                7'd17:          stepSize <= 15'd37;
214
                7'd18:          stepSize <= 15'd41;
215
                7'd19:          stepSize <= 15'd45;
216
                7'd20:          stepSize <= 15'd50;
217
                7'd21:          stepSize <= 15'd55;
218
                7'd22:          stepSize <= 15'd60;
219
                7'd23:          stepSize <= 15'd66;
220
                7'd24:          stepSize <= 15'd73;
221
                7'd25:          stepSize <= 15'd80;
222
                7'd26:          stepSize <= 15'd88;
223
                7'd27:          stepSize <= 15'd97;
224
                7'd28:          stepSize <= 15'd107;
225
                7'd29:          stepSize <= 15'd118;
226
                7'd30:          stepSize <= 15'd130;
227
                7'd31:          stepSize <= 15'd143;
228
                7'd32:          stepSize <= 15'd157;
229
                7'd33:          stepSize <= 15'd173;
230
                7'd34:          stepSize <= 15'd190;
231
                7'd35:          stepSize <= 15'd209;
232
                7'd36:          stepSize <= 15'd230;
233
                7'd37:          stepSize <= 15'd253;
234
                7'd38:          stepSize <= 15'd279;
235
                7'd39:          stepSize <= 15'd307;
236
                7'd40:          stepSize <= 15'd337;
237
                7'd41:          stepSize <= 15'd371;
238
                7'd42:          stepSize <= 15'd408;
239
                7'd43:          stepSize <= 15'd449;
240
                7'd44:          stepSize <= 15'd494;
241
                7'd45:          stepSize <= 15'd544;
242
                7'd46:          stepSize <= 15'd598;
243
                7'd47:          stepSize <= 15'd658;
244
                7'd48:          stepSize <= 15'd724;
245
                7'd49:          stepSize <= 15'd796;
246
                7'd50:          stepSize <= 15'd876;
247
                7'd51:          stepSize <= 15'd963;
248
                7'd52:          stepSize <= 15'd1060;
249
                7'd53:          stepSize <= 15'd1166;
250
                7'd54:          stepSize <= 15'd1282;
251
                7'd55:          stepSize <= 15'd1411;
252
                7'd56:          stepSize <= 15'd1552;
253
                7'd57:          stepSize <= 15'd1707;
254
                7'd58:          stepSize <= 15'd1878;
255
                7'd59:          stepSize <= 15'd2066;
256
                7'd60:          stepSize <= 15'd2272;
257
                7'd61:          stepSize <= 15'd2499;
258
                7'd62:          stepSize <= 15'd2749;
259
                7'd63:          stepSize <= 15'd3024;
260
                7'd64:          stepSize <= 15'd3327;
261
                7'd65:          stepSize <= 15'd3660;
262
                7'd66:          stepSize <= 15'd4026;
263
                7'd67:          stepSize <= 15'd4428;
264
                7'd68:          stepSize <= 15'd4871;
265
                7'd69:          stepSize <= 15'd5358;
266
                7'd70:          stepSize <= 15'd5894;
267
                7'd71:          stepSize <= 15'd6484;
268
                7'd72:          stepSize <= 15'd7132;
269
                7'd73:          stepSize <= 15'd7845;
270
                7'd74:          stepSize <= 15'd8630;
271
                7'd75:          stepSize <= 15'd9493;
272
                7'd76:          stepSize <= 15'd10442;
273
                7'd77:          stepSize <= 15'd11487;
274
                7'd78:          stepSize <= 15'd12635;
275
                7'd79:          stepSize <= 15'd13899;
276
                7'd80:          stepSize <= 15'd15289;
277
                7'd81:          stepSize <= 15'd16818;
278
                7'd82:          stepSize <= 15'd18500;
279
                7'd83:          stepSize <= 15'd20350;
280
                7'd84:          stepSize <= 15'd22385;
281
                7'd85:          stepSize <= 15'd24623;
282
                7'd86:          stepSize <= 15'd27086;
283
                7'd87:          stepSize <= 15'd29794;
284
                7'd88:          stepSize <= 15'd32767;
285
                default:        stepSize <= 15'd32767;
286
        endcase
287
end
288
 
289
endmodule
290
//---------------------------------------------------------------------------------------
291
//                                              Th.. Th.. Th.. That's all folks !!!
292
//---------------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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