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

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [BFM/] [src/] [axis_video_frame/] [axis_video_frame_bfm_pkg.sv] - Blame information for rev 34

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 34 qaztronic
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
//// Copyright (C) 2015 Authors and OPENCORES.ORG                 ////
4
////                                                              ////
5
//// This source file may be used and distributed without         ////
6
//// restriction provided that this copyright statement is not    ////
7
//// removed from the file and that any derivative work contains  ////
8
//// the original copyright notice and the associated disclaimer. ////
9
////                                                              ////
10
//// This source file is free software; you can redistribute it   ////
11
//// and/or modify it under the terms of the GNU Lesser General   ////
12
//// Public License as published by the Free Software Foundation; ////
13
//// either version 2.1 of the License, or (at your option) any   ////
14
//// later version.                                               ////
15
////                                                              ////
16
//// This source is distributed in the hope that it will be       ////
17
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
18
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
19
//// PURPOSE.  See the GNU Lesser General Public License for more ////
20
//// details.                                                     ////
21
////                                                              ////
22
//// You should have received a copy of the GNU Lesser General    ////
23
//// Public License along with this source; if not, download it   ////
24
//// from http://www.opencores.org/lgpl.shtml                     ////
25
////                                                              ////
26
//////////////////////////////////////////////////////////////////////
27
 
28
 
29
package axis_video_frame_bfm_pkg;
30
 
31
  typedef enum
32
  {
33
    RIGHT_DOWN,
34
    RIGHT_UP,
35
    LEFT_DOWN,
36
    LEFT_UP
37
  } avf_direction_t;
38
 
39
  typedef struct
40
  {
41
    avf_direction_t direction;
42
    int             delay = 0;
43
  } avf_tile_config_t;
44
 
45
  // --------------------------------------------------------------------
46
  //
47
  import q_pkg::*;
48
  import video_frame_pkg::*;
49
 
50
 
51
  // --------------------------------------------------------------------
52
  //
53
  class avf_config_class;
54
 
55
    int     width;
56
    int     height;
57
    int     bytes_per_pixel;
58
    int     bits_per_pixel;
59
    int     pixels_per_clk;
60
    string  name;
61
    int     vertical_blanking;
62
 
63
    avf_tile_config_t tile[];
64
 
65
 
66
    //--------------------------------------------------------------------
67
    function
68
      new
69
      (
70
        int               width,
71
        int               height,
72
        int               bytes_per_pixel,
73
        int               bits_per_pixel,
74
        int               pixels_per_clk,
75
        string            name,
76
        int               vertical_blanking,
77
        avf_tile_config_t tile[]
78
      );
79
 
80
      this.width              = width;
81
      this.height             = height;
82
      this.bytes_per_pixel    = bytes_per_pixel;
83
      this.bits_per_pixel     = bits_per_pixel;
84
      this.pixels_per_clk     = pixels_per_clk;
85
      this.name               = name;
86
      this.vertical_blanking  = vertical_blanking;
87
      this.tile               = tile;
88
 
89
      $display("^^^ %16.t | %m", $time);
90
 
91
    endfunction: new
92
 
93
 
94
    // --------------------------------------------------------------------
95
    //
96
    task automatic
97
      avf_direction
98
      (
99
        input     avf_direction_t direction,
100
        output    frame_coordinate_t inc
101
      );
102
 
103
        case(direction)
104
          RIGHT_DOWN: inc = '{ 1,  1};
105
          RIGHT_UP:   inc = '{ 1, -1};
106
          LEFT_DOWN:  inc = '{-1,  1};
107
          LEFT_UP:    inc = '{-1, -1};
108
          default:    $display("^^^ %16.t | %m | ERROR!!! Incorrect AVF direction.", $time );
109
        endcase
110
 
111
    endtask: avf_direction
112
 
113
 
114
    // --------------------------------------------------------------------
115
    //
116
    task automatic
117
      avf_calculate
118
      (
119
        input       avf_direction_t direction,
120
        output      frame_coordinate_t start,
121
        output      frame_coordinate_t inc,
122
        output int  x_end,
123
        output int  y_end,
124
        output int  x_eol
125
      );
126
 
127
        case(direction)
128
          RIGHT_DOWN: start = '{0         , 0           };
129
          RIGHT_UP:   start = '{0         , height - 1  };
130
          LEFT_DOWN:  start = '{width - 1 , 0           };
131
          LEFT_UP:    start = '{width - 1 , height - 1  };
132
          default:    $display("^^^ %16.t | %m | [%04d, %04d] | ERROR!!! Incorrect AVF direction.", $time, start.x, start.y );
133
        endcase
134
 
135
        avf_direction(direction, inc);
136
 
137
        x_end = (start.x + (width * inc.x));
138
        y_end = (start.y + (height * inc.y));
139
 
140
        inc.x *= pixels_per_clk;  //  increment stride by number of outputs
141
        x_eol = x_end - inc.x;
142
 
143
    endtask: avf_calculate
144
 
145
  endclass: avf_config_class
146
 
147
 
148
  //--------------------------------------------------------------------
149
  //
150
  class avf_tx_bfm_class #(BYTES_PER_PIXEL, PIXELS_PER_CLK, AVF_U)
151
    extends blocking_transmission_q_class #(video_frame_class);
152
 
153
    localparam AVF_N = BYTES_PER_PIXEL * PIXELS_PER_CLK;  // data bus width in bytes
154
    localparam AVF_B = BYTES_PER_PIXEL * 8;               // bits per pixel on TDATA
155
 
156
    virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_if;
157
 
158
    string  avf_name              = "";
159
    string  avf_type              = "";
160
 
161
    avf_config_class c_h;
162
    avf_tile_config_t tile;
163
    video_frame_class f_h;
164
 
165
    // --------------------------------------------------------------------
166
    //
167
    function void axis_default;
168
 
169
      avf_axis_if.cb_m.tvalid  <= 0;
170
      avf_axis_if.cb_m.tdata   <= 'hx;
171
      avf_axis_if.cb_m.tlast   <= 'hx;
172
      avf_axis_if.cb_m.tuser   <= 'hx;
173
 
174
    endfunction: axis_default
175
 
176
 
177
    // --------------------------------------------------------------------
178
    //
179
    task automatic
180
      output_pixels(input int l, input int p);
181
 
182
        for(int i = 0; i < PIXELS_PER_CLK; i++)
183
          avf_axis_if.cb_m.tdata[i*AVF_B +: AVF_B] <= f_h.lines[l].pixel[p + i];
184
 
185
    endtask: output_pixels
186
 
187
 
188
    // --------------------------------------------------------------------
189
    //
190
    task automatic
191
      avf_tx(input avf_direction_t direction, input int unsigned  avf_delay);
192
 
193
        frame_coordinate_t start;
194
        frame_coordinate_t inc;
195
        int x_end;
196
        int y_end;
197
        int x_eol;
198
        int pixel_count = 0;
199
        int l;
200
        int p;
201
 
202
        c_h.avf_calculate
203
        (
204
          .start(start),
205
          .direction(direction),
206
          .inc(inc),
207
          .x_end(x_end),
208
          .y_end(y_end),
209
          .x_eol(x_eol)
210
        );
211
 
212
        @(avf_axis_if.cb_m);
213
 
214
        repeat(avf_delay) @(avf_axis_if.cb_m);
215
 
216
        avf_axis_if.cb_m.tvalid   <= 1;   // assert first pixel
217
        avf_axis_if.cb_m.tuser[0] <= 1;
218
        avf_axis_if.cb_m.tuser[1] <= 1;
219
        avf_axis_if.cb_m.tuser[2] <= 0;
220
        avf_axis_if.cb_m.tlast    <= 0;
221
 
222
        output_pixels(start.y, start.x);
223
 
224
        for(l = start.y; y_end != l; l = l + inc.y)
225
          for(p = start.x; x_end != p; p = p + inc.x)
226
          begin
227
 
228
            if((l == start.y) & (p == start.x))   // first pixel already asserted
229
              continue;
230
 
231
            @(avf_axis_if.cb_m iff avf_axis_if.cb_m.tready)
232
            begin
233
              avf_axis_if.cb_m.tvalid  <= 1;
234
              output_pixels(l, p);
235
 
236
              avf_axis_if.cb_m.tuser[0] <= 0;
237
 
238
              if(p == start.x)
239
                avf_axis_if.cb_m.tuser[1] <= 1;
240
              else
241
                avf_axis_if.cb_m.tuser[1] <= 0;
242
 
243
              if(p == x_eol)
244
                avf_axis_if.cb_m.tlast <= 1;
245
              else
246
                avf_axis_if.cb_m.tlast <= 0;
247
 
248
              if((l == y_end - 1) && (p == x_eol))
249
                avf_axis_if.cb_m.tuser[2] <= 1;
250
            end
251
          end
252
 
253
        @(avf_axis_if.cb_m)
254
          axis_default();
255
 
256
    endtask: avf_tx
257
 
258
 
259
    // --------------------------------------------------------------------
260
    //
261
    task
262
      avf_fork_tx;
263
 
264
      fork
265
        avf_tx(tile.direction, tile.delay);
266
      join_none
267
 
268
      #0;
269
 
270
    endtask: avf_fork_tx
271
 
272
 
273
    // --------------------------------------------------------------------
274
    //
275
    event tx_frame_done;
276
 
277
    task automatic
278
      transmit(ref Q_T tr_h);
279
 
280
      f_h = tr_h;
281
 
282
      avf_fork_tx();
283
      wait fork;
284
 
285
      repeat(c_h.vertical_blanking) @(avf_axis_if.cb_m);
286
      ->tx_frame_done;
287
 
288
    endtask: transmit
289
 
290
 
291
    //--------------------------------------------------------------------
292
    //
293
    function
294
      new
295
      (
296
        int                                     index,
297
        avf_config_class                        c_h,
298
        input string                            avf_type,
299
        virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_if
300
      );
301
 
302
      super.new();
303
 
304
      this.avf_axis_if = avf_axis_if;
305
 
306
      this.c_h = c_h;
307
      this.tile = c_h.tile[index];
308
      this.avf_name = $sformatf("%s%0d", c_h.name, index);
309
      this.avf_type = avf_type.toupper();
310
 
311
      f_h = new();
312
 
313
      f_h.init
314
      (
315
        .pixels_per_line(c_h.width),
316
        .lines_per_frame(c_h.height),
317
        .bits_per_pixel(c_h.bits_per_pixel),
318
        .name(avf_name)
319
      );
320
 
321
      axis_default();
322
 
323
    endfunction: new
324
 
325
 
326
  // --------------------------------------------------------------------
327
  //
328
  endclass: avf_tx_bfm_class
329
 
330
 
331
  //--------------------------------------------------------------------
332
  //
333
  class avf_rx_bfm_class #(BYTES_PER_PIXEL, PIXELS_PER_CLK, AVF_U)
334
    extends blocking_receiver_q_class #(video_frame_class);
335
 
336
    localparam AVF_N = BYTES_PER_PIXEL * PIXELS_PER_CLK;  // data bus width in bytes
337
    localparam AVF_B = BYTES_PER_PIXEL * 8;               // bits per pixel on TDATA
338
 
339
    virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_if;
340
 
341
    string  avf_name              = "";
342
    string  avf_type              = "";
343
 
344
    avf_config_class c_h;
345
    avf_tile_config_t tile;
346
    video_frame_class f_h;
347
 
348
    // --------------------------------------------------------------------
349
    //
350
    function void axis_default;
351
 
352
      avf_axis_if.cb_s.tready <= 1;
353
 
354
    endfunction: axis_default
355
 
356
 
357
    // --------------------------------------------------------------------
358
    //
359
    task automatic
360
      set_tready(input tready);
361
 
362
      avf_axis_if.cb_s.tready <= tready;
363
 
364
    endtask: set_tready
365
 
366
 
367
    // --------------------------------------------------------------------
368
    //
369
    task automatic
370
      avf_rx(input avf_direction_t direction);
371
 
372
        frame_coordinate_t start;
373
        frame_coordinate_t inc;
374
        int x_end;
375
        int y_end;
376
        int x_eol;
377
        int pixel_count = 0;
378
        int l;
379
        int p;
380
 
381
        c_h.avf_calculate
382
        (
383
          .start(start),
384
          .direction(direction),
385
          .inc(inc),
386
          .x_end(x_end),
387
          .y_end(y_end),
388
          .x_eol(x_eol)
389
        );
390
 
391
        wait(avf_axis_if.cb_s.tuser[0] & avf_axis_if.cb_s.tvalid & avf_axis_if.cb_m.tready);
392
 
393
        for(l = start.y; y_end != l; l = l + inc.y)
394
          for(p = start.x; x_end != p; p = p + inc.x)
395
            begin
396
 
397
              wait(avf_axis_if.cb_s.tvalid & avf_axis_if.cb_m.tready);
398
 
399
              for(int i = 0; i < PIXELS_PER_CLK; i++)
400
                f_h.lines[l].pixel[p + i] = avf_axis_if.cb_s.tdata[i*AVF_B +: AVF_B];
401
 
402
              if(p == x_eol)
403
                if(~avf_axis_if.cb_s.tlast)
404
                  $display("^^^ %16.t | %m | [%04d, %04d] | %s_%s | ERROR! x_eol without tlast | x_eol = %04d | 0x%06x", $time, p, l, avf_name, avf_type, x_eol, f_h.lines[l].pixel[p]);
405
 
406
              if(avf_axis_if.cb_s.tlast)
407
                if(p != x_eol)
408
                  $display("^^^ %16.t | %m | [%04d, %04d] | %s_%s | ERROR! tlast without x_eol | x_eol = %04d | 0x%06x", $time, p, l, avf_name, avf_type, x_eol, f_h.lines[l].pixel[p]);
409
 
410
              @(avf_axis_if.cb_s);
411
 
412
            end
413
 
414
    endtask: avf_rx
415
 
416
 
417
    // --------------------------------------------------------------------
418
    //
419
    task automatic
420
      avf_fork_rx;
421
 
422
      fork
423
        avf_rx(tile.direction);
424
      join_none
425
 
426
      #0;
427
 
428
    endtask: avf_fork_rx
429
 
430
 
431
    // --------------------------------------------------------------------
432
    //
433
    event rx_frame_done;
434
 
435
    virtual task
436
      receive(ref Q_T tr_h);
437
 
438
      avf_fork_rx();
439
      wait fork;
440
 
441
      tr_h = f_h.clone();
442
      ->rx_frame_done;
443
 
444
    endtask: receive
445
 
446
 
447
    //--------------------------------------------------------------------
448
    //
449
    function
450
      new
451
      (
452
        int               index,
453
        avf_config_class c_h,
454
        input string      avf_type,
455
        virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_if
456
      );
457
 
458
      super.new();
459
 
460
      this.avf_axis_if = avf_axis_if;
461
 
462
      this.c_h = c_h;
463
      this.tile = c_h.tile[index];
464
      this.avf_name = $sformatf("%s%0d", c_h.name, index);
465
      this.avf_type = avf_type.toupper();
466
 
467
      f_h = new();
468
 
469
      f_h.init
470
      (
471
        .pixels_per_line(c_h.width),
472
        .lines_per_frame(c_h.height),
473
        .bits_per_pixel(c_h.bits_per_pixel),
474
        .name(avf_name)
475
      );
476
 
477
      axis_default();
478
 
479
    endfunction: new
480
 
481
 
482
  // --------------------------------------------------------------------
483
  //
484
  endclass: avf_rx_bfm_class
485
 
486
  // --------------------------------------------------------------------
487
  //
488
  class avf_tx_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U);
489
 
490
    localparam AVF_N = BYTES_PER_PIXEL * OUTPUTS_PER_TILE;  // data bus width in bytes
491
    localparam AVF_B = BYTES_PER_PIXEL * 8;                 // bits per pixel on TDATA
492
 
493
    int number_of_tx_tiles;
494
 
495
    virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_out_if[];
496
 
497
    avf_tx_bfm_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U) tx_bfm_h[];
498
 
499
    video_frame_class clone_h;
500
 
501
 
502
    // --------------------------------------------------------------------
503
    //
504
    virtual task automatic
505
      make_frame
506
      (
507
        string pattern,
508
        int pixel = 0
509
      );
510
 
511
        case(pattern.tolower)
512
          "constant":   foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_constant(pixel);
513
          "counting":   foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_counting();
514
          "horizontal": foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_horizontal();
515
          "vertical":   foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_vertical();
516
          "random":     foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_random();
517
          default:      $display("^^^ %16.t | %m | ERROR! %s pattern not supported", $time, pattern);
518
        endcase
519
 
520
    endtask: make_frame
521
 
522
 
523
    // --------------------------------------------------------------------
524
    //
525
    virtual task
526
      wait_for_tx_frames
527
      (
528
        input int unsigned count
529
      );
530
 
531
      repeat(count)
532
        @(tx_bfm_h[0].tx_frame_done);
533
 
534
    endtask: wait_for_tx_frames
535
 
536
 
537
    //--------------------------------------------------------------------
538
    //
539
    function new
540
      (
541
        avf_config_class c_h,
542
        virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_out_if[]
543
      );
544
 
545
      this.number_of_tx_tiles = $size(avf_axis_out_if);
546
      this.avf_axis_out_if = avf_axis_out_if;
547
 
548
      this.tx_bfm_h = new[number_of_tx_tiles];
549
      foreach(tx_bfm_h[i])
550
        tx_bfm_h[i] = new(i, c_h, "TX", avf_axis_out_if[i]);
551
 
552
    endfunction: new
553
 
554
 
555
  // --------------------------------------------------------------------
556
  //
557
  endclass: avf_tx_class
558
 
559
 
560
  // --------------------------------------------------------------------
561
  //
562
  class avf_rx_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U);
563
 
564
    localparam AVF_N = BYTES_PER_PIXEL * OUTPUTS_PER_TILE;  // data bus width in bytes
565
    localparam AVF_B = BYTES_PER_PIXEL * 8;                 // bits per pixel on TDATA
566
 
567
    int number_of_rx_tiles;
568
 
569
    virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_in_if[];
570
 
571
    avf_rx_bfm_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U) rx_bfm_h[];
572
 
573
    video_frame_class clone_h;
574
 
575
 
576
    // --------------------------------------------------------------------
577
    //
578
    virtual task
579
      wait_for_rx_frames
580
      (
581
        input int unsigned count
582
      );
583
 
584
      repeat(count)
585
        @(rx_bfm_h[0].rx_frame_done);
586
 
587
    endtask: wait_for_rx_frames
588
 
589
 
590
    //--------------------------------------------------------------------
591
    //
592
    function new
593
      (
594
        avf_config_class c_h,
595
        virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_in_if[]
596
      );
597
 
598
      this.number_of_rx_tiles = $size(avf_axis_in_if);
599
      this.avf_axis_in_if = avf_axis_in_if;
600
 
601
      this.rx_bfm_h = new[number_of_rx_tiles];
602
      foreach(rx_bfm_h[i])
603
        rx_bfm_h[i] = new(i, c_h, "RX", avf_axis_in_if[i]);
604
 
605
    endfunction: new
606
 
607
 
608
  // --------------------------------------------------------------------
609
  //
610
  endclass: avf_rx_class
611
 
612
 
613
// --------------------------------------------------------------------
614
//
615
endpackage: axis_video_frame_bfm_pkg
616
 

powered by: WebSVN 2.1.0

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