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

Subversion Repositories mpeg2fpga

[/] [mpeg2fpga/] [trunk/] [rtl/] [mpeg2/] [iquant.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kdv
/*
2
 * iquant.v
3
 *
4
 * Copyright (c) 2007 Koen De Vleeschauwer.
5
 *
6
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
7
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
9
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
10
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
11
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
12
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
14
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
15
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16
 * SUCH DAMAGE.
17
 */
18
 
19
`include "timescale.v"
20
 
21
`undef DEBUG
22
//`define DEBUG 1
23
 
24
module intra_quant_matrix(clk, rst, rd_addr, rd_clk_en, dta_out, wr_addr, dta_in, wr_clk_en, wr_en, rst_values, alternate_scan);
25
  input           clk;
26
  input           rst;
27
  input      [5:0]rd_addr;
28
  input           rd_clk_en;
29
  output reg [7:0]dta_out;
30
  input      [5:0]wr_addr;
31
  input      [7:0]dta_in;
32
  input           wr_en;
33
  input           wr_clk_en;
34
  input           rst_values;
35
  input           alternate_scan;
36
 
37
  reg default_values;
38
  wire    [7:0]do;
39
  reg     [7:0]default_do;
40
  reg     [5:0]iquant_wr_addr;
41
  reg          iquant_wr_en;
42
  reg     [7:0]iquant_wr_dta;
43
 
44
  parameter [2:0]
45
    STATE_INIT  = 3'b001,
46
    STATE_CLEAR = 3'b010,
47
    STATE_RUN   = 3'b100;
48
 
49
  reg [2:0]next;
50
  reg [2:0]state;
51
 
52
  /*
53
   * state machine to initialize intra_quantiser_matrix at reset
54
   */
55
 
56
  always @*
57
    case (state)
58
      STATE_INIT:  next = STATE_CLEAR;
59
      STATE_CLEAR: if (iquant_wr_addr == 6'h3f) next = STATE_RUN;
60
                   else next = STATE_CLEAR;
61
      STATE_RUN:   next = STATE_RUN;
62
      default:     next = STATE_INIT;
63
    endcase
64
 
65
  always @(posedge clk)
66
    if (~rst) state <= STATE_INIT;
67
    else state <= next;
68
 
69
  always @(posedge clk)
70
    if (~rst) iquant_wr_en <= 1'b0;
71
    else
72
      case (state)
73
        STATE_INIT:  iquant_wr_en <= 1'b0;
74
        STATE_CLEAR: iquant_wr_en <= 1'b1;
75
        STATE_RUN:   iquant_wr_en <= wr_clk_en && wr_en;
76
        default      iquant_wr_en <= 1'b0;
77
      endcase
78
 
79
  always @(posedge clk)
80
    if (~rst) iquant_wr_addr <= 6'b0;
81
    else
82
      case (state)
83
        STATE_INIT:  iquant_wr_addr <= 6'b0;
84
        STATE_CLEAR: iquant_wr_addr <= iquant_wr_addr + 6'b1;
85
        STATE_RUN:   iquant_wr_addr <= scan_reverse(alternate_scan, wr_addr);
86
        default      iquant_wr_addr <= 6'b0;
87
      endcase
88
 
89
  always @(posedge clk)
90
    if (~rst) iquant_wr_dta <= 8'b0;
91
    else
92
      case (state)
93
        STATE_INIT:  iquant_wr_dta <= 8'b0;
94
        STATE_CLEAR: iquant_wr_dta <= 8'b0;
95
        STATE_RUN:   iquant_wr_dta <= dta_in;
96
        default      iquant_wr_dta <= 8'b0;
97
      endcase
98
 
99
  /* reading */
100
 
101
  always @(posedge clk)
102
    if (~rst) default_do <= 8'b0;
103
    else if (rd_clk_en) default_do <= default_intra_quant(rd_addr);
104
    else default_do <= default_do;
105
 
106
  always @(posedge clk)
107
    if (~rst) dta_out <= 8'b0;
108
    else if (rd_clk_en && default_values) dta_out <= default_do;
109
    else if (rd_clk_en) dta_out <= do;
110
    else dta_out <= dta_out;
111
 
112
  always @(posedge clk)
113
    if (~rst) default_values <= 1;
114
    else if (wr_clk_en && rst_values) default_values <= 1;
115
    else if (wr_clk_en && wr_en && (wr_addr == 6'h3f)) default_values <= 0; // set after last of intra_quant values has been uploaded
116
    else default_values <= default_values;
117
 
118
`include "zigzag_table.v"
119
 
120
 /*
121
    intra block quantisation matrix.
122
    par. 6.3.11: when sequence_header_code is decoded all matrices shall be reset to their default values.
123
    par. 7.3.1: inverse scan for quantization matrix download:
124
    the quantisation matrix is sent in zigzag (scan 0) order, so here we un-zigzag it using scan0_reverse.
125
  */
126
 
127
  dpram_sc
128
    #(.addr_width(6),                                         // number of bits in address bus
129
    .dta_width(8))                                            // number of bits in data bus
130
    intra_quantiser_matrix (
131
    .rst(rst),                                                // reset, active low
132
    .clk(clk),                                                // clock, rising edge trigger
133
    .wr_en(iquant_wr_en),                                     // write enable, active high
134
    .wr_addr(iquant_wr_addr),                                 // write address
135
    .din(iquant_wr_dta),                                      // data input
136
    .rd_en(1'b1),                                             // read enable, active high
137
    .rd_addr(rd_addr),                                        // read address
138
    .dout(do)                                                 // data output
139
    );
140
 
141
  /*
142
    Default intra block quantisation matrix values. par. 6.3.11.
143
  */
144
 
145
  function [7:0]default_intra_quant;
146
    input [5:0]u_v;
147
    begin
148
      casex(u_v)
149
        6'd00: default_intra_quant = 8;
150
        6'd01: default_intra_quant = 16;
151
        6'd02: default_intra_quant = 19;
152
        6'd03: default_intra_quant = 22;
153
        6'd04: default_intra_quant = 26;
154
        6'd05: default_intra_quant = 27;
155
        6'd06: default_intra_quant = 29;
156
        6'd07: default_intra_quant = 34;
157
        6'd08: default_intra_quant = 16;
158
        6'd09: default_intra_quant = 16;
159
        6'd10: default_intra_quant = 22;
160
        6'd11: default_intra_quant = 24;
161
        6'd12: default_intra_quant = 27;
162
        6'd13: default_intra_quant = 29;
163
        6'd14: default_intra_quant = 34;
164
        6'd15: default_intra_quant = 37;
165
        6'd16: default_intra_quant = 19;
166
        6'd17: default_intra_quant = 22;
167
        6'd18: default_intra_quant = 26;
168
        6'd19: default_intra_quant = 27;
169
        6'd20: default_intra_quant = 29;
170
        6'd21: default_intra_quant = 34;
171
        6'd22: default_intra_quant = 34;
172
        6'd23: default_intra_quant = 38;
173
        6'd24: default_intra_quant = 22;
174
        6'd25: default_intra_quant = 22;
175
        6'd26: default_intra_quant = 26;
176
        6'd27: default_intra_quant = 27;
177
        6'd28: default_intra_quant = 29;
178
        6'd29: default_intra_quant = 34;
179
        6'd30: default_intra_quant = 37;
180
        6'd31: default_intra_quant = 40;
181
        6'd32: default_intra_quant = 22;
182
        6'd33: default_intra_quant = 26;
183
        6'd34: default_intra_quant = 27;
184
        6'd35: default_intra_quant = 29;
185
        6'd36: default_intra_quant = 32;
186
        6'd37: default_intra_quant = 35;
187
        6'd38: default_intra_quant = 40;
188
        6'd39: default_intra_quant = 48;
189
        6'd40: default_intra_quant = 26;
190
        6'd41: default_intra_quant = 27;
191
        6'd42: default_intra_quant = 29;
192
        6'd43: default_intra_quant = 32;
193
        6'd44: default_intra_quant = 35;
194
        6'd45: default_intra_quant = 40;
195
        6'd46: default_intra_quant = 48;
196
        6'd47: default_intra_quant = 58;
197
        6'd48: default_intra_quant = 26;
198
        6'd49: default_intra_quant = 27;
199
        6'd50: default_intra_quant = 29;
200
        6'd51: default_intra_quant = 34;
201
        6'd52: default_intra_quant = 38;
202
        6'd53: default_intra_quant = 46;
203
        6'd54: default_intra_quant = 56;
204
        6'd55: default_intra_quant = 69;
205
        6'd56: default_intra_quant = 27;
206
        6'd57: default_intra_quant = 29;
207
        6'd58: default_intra_quant = 35;
208
        6'd59: default_intra_quant = 38;
209
        6'd60: default_intra_quant = 46;
210
        6'd61: default_intra_quant = 56;
211
        6'd62: default_intra_quant = 69;
212
        6'd63: default_intra_quant = 83;
213
      endcase
214
    end
215
  endfunction
216
 
217
`ifdef DEBUG
218
  always @(posedge clk)
219
    if (rd_clk_en && default_values) #0 $display("%m\tread %h from %h (default value)", default_intra_quant(rd_addr), rd_addr);
220
    else if (rd_clk_en) #0 $display("%m\tread %h from %h", do, rd_addr);
221
 
222
  always @(posedge clk)
223
    if (~rst) $display("%m\tset to default values");
224
    else if (wr_clk_en && rst_values) $display("%m\tset to default values");
225
    else if (wr_clk_en && wr_en) $display("%m\tset to uploaded table");
226
 
227
  always @(posedge clk)
228
    if (wr_clk_en && wr_en) #0 $display("%m\twrite %h to %h (was %h)", dta_in, scan_reverse(alternate_scan, wr_addr), wr_addr);
229
 
230
`endif
231
 
232
endmodule
233
 
234
module non_intra_quant_matrix(clk, rst, rd_addr, rd_clk_en, dta_out, wr_addr, dta_in, wr_clk_en, wr_en, rst_values, alternate_scan);
235
  input           clk;
236
  input           rst;
237
  input      [5:0]rd_addr;
238
  input           rd_clk_en;
239
  output reg [7:0]dta_out;
240
  input      [5:0]wr_addr;
241
  input      [7:0]dta_in;
242
  input           wr_clk_en;
243
  input           wr_en;
244
  input           rst_values;
245
  input           alternate_scan;
246
 
247
  reg default_values;
248
  wire [7:0]do;
249
  reg     [5:0]non_iquant_wr_addr;
250
  reg          non_iquant_wr_en;
251
  reg     [7:0]non_iquant_wr_dta;
252
 
253
  parameter [2:0]
254
    STATE_INIT  = 3'b001,
255
    STATE_CLEAR = 3'b010,
256
    STATE_RUN   = 3'b100;
257
 
258
  reg [2:0]next;
259
  reg [2:0]state;
260
 
261
  /*
262
   * state machine to initialize intra_quantiser_matrix at reset
263
   */
264
 
265
  always @*
266
    case (state)
267
      STATE_INIT:  next = STATE_CLEAR;
268
      STATE_CLEAR: if (non_iquant_wr_addr == 6'h3f) next = STATE_RUN;
269
                   else next = STATE_CLEAR;
270
      STATE_RUN:   next = STATE_RUN;
271
      default:     next = STATE_INIT;
272
    endcase
273
 
274
  always @(posedge clk)
275
    if (~rst) state <= STATE_INIT;
276
    else state <= next;
277
 
278
  always @(posedge clk)
279
    if (~rst) non_iquant_wr_en <= 1'b0;
280
    else
281
      case (state)
282
        STATE_INIT:  non_iquant_wr_en <= 1'b0;
283
        STATE_CLEAR: non_iquant_wr_en <= 1'b1;
284
        STATE_RUN:   non_iquant_wr_en <= wr_clk_en && wr_en;
285
        default      non_iquant_wr_en <= 1'b0;
286
      endcase
287
 
288
  always @(posedge clk)
289
    if (~rst) non_iquant_wr_addr <= 6'b0;
290
    else
291
      case (state)
292
        STATE_INIT:  non_iquant_wr_addr <= 6'b0;
293
        STATE_CLEAR: non_iquant_wr_addr <= non_iquant_wr_addr + 6'b1;
294
        STATE_RUN:   non_iquant_wr_addr <= scan_reverse(alternate_scan, wr_addr);
295
        default      non_iquant_wr_addr <= 6'b0;
296
      endcase
297
 
298
  always @(posedge clk)
299
    if (~rst) non_iquant_wr_dta <= 8'b0;
300
    else
301
      case (state)
302
        STATE_INIT:  non_iquant_wr_dta <= 8'b0;
303
        STATE_CLEAR: non_iquant_wr_dta <= 8'b0;
304
        STATE_RUN:   non_iquant_wr_dta <= dta_in;
305
        default      non_iquant_wr_dta <= 8'b0;
306
      endcase
307
 
308
  /* reading */
309
 
310
  always @(posedge clk)
311
    if (rd_clk_en && default_values) dta_out <= 8'd16 ; // Default non intra block quantisation matrix value is 8'd16. par. 6.3.11.
312
    else if (rd_clk_en) dta_out <= do;
313
    else dta_out <= dta_out;
314
 
315
  always @(posedge clk)
316
    if (~rst) default_values <= 1;
317
    else if (wr_clk_en && rst_values) default_values <= 1;
318
    else if (wr_clk_en && wr_en && (wr_addr == 6'h3f)) default_values <= 0; // set after last of non_intra_quant values has been uploaded
319
    else default_values <= default_values;
320
 
321
`include "zigzag_table.v"
322
  /*
323
    non intra block quantisation matrix.
324
    par. 6.3.11: when sequence_header_code is decoded all matrices shall be reset to their default values.
325
    par. 7.3.1: inverse scan for quantization matrix download:
326
    the quantisation matrix is sent in zigzag (scan 0) order, so here we un-zigzag it using scan0_reverse.
327
  */
328
 
329
  dpram_sc
330
    #(.addr_width(6),                                         // number of bits in address bus
331
    .dta_width(8))                                            // number of bits in data bus
332
    non_intra_quantiser_matrix (
333
    .rst(rst),                                                // reset, active low
334
    .clk(clk),                                                // clock, rising edge trigger
335
    .wr_en(non_iquant_wr_en),                                 // write enable, active high
336
    .wr_addr(non_iquant_wr_addr),                             // write address
337
    .din(non_iquant_wr_dta),                                  // data input
338
    .rd_en(1'b1),                                             // read enable, active high
339
    .rd_addr(rd_addr),                                        // read address
340
    .dout(do)                                                 // data output
341
    );
342
 
343
`ifdef DEBUG
344
  always @(posedge clk)
345
    if (rd_clk_en && default_values) #0 $display("%m\tread %h from %h (default value)", 8'd16, rd_addr);
346
    else if (rd_clk_en) #0 $display("%m\tread %h from %h", do, rd_addr);
347
 
348
  always @(posedge clk)
349
    if (~rst) $display("%m\tset to default values");
350
    else if (wr_clk_en && rst_values) $display("%m\tset to default values");
351
    else if (wr_clk_en && wr_en && (wr_addr == 6'h3f)) $display("%m\tset to uploaded table");
352
 
353
  always @(posedge clk)
354
    if (wr_clk_en && wr_en) #0 $display("%m\twrite %h to %h (was %h)", dta_in, scan_reverse(alternate_scan, wr_addr), wr_addr);
355
 
356
`endif
357
 
358
endmodule
359
/* not truncated */

powered by: WebSVN 2.1.0

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