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

Subversion Repositories qaz_libs

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 45 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
        wait(avf_axis_if.cb_m.tready);
255
        axis_default();
256
 
257
    endtask: avf_tx
258
 
259
 
260
    // --------------------------------------------------------------------
261
    //
262
    task
263
      avf_fork_tx;
264
 
265
      fork
266
        avf_tx(tile.direction, tile.delay);
267
      join_none
268
 
269
      #0;
270
 
271
    endtask: avf_fork_tx
272
 
273
 
274
    // --------------------------------------------------------------------
275
    //
276
    event tx_frame_done;
277
 
278
    task automatic
279
      transmit(ref Q_T tr_h);
280
 
281
      f_h = tr_h;
282
 
283
      avf_fork_tx();
284
      wait fork;
285
 
286
      repeat(c_h.vertical_blanking) @(avf_axis_if.cb_m);
287
      ->tx_frame_done;
288
 
289
    endtask: transmit
290
 
291
 
292
    //--------------------------------------------------------------------
293
    //
294
    function
295
      new
296
      (
297
        int                                     index,
298
        avf_config_class                        c_h,
299
        input string                            avf_type,
300
        virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_if
301
      );
302
 
303
      super.new();
304
 
305
      this.avf_axis_if = avf_axis_if;
306
 
307
      this.c_h = c_h;
308
      this.tile = c_h.tile[index];
309
      this.avf_name = $sformatf("%s%0d", c_h.name, index);
310
      this.avf_type = avf_type.toupper();
311
 
312
      f_h = new();
313
 
314
      f_h.init
315
      (
316
        .pixels_per_line(c_h.width),
317
        .lines_per_frame(c_h.height),
318
        .bits_per_pixel(c_h.bits_per_pixel),
319
        .name(avf_name)
320
      );
321
 
322
      axis_default();
323
 
324
    endfunction: new
325
 
326
 
327
  // --------------------------------------------------------------------
328
  //
329
  endclass: avf_tx_bfm_class
330
 
331
 
332
  //--------------------------------------------------------------------
333
  //
334
  class avf_rx_bfm_class #(BYTES_PER_PIXEL, PIXELS_PER_CLK, AVF_U)
335
    extends blocking_receiver_q_class #(video_frame_class);
336
 
337
    localparam AVF_N = BYTES_PER_PIXEL * PIXELS_PER_CLK;  // data bus width in bytes
338
    localparam AVF_B = BYTES_PER_PIXEL * 8;               // bits per pixel on TDATA
339
 
340
    virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_if;
341
 
342
    string  avf_name              = "";
343
    string  avf_type              = "";
344
 
345
    avf_config_class c_h;
346
    avf_tile_config_t tile;
347
    video_frame_class f_h;
348
 
349
    // --------------------------------------------------------------------
350
    //
351
    function void axis_default;
352
 
353
      avf_axis_if.cb_s.tready <= 1;
354
 
355
    endfunction: axis_default
356
 
357
 
358
    // --------------------------------------------------------------------
359
    //
360
    task automatic
361
      set_tready(input tready);
362
 
363
      avf_axis_if.cb_s.tready <= tready;
364
 
365
    endtask: set_tready
366
 
367
 
368
    // --------------------------------------------------------------------
369
    //
370
    task automatic
371
      avf_rx(input avf_direction_t direction);
372
 
373
        frame_coordinate_t start;
374
        frame_coordinate_t inc;
375
        int x_end;
376
        int y_end;
377
        int x_eol;
378
        int pixel_count = 0;
379
        int l;
380
        int p;
381
 
382
        c_h.avf_calculate
383
        (
384
          .start(start),
385
          .direction(direction),
386
          .inc(inc),
387
          .x_end(x_end),
388
          .y_end(y_end),
389
          .x_eol(x_eol)
390
        );
391
 
392
        wait(avf_axis_if.cb_s.tuser[0] & avf_axis_if.cb_s.tvalid & avf_axis_if.cb_m.tready);
393
 
394
        for(l = start.y; y_end != l; l = l + inc.y)
395
          for(p = start.x; x_end != p; p = p + inc.x)
396
            begin
397
 
398
              wait(avf_axis_if.cb_s.tvalid & avf_axis_if.cb_m.tready);
399
 
400
              for(int i = 0; i < PIXELS_PER_CLK; i++)
401
                f_h.lines[l].pixel[p + i] = avf_axis_if.cb_s.tdata[i*AVF_B +: AVF_B];
402
 
403
              if(p == x_eol)
404
                if(~avf_axis_if.cb_s.tlast)
405
                  $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]);
406
 
407
              if(avf_axis_if.cb_s.tlast)
408
                if(p != x_eol)
409
                  $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]);
410
 
411
              @(avf_axis_if.cb_s);
412
 
413
            end
414
 
415
    endtask: avf_rx
416
 
417
 
418
    // --------------------------------------------------------------------
419
    //
420
    task automatic
421
      avf_fork_rx;
422
 
423
      fork
424
        avf_rx(tile.direction);
425
      join_none
426
 
427
      #0;
428
 
429
    endtask: avf_fork_rx
430
 
431
 
432
    // --------------------------------------------------------------------
433
    //
434
    event rx_frame_done;
435
 
436
    virtual task
437
      receive(ref Q_T tr_h);
438
 
439
      avf_fork_rx();
440
      wait fork;
441
 
442
      tr_h = f_h.clone();
443
      ->rx_frame_done;
444
 
445
    endtask: receive
446
 
447
 
448
    //--------------------------------------------------------------------
449
    //
450
    function
451
      new
452
      (
453
        int               index,
454
        avf_config_class c_h,
455
        input string      avf_type,
456
        virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_if
457
      );
458
 
459
      super.new();
460
 
461
      this.avf_axis_if = avf_axis_if;
462
 
463
      this.c_h = c_h;
464
      this.tile = c_h.tile[index];
465
      this.avf_name = $sformatf("%s%0d", c_h.name, index);
466
      this.avf_type = avf_type.toupper();
467
 
468
      f_h = new();
469
 
470
      f_h.init
471
      (
472
        .pixels_per_line(c_h.width),
473
        .lines_per_frame(c_h.height),
474
        .bits_per_pixel(c_h.bits_per_pixel),
475
        .name(avf_name)
476
      );
477
 
478
      axis_default();
479
 
480
    endfunction: new
481
 
482
 
483
  // --------------------------------------------------------------------
484
  //
485
  endclass: avf_rx_bfm_class
486
 
487
  // --------------------------------------------------------------------
488
  //
489
  class avf_tx_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U);
490
 
491
    localparam AVF_N = BYTES_PER_PIXEL * OUTPUTS_PER_TILE;  // data bus width in bytes
492
    localparam AVF_B = BYTES_PER_PIXEL * 8;                 // bits per pixel on TDATA
493
 
494
    int number_of_tx_tiles;
495
 
496
    virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_out_if[];
497
 
498
    avf_tx_bfm_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U) tx_bfm_h[];
499
 
500
    video_frame_class clone_h;
501
 
502
 
503
    // --------------------------------------------------------------------
504
    //
505
    virtual task automatic
506
      make_frame
507
      (
508
        string pattern,
509
        int pixel = 0
510
      );
511
 
512
        case(pattern.tolower)
513
          "constant":   foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_constant(pixel);
514
          "counting":   foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_counting();
515
          "horizontal": foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_horizontal();
516
          "vertical":   foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_vertical();
517
          "random":     foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_random();
518
          default:      $display("^^^ %16.t | %m | ERROR! %s pattern not supported", $time, pattern);
519
        endcase
520
 
521
    endtask: make_frame
522
 
523
 
524
    // --------------------------------------------------------------------
525
    //
526
    virtual task
527
      wait_for_tx_frames
528
      (
529
        input int unsigned count
530
      );
531
 
532
      repeat(count)
533
        @(tx_bfm_h[0].tx_frame_done);
534
 
535
    endtask: wait_for_tx_frames
536
 
537
 
538
    //--------------------------------------------------------------------
539
    //
540
    function new
541
      (
542
        avf_config_class c_h,
543
        virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_out_if[]
544
      );
545
 
546
      this.number_of_tx_tiles = $size(avf_axis_out_if);
547
      this.avf_axis_out_if = avf_axis_out_if;
548
 
549
      this.tx_bfm_h = new[number_of_tx_tiles];
550
      foreach(tx_bfm_h[i])
551
        tx_bfm_h[i] = new(i, c_h, "TX", avf_axis_out_if[i]);
552
 
553
    endfunction: new
554
 
555
 
556
  // --------------------------------------------------------------------
557
  //
558
  endclass: avf_tx_class
559
 
560
 
561
  // --------------------------------------------------------------------
562
  //
563
  class avf_rx_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U);
564
 
565
    localparam AVF_N = BYTES_PER_PIXEL * OUTPUTS_PER_TILE;  // data bus width in bytes
566
    localparam AVF_B = BYTES_PER_PIXEL * 8;                 // bits per pixel on TDATA
567
 
568
    int number_of_rx_tiles;
569
 
570
    virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_in_if[];
571
 
572
    avf_rx_bfm_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U) rx_bfm_h[];
573
 
574
    video_frame_class clone_h;
575
 
576
 
577
    // --------------------------------------------------------------------
578
    //
579
    virtual task
580
      wait_for_rx_frames
581
      (
582
        input int unsigned count
583
      );
584
 
585
      repeat(count)
586
        @(rx_bfm_h[0].rx_frame_done);
587
 
588
    endtask: wait_for_rx_frames
589
 
590
 
591
    //--------------------------------------------------------------------
592
    //
593
    function new
594
      (
595
        avf_config_class c_h,
596
        virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_in_if[]
597
      );
598
 
599
      this.number_of_rx_tiles = $size(avf_axis_in_if);
600
      this.avf_axis_in_if = avf_axis_in_if;
601
 
602
      this.rx_bfm_h = new[number_of_rx_tiles];
603
      foreach(rx_bfm_h[i])
604
        rx_bfm_h[i] = new(i, c_h, "RX", avf_axis_in_if[i]);
605
 
606
    endfunction: new
607
 
608
 
609
  // --------------------------------------------------------------------
610
  //
611
  endclass: avf_rx_class
612
 
613
 
614
// --------------------------------------------------------------------
615
//
616
endpackage: axis_video_frame_bfm_pkg
617
 

powered by: WebSVN 2.1.0

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