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

Subversion Repositories mpeg2fpga

[/] [mpeg2fpga/] [trunk/] [bench/] [iverilog/] [testbench.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kdv
/*
2
 * testbench.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
 
20
/*
21
 * testbench - mpeg2 decoder test bench
22
 */
23
 
24
`include "timescale.v"
25
 
26
/* max number of bytes in stream.dat mpeg2 stream */
27
`define MAX_STREAM_LENGTH 4194304
28
 
29
/* clk at 75 MHz */
30
`define CLK_PERIOD 13.3
31
 
32
/* mem_clk at 125 MHz */
33
`define MEMCLK_PERIOD 8.0
34
 
35
/* dot_clk at 27 MHz */
36
`define VIDCLK_PERIOD 37.0
37
 
38
`undef DEBUG
39
//`define DEBUG 1
40
 
41
/* write (lxt) dumpfile of simulation run */
42
`undef DEBUG_DUMP
43
`define DEBUG_DUMP 1
44
 
45
// write rgb+sync output to file tvout_0.ppm or tv_out_1.ppm, alternately.
46
`undef DUMP_TVOUT
47
`define DUMP_TVOUT 1
48
 
49
module testbench();
50
  /* clocks and reset */
51
  reg        clk;     // system clock
52
  reg        mem_clk; // clock for memory controller and dram
53
  reg        dot_clk; // video dot clock
54
  reg   [7:0]rst_ff;
55
  wire       rst;
56
  /* mpeg2 stream input */
57
  reg   [7:0]stream_data;
58
  reg        stream_valid;
59
  /* status output */
60
  wire       busy;
61
  wire       error;
62
  wire       interrupt;
63
  /* video output */
64
  wire       pixel_en;
65
  wire       h_sync;
66
  wire       v_sync;
67
  wire  [7:0]r; // red
68
  wire  [7:0]g; // green
69
  wire  [7:0]b; // blue
70
  wire  [7:0]y; // luminance
71
  wire  [7:0]u; // chrominance
72
  wire  [7:0]v; // chrominance
73
  /* register file interface */
74
  reg   [3:0]reg_addr;
75
  reg        reg_wr_en;
76
  reg  [31:0]reg_dta_in;
77
  reg        reg_rd_en;
78
  wire [31:0]reg_dta_out;
79
  /* memory controller interface */
80
  wire  [1:0]mem_req_rd_cmd;
81
  wire [21:0]mem_req_rd_addr;
82
  wire [63:0]mem_req_rd_dta;
83
  wire       mem_req_rd_en;
84
  wire       mem_req_rd_valid;
85
  wire [63:0]mem_res_wr_dta;
86
  wire       mem_res_wr_en;
87
  wire       mem_res_wr_almost_full;
88
  wire [33:0]testpoint;
89
 
90
  /*
91
   * clocks
92
   */
93
 
94
  initial
95
    begin
96
      clk = 1'b0;
97
      #(`CLK_PERIOD/2);
98
      forever #(`CLK_PERIOD/2) clk = ~clk;
99
    end
100
 
101
  initial
102
    begin
103
      mem_clk = 1'b0;
104
      #(`MEMCLK_PERIOD/2);
105
      forever #(`MEMCLK_PERIOD/2) mem_clk = ~mem_clk;
106
    end
107
 
108
  initial
109
    begin
110
      dot_clk = 1'b0;
111
      #(`VIDCLK_PERIOD/2);
112
      forever #(`VIDCLK_PERIOD/2) dot_clk = ~dot_clk;
113
    end
114
 
115
  /*
116
   * read mpeg2 clip from file "stream.dat"
117
   */
118
 
119
  integer    i;
120
  reg   [7:0]stream[0:`MAX_STREAM_LENGTH];
121
 
122
  initial #0
123
    begin
124
      $readmemh("stream.dat", stream, 0, `MAX_STREAM_LENGTH);
125
      rst_ff    = 8'b0;
126
      i         = 0;
127
      stream_data  = 0;
128
      stream_valid = 0;
129
      reg_dta_in = 32'd0;
130
      reg_addr  = 4'b0;
131
      reg_wr_en = 0;
132
      reg_rd_en = 0;
133
    end
134
 
135
  assign rst = rst_ff[7];
136
 
137
  always @(posedge clk)
138
    rst_ff <= {rst_ff[6:0], 1'b1};
139
 
140
  /* timing simulation: add #1 = 1 ns hold time to stream_data and stream_valid */
141
 
142
  always @(posedge clk)
143
    if (~rst)
144
      begin
145
        i <= 0;
146
        stream_data <= #1 0;
147
        stream_valid <= #1 1'b0;
148
      end
149
    else if (~busy && (i < `MAX_STREAM_LENGTH) && (^stream [i] !== 1'bx))
150
      begin
151
        i <= i + 1;
152
        stream_data <= #1 stream [i];
153
        stream_valid <= #1 1'b1;
154
      end
155
    else
156
      begin
157
        i <= i;
158
        stream_data <= #1 0;
159
        stream_valid <= #1 1'b0;
160
      end
161
 
162
   /*
163
    * mpeg2 decoder
164
    */
165
 
166
  mpeg2video mpeg2 (
167
    .clk(clk),
168
    .mem_clk(mem_clk),
169
    .dot_clk(dot_clk),
170
    .rst(rst),
171
    .stream_data(stream_data),
172
    .stream_valid(stream_valid),
173
    .reg_addr(reg_addr),
174
    .reg_wr_en(reg_wr_en),
175
    .reg_dta_in(reg_dta_in),
176
    .reg_rd_en(reg_rd_en),
177
    .reg_dta_out(reg_dta_out),
178
    .busy(busy),
179
    .error(error),
180
    .interrupt(interrupt),
181
    .watchdog_rst(),
182
    .r(r),
183
    .g(g),
184
    .b(b),
185
    .y(y),
186
    .u(u),
187
    .v(v),
188
    .pixel_en(pixel_en),
189
    .h_sync(h_sync),
190
    .v_sync(v_sync),
191
    .c_sync(),
192
    .mem_req_rd_cmd(mem_req_rd_cmd),
193
    .mem_req_rd_addr(mem_req_rd_addr),
194
    .mem_req_rd_dta(mem_req_rd_dta),
195
    .mem_req_rd_en(mem_req_rd_en),
196
    .mem_req_rd_valid(mem_req_rd_valid),
197
    .mem_res_wr_dta(mem_res_wr_dta),
198
    .mem_res_wr_en(mem_res_wr_en),
199
    .mem_res_wr_almost_full(mem_res_wr_almost_full),
200
    .testpoint(testpoint),
201
    .testpoint_dip(4'h0),
202
    .testpoint_dip_en(1'b1)
203
    );
204
 
205
   /*
206
    * Memory controller
207
    */
208
 
209
    mem_ctl mem_ctl (
210
    .clk(mem_clk),
211
    .rst(rst),
212
    .mem_req_rd_cmd(mem_req_rd_cmd),
213
    .mem_req_rd_addr(mem_req_rd_addr),
214
    .mem_req_rd_dta(mem_req_rd_dta),
215
    .mem_req_rd_en(mem_req_rd_en),
216
    .mem_req_rd_valid(mem_req_rd_valid),
217
    .mem_res_wr_dta(mem_res_wr_dta),
218
    .mem_res_wr_en(mem_res_wr_en),
219
    .mem_res_wr_almost_full(mem_res_wr_almost_full)
220
    );
221
 
222
`ifdef DEBUG_DUMP
223
  /*
224
   * begin vcd dump
225
   */
226
 
227
  initial
228
    // generate vcd dump, for use with gtkwave 
229
    // set IVERILOG_DUMPER=lxt environment variable for lxt format (smaller)
230
    // export IVERILOG_DUMPER=lxt
231
    begin
232
      $dumpfile("testbench.lxt");
233
//      $dumpvars;
234
//        $dumpvars(0, testbench.mpeg2.resample.resample_dta);
235
//        $dumpvars(0, testbench.mpeg2.resample.resample_bilinear);
236
        $dumpvars(0, testbench.mpeg2.probe);
237
    end
238
`endif
239
 
240
`ifdef DUMP_TVOUT
241
 
242
/*
243
  Writes rgb output to portable pixmap graphics file "tv_out_xxxx.ppm".
244
 */
245
 
246
  integer fp = 0;
247
  reg [31:0]fname_cnt = "0000";
248
  integer v_sync_seen = 1;
249
  integer pixel_count = 0;
250
  integer img_count = 0;
251
 
252
  wire [11:0]syncgen_horizontal_resolution;
253
  wire [11:0]syncgen_horizontal_sync_start;
254
  wire [11:0]syncgen_horizontal_sync_end;
255
  wire [11:0]syncgen_horizontal_length;
256
  wire [11:0]dot_vertical_resolution;
257
  wire [11:0]dot_vertical_sync_start;
258
  wire [11:0]dot_vertical_sync_end;
259
  wire [11:0]dot_vertical_length;
260
  wire       dot_interlaced;
261
  wire [11:0]syncgen_horizontal_halfline;
262
 
263
  /*
264
   * Note: these assignments have to be modified if synthesis assigns other names to these nets.
265
   * Use commands such as "find signals -r *name*" at the simulator prompt to find suitable candidates.
266
   */
267
 
268
  assign syncgen_horizontal_resolution = testbench.mpeg2.syncgen_intf.syncgen_horizontal_resolution;
269
  assign syncgen_horizontal_sync_start = testbench.mpeg2.syncgen_intf.syncgen_horizontal_sync_start;
270
  assign syncgen_horizontal_sync_end   = testbench.mpeg2.syncgen_intf.syncgen_horizontal_sync_end;
271
  assign syncgen_horizontal_length     = testbench.mpeg2.syncgen_intf.syncgen_horizontal_length;
272
  assign syncgen_horizontal_halfline   = testbench.mpeg2.syncgen_intf.syncgen_horizontal_halfline;
273
  assign dot_vertical_resolution       = testbench.mpeg2.syncgen_intf.dot_vertical_resolution;
274
  assign dot_vertical_sync_start       = testbench.mpeg2.syncgen_intf.dot_vertical_sync_start;
275
  assign dot_vertical_sync_end         = testbench.mpeg2.syncgen_intf.dot_vertical_sync_end;
276
  assign dot_vertical_length           = testbench.mpeg2.syncgen_intf.dot_vertical_length;
277
  assign dot_interlaced                = testbench.mpeg2.syncgen_intf.dot_interlaced;
278
 
279
  always @(posedge dot_clk)
280
    begin
281
      if (v_sync) v_sync_seen = 1;
282
 
283
      if (v_sync_seen && pixel_en && (^syncgen_horizontal_length !== 1'bx) && (^dot_vertical_length !== 1'bx))
284
        begin
285
          // pad and close old dump file
286
          if (fp != 0)
287
            begin
288
              while (pixel_count < (syncgen_horizontal_length + 1) * (dot_vertical_length + 1))
289
                begin
290
                  $fwrite(fp, " 48  48  48\n");
291
                  pixel_count = pixel_count + 1;
292
                end
293
              $fclose(fp);
294
            end
295
          v_sync_seen = 0;
296
          pixel_count = 0;
297
          // open new dump file
298
          fp=$fopen({"tv_out_", fname_cnt, ".ppm"}, "w");
299
          /* implement a counter for string "fname_cnt" */
300
          if (fname_cnt[7:0] != "9")
301
            fname_cnt[7:0] = fname_cnt[7:0] + 1;
302
          else
303
            begin
304
              fname_cnt[7:0] = "0";
305
              if (fname_cnt[15:8] != "9")
306
                fname_cnt[15:8] = fname_cnt[15:8] + 1;
307
              else
308
                begin
309
                  fname_cnt[15:8] = "0";
310
                  if (fname_cnt[23:16] != "9")
311
                    fname_cnt[23:16] = fname_cnt[23:16] + 1;
312
                  else
313
                    begin
314
                      fname_cnt[23:16] = "0";
315
                      if (fname_cnt[31:24] != "9")
316
                        fname_cnt[31:24] = fname_cnt[31:24] + 1;
317
                      else
318
                        fname_cnt[31:24] = "0";
319
                    end
320
                end
321
            end
322
          // write header
323
          if (fp != 0)
324
            begin
325
              $fwrite(fp, "P3\n"); // Portable pixmap, ascii.
326
              $timeformat(-3, 2, " ms", 8);
327
              $fwrite(fp, "# picture %0d  @ %t\n", img_count, $time);
328
              $timeformat(-9, 2, " ns", 20);
329
              $fwrite(fp, "# horizontal resolution %0d sync_start %0d sync_end %0d length %0d\n", syncgen_horizontal_resolution, syncgen_horizontal_sync_start, syncgen_horizontal_sync_end, syncgen_horizontal_length);
330
              $fwrite(fp, "# vertical resolution %0d sync_start %0d sync_end %0d length %0d\n", dot_vertical_resolution, dot_vertical_sync_start, dot_vertical_sync_end, dot_vertical_length);
331
              $fwrite(fp, "# interlaced %0d halfline %0d\n", dot_interlaced, syncgen_horizontal_halfline);
332
              img_count = img_count + 1;
333
              $fwrite(fp, "%5d %5d 255\n", syncgen_horizontal_length + 1, dot_vertical_length + 1);
334
            end
335
        end
336
 
337
      // write rgb values to dump file
338
      if (fp != 0)
339
        begin
340
          if (pixel_en && ((^r === 1'bx) || (^g === 1'bx) || (^g === 1'bx)))
341
            begin
342
              $fwrite(fp, "    255   0   0\n"); // draw pixel in vivid red if r, g or b undefined
343
            end
344
          else if (pixel_en) $fwrite(fp, "%3d %3d %3d\n", r, g, b);
345
          else if (v_sync || h_sync) $fwrite(fp, "  0   0   0\n");
346
          else $fwrite(fp, " 48  48  48\n");
347
          pixel_count = pixel_count + 1;
348
        end
349
    end
350
 
351
`endif
352
 
353
`ifdef DEBUG
354
  always @(posedge clk)
355
    if (error)
356
      begin
357
        $display("%m\terror asserted\n");
358
//        $stop;
359
      end
360
 
361
  always @(posedge clk)
362
    $strobe("%m\tcnt: %h stream_data: 8'h%h stream_valid: %d rst: %d busy: %d interrupt: %d reg_dta_out: %h", i, stream_data, stream_valid, rst, busy, interrupt, reg_dta_out);
363
`endif
364
 
365
endmodule
366
/* not truncated */

powered by: WebSVN 2.1.0

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