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_enc.v] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 motilito
//---------------------------------------------------------------------------------------
2
//      Project:        ADPCM Encoder 
3
// 
4
//      Filename:       ima_adpcm_enc.v                 (February 18, 2010)
5
// 
6
//      Author(s):      Moti Litochevski 
7
// 
8
//      Description:
9
//              This module implements the IMA ADPCM audio encoding algorithm. The input samples 
10
//              interface is 16 bits wide. ADPCM encoded data output is 4 bits wide and is sent 
11
//              for every new input sample. 
12
//
13
//---------------------------------------------------------------------------------------
14
//
15
//      To Do: 
16
//      - 
17
// 
18
//---------------------------------------------------------------------------------------
19
// 
20
//      Copyright (C) 2010 Moti Litochevski 
21
// 
22
//      This source file may be used and distributed without restriction provided that this 
23
//      copyright statement is not removed from the file and that any derivative work 
24
//      contains the original copyright notice and the associated disclaimer.
25
//
26
//      THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 
27
//      INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND 
28
//      FITNESS FOR A PARTICULAR PURPOSE. 
29
// 
30
//---------------------------------------------------------------------------------------
31
 
32
module ima_adpcm_enc
33
(
34
        clock, reset,
35
        inSamp, inValid,
36
        inReady,
37
        outPCM, outValid,
38
        outPredictSamp, outStepIndex
39
);
40
//---------------------------------------------------------------------------------------
41
// global inputs 
42
input                   reset;
43
input                   clock;
44
 
45
// input interface 
46
input   [15:0]   inSamp;                 // input sample 
47
input                   inValid;                // input valid flag 
48
output                  inReady;                // input ready indication  
49
 
50
// output interface 
51
output  [3:0]    outPCM;                 // ADPCM encoded value 
52
output                  outValid;               // output valid flag 
53
output  [15:0]   outPredictSamp; // predictor sample value output 
54
output  [6:0]    outStepIndex;   // step index value output 
55
 
56
//---------------------------------------------------------------------------------------
57
// registers output 
58
reg [3:0] outPCM;
59
reg outValid, inReady;
60
 
61
// internals 
62
reg [2:0] pcmSq;
63
reg [19:0] sampDiff, prePredSamp;
64
reg [18:0] predictorSamp, dequantSamp;
65
reg [3:0] prePCM;
66
reg [14:0] stepSize;     // unsigned 
67
reg [6:0] stepIndex;     // unsigned 
68
reg [4:0] stepDelta;
69
wire [7:0] preStepIndex;
70
 
71
// constant declarations 
72
// main state machine 
73
`define PCM_IDLE        3'd0
74
`define PCM_SIGN        3'd1
75
`define PCM_BIT2        3'd2
76
`define PCM_BIT1        3'd3
77
`define PCM_BIT0        3'd4
78
`define PCM_DONE        3'd5
79
 
80
//---------------------------------------------------------------------------------------
81
// module implementation 
82
// encoder main control process 
83
always @ (posedge clock or posedge reset)
84
begin
85
        if (reset)
86
        begin
87
                pcmSq <= 3'b0;
88
                sampDiff <= 20'b0;
89
                predictorSamp <= 19'b0;
90
                dequantSamp <= 19'b0;
91
                prePCM <= 4'b0;
92
                inReady <= 1'b0;
93
        end
94
        else
95
        begin
96
                case (pcmSq)
97
                        // waiting for a new input sample 
98
                        `PCM_IDLE:
99
                                // on a new input sample calculate the difference between the input 
100
                                // sample and predictor output 
101
                                if (inValid)
102
                                begin
103
                                        // compute the difference between the current predictor output and the input 
104
                                        // sample with extended width to prevent any wrapping.
105
                                        sampDiff <= {inSamp[15], inSamp, 3'b0} - {predictorSamp[18], predictorSamp};
106
 
107
                                        // sign that input is not ready 
108
                                        inReady <= 1'b0;
109
 
110
                                        // switch to next state 
111
                                        pcmSq <= `PCM_SIGN;
112
                                end
113
                                else
114
                                        // sign that input is ready 
115
                                        inReady <= 1'b1;
116
 
117
                        // check the difference sign and set PCM sign bit accordingly 
118
                        `PCM_SIGN:
119
                                begin
120
                                        // check the difference sign 
121
                                        if (sampDiff[19])
122
                                        begin
123
                                                // set PCM sign bit and negate the calculated sample difference 
124
                                                prePCM[3] <= 1'b1;
125 3 motilito
                                                sampDiff <= (~sampDiff) + 20'd1;
126 2 motilito
                                        end
127
                                        else
128
                                                // clear the PCM sign bit 
129
                                                prePCM[3] <= 1'b0;
130
 
131
                                        // prepare the de-quantizer sample 
132
                                        dequantSamp <= {4'b0, stepSize};
133
 
134
                                        // switch to next state 
135
                                        pcmSq <= `PCM_BIT2;
136
                                end
137
 
138
                        // determine quantizer bit 2 value 
139
                        `PCM_BIT2:
140
                                begin
141
                                        // check if the difference is larger than step size 
142
                                        if (sampDiff[19:3] >= {2'b0, stepSize})
143
                                        begin
144
                                                // bit 2 of PCM nibble is set 
145
                                                prePCM[2] <= 1'b1;
146
                                                // update the difference value and the de-quantizer value 
147
                                                sampDiff[19:3] <= sampDiff[19:3] - {2'b0, stepSize};
148
                                                dequantSamp <= dequantSamp + {1'b0, stepSize, 3'b0};
149
                                        end
150
                                        else
151
                                                // bit 2 of PCM nibble is zero 
152
                                                prePCM[2] <= 1'b0;
153
 
154
                                        // switch to next state 
155
                                        pcmSq <= `PCM_BIT1;
156
                                end
157
 
158
                        // determine quantizer bit 1 value 
159
                        `PCM_BIT1:
160
                                begin
161
                                        // check if the difference is larger than step size 
162
                                        if (sampDiff[19:2] >= {3'b0, stepSize})
163
                                        begin
164
                                                // bit 1 of PCM nibble is set 
165
                                                prePCM[1] <= 1'b1;
166
                                                // update the difference value and the de-quantizer value 
167
                                                sampDiff[19:2] <= sampDiff[19:2] - {3'b0, stepSize};
168
                                                dequantSamp <= dequantSamp + {2'b0, stepSize, 2'b0};
169
                                        end
170
                                        else
171
                                                // bit 1 of PCM nibble is zero 
172
                                                prePCM[1] <= 1'b0;
173
 
174
                                        // switch to next state 
175
                                        pcmSq <= `PCM_BIT0;
176
                                end
177
 
178
                        // determine quantizer bit 0 value 
179
                        `PCM_BIT0:
180
                                begin
181
                                        // check if the difference is larger than step size 
182
                                        if (sampDiff[19:1] >= {4'b0, stepSize})
183
                                        begin
184
                                                // bit 0 of PCM nibble is set 
185
                                                prePCM[0] <= 1'b1;
186
                                                // update the de-quantizer value 
187
                                                dequantSamp <= dequantSamp + {3'b0, stepSize, 1'b0};
188
                                        end
189
                                        else
190
                                                // bit 0 of PCM nibble is zero 
191
                                                prePCM[0] <= 1'b0;
192
 
193
                                        // switch to next state 
194
                                        pcmSq <= `PCM_DONE;
195
                                end
196
 
197
                        // check saturation condition on new predictor sample and update it 
198
                        `PCM_DONE:
199
                                begin
200
                                        // check the new predictor output saturation conditions 
201
                                        if (prePredSamp[19] && !prePredSamp[18])
202
                                                // negative saturation 
203
                                                predictorSamp <= {1'b1, 18'b0};
204
                                        else if (!prePredSamp[19] && prePredSamp[18])
205
                                                // positive saturation 
206
                                                predictorSamp <= {1'b0, {18{1'b1}}};
207
                                        else
208
                                                // no saturation 
209
                                                predictorSamp <= prePredSamp[18:0];
210
 
211
                                        // sign that input is ready 
212
                                        inReady <= 1'b1;
213
 
214
                                        // return to idle state 
215
                                        pcmSq <= `PCM_IDLE;
216
                                end
217
 
218
                        // unused states 
219
                        default:        pcmSq <= `PCM_IDLE;
220
                endcase
221
        end
222
end
223
// internal state output assignment 
224
assign outPredictSamp = predictorSamp[18:3] + predictorSamp[2];
225
assign outStepIndex = stepIndex;
226
 
227
// calculate the update predictor sample before it is updated by the state machine 
228
always @ (prePCM or predictorSamp or dequantSamp)
229
begin
230
        if (prePCM[3])
231
                prePredSamp <= {predictorSamp[18], predictorSamp} - {1'b0, dequantSamp};
232
        else
233
                prePredSamp <= {predictorSamp[18], predictorSamp} + {1'b0, dequantSamp};
234
end
235
 
236
// output interface 
237
always @ (posedge clock or posedge reset)
238
begin
239
        if (reset)
240
        begin
241
                outPCM <= 4'b0;
242
                outValid <= 1'b0;
243
        end
244
        else if (pcmSq == `PCM_DONE)
245
        begin
246
                outPCM <= prePCM;
247
                outValid <= 1'b1;
248
        end
249
        else
250
                outValid <= 1'b0;
251
end
252
 
253
// quantizer index adaptation lookup table 
254
always @ (prePCM)
255
begin
256
        case (prePCM[2:0])
257
                3'd0:   stepDelta <= 5'd31;             // = -1 
258
                3'd1:   stepDelta <= 5'd31;             // = -1 
259
                3'd2:   stepDelta <= 5'd31;             // = -1 
260
                3'd3:   stepDelta <= 5'd31;             // = -1 
261
                3'd4:   stepDelta <= 5'd2;
262
                3'd5:   stepDelta <= 5'd4;
263
                3'd6:   stepDelta <= 5'd6;
264
                3'd7:   stepDelta <= 5'd8;
265
        endcase
266
end
267
// calculate the new index value before saturation 
268
assign preStepIndex = {1'b0, stepIndex} + {{3{stepDelta[4]}}, stepDelta};
269
 
270
// update the step index with saturation checking 
271
always @ (posedge clock or posedge reset)
272
begin
273
        if (reset)
274
                stepIndex <= 7'b0;
275
        else if (pcmSq == `PCM_DONE)
276
        begin
277
                // check is the updated step value should be saturated 
278
                if (preStepIndex[7])
279
                        stepIndex <= 7'd0;
280
                else if (preStepIndex[6:0] > 7'd88)
281
                        stepIndex <= 7'd88;
282
                else
283
                        stepIndex <= preStepIndex[6:0];
284
        end
285
end
286
 
287
// quantizer step size lookup table 
288
always @ (posedge clock)
289
begin
290
        case (stepIndex)
291
                7'd0:           stepSize <= 15'd7;
292
                7'd1:           stepSize <= 15'd8;
293
                7'd2:           stepSize <= 15'd9;
294
                7'd3:           stepSize <= 15'd10;
295
                7'd4:           stepSize <= 15'd11;
296
                7'd5:           stepSize <= 15'd12;
297
                7'd6:           stepSize <= 15'd13;
298
                7'd7:           stepSize <= 15'd14;
299
                7'd8:           stepSize <= 15'd16;
300
                7'd9:           stepSize <= 15'd17;
301
                7'd10:          stepSize <= 15'd19;
302
                7'd11:          stepSize <= 15'd21;
303
                7'd12:          stepSize <= 15'd23;
304
                7'd13:          stepSize <= 15'd25;
305
                7'd14:          stepSize <= 15'd28;
306
                7'd15:          stepSize <= 15'd31;
307
                7'd16:          stepSize <= 15'd34;
308
                7'd17:          stepSize <= 15'd37;
309
                7'd18:          stepSize <= 15'd41;
310
                7'd19:          stepSize <= 15'd45;
311
                7'd20:          stepSize <= 15'd50;
312
                7'd21:          stepSize <= 15'd55;
313
                7'd22:          stepSize <= 15'd60;
314
                7'd23:          stepSize <= 15'd66;
315
                7'd24:          stepSize <= 15'd73;
316
                7'd25:          stepSize <= 15'd80;
317
                7'd26:          stepSize <= 15'd88;
318
                7'd27:          stepSize <= 15'd97;
319
                7'd28:          stepSize <= 15'd107;
320
                7'd29:          stepSize <= 15'd118;
321
                7'd30:          stepSize <= 15'd130;
322
                7'd31:          stepSize <= 15'd143;
323
                7'd32:          stepSize <= 15'd157;
324
                7'd33:          stepSize <= 15'd173;
325
                7'd34:          stepSize <= 15'd190;
326
                7'd35:          stepSize <= 15'd209;
327
                7'd36:          stepSize <= 15'd230;
328
                7'd37:          stepSize <= 15'd253;
329
                7'd38:          stepSize <= 15'd279;
330
                7'd39:          stepSize <= 15'd307;
331
                7'd40:          stepSize <= 15'd337;
332
                7'd41:          stepSize <= 15'd371;
333
                7'd42:          stepSize <= 15'd408;
334
                7'd43:          stepSize <= 15'd449;
335
                7'd44:          stepSize <= 15'd494;
336
                7'd45:          stepSize <= 15'd544;
337
                7'd46:          stepSize <= 15'd598;
338
                7'd47:          stepSize <= 15'd658;
339
                7'd48:          stepSize <= 15'd724;
340
                7'd49:          stepSize <= 15'd796;
341
                7'd50:          stepSize <= 15'd876;
342
                7'd51:          stepSize <= 15'd963;
343
                7'd52:          stepSize <= 15'd1060;
344
                7'd53:          stepSize <= 15'd1166;
345
                7'd54:          stepSize <= 15'd1282;
346
                7'd55:          stepSize <= 15'd1411;
347
                7'd56:          stepSize <= 15'd1552;
348
                7'd57:          stepSize <= 15'd1707;
349
                7'd58:          stepSize <= 15'd1878;
350
                7'd59:          stepSize <= 15'd2066;
351
                7'd60:          stepSize <= 15'd2272;
352
                7'd61:          stepSize <= 15'd2499;
353
                7'd62:          stepSize <= 15'd2749;
354
                7'd63:          stepSize <= 15'd3024;
355
                7'd64:          stepSize <= 15'd3327;
356
                7'd65:          stepSize <= 15'd3660;
357
                7'd66:          stepSize <= 15'd4026;
358
                7'd67:          stepSize <= 15'd4428;
359
                7'd68:          stepSize <= 15'd4871;
360
                7'd69:          stepSize <= 15'd5358;
361
                7'd70:          stepSize <= 15'd5894;
362
                7'd71:          stepSize <= 15'd6484;
363
                7'd72:          stepSize <= 15'd7132;
364
                7'd73:          stepSize <= 15'd7845;
365
                7'd74:          stepSize <= 15'd8630;
366
                7'd75:          stepSize <= 15'd9493;
367
                7'd76:          stepSize <= 15'd10442;
368
                7'd77:          stepSize <= 15'd11487;
369
                7'd78:          stepSize <= 15'd12635;
370
                7'd79:          stepSize <= 15'd13899;
371
                7'd80:          stepSize <= 15'd15289;
372
                7'd81:          stepSize <= 15'd16818;
373
                7'd82:          stepSize <= 15'd18500;
374
                7'd83:          stepSize <= 15'd20350;
375
                7'd84:          stepSize <= 15'd22385;
376
                7'd85:          stepSize <= 15'd24623;
377
                7'd86:          stepSize <= 15'd27086;
378
                7'd87:          stepSize <= 15'd29794;
379
                7'd88:          stepSize <= 15'd32767;
380
                default:        stepSize <= 15'd32767;
381
        endcase
382
end
383
 
384
endmodule
385
//---------------------------------------------------------------------------------------
386
//                                              Th.. Th.. Th.. That's all folks !!!
387
//---------------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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