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] - Rev 45
Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////////// //////// Copyright (C) 2015 Authors and OPENCORES.ORG //////// //////// This source file may be used and distributed without //////// restriction provided that this copyright statement is not //////// removed from the file and that any derivative work contains //////// the original copyright notice and the associated disclaimer. //////// //////// This source file is free software; you can redistribute it //////// and/or modify it under the terms of the GNU Lesser General //////// Public License as published by the Free Software Foundation; //////// either version 2.1 of the License, or (at your option) any //////// later version. //////// //////// This source is distributed in the hope that it will be //////// useful, but WITHOUT ANY WARRANTY; without even the implied //////// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //////// PURPOSE. See the GNU Lesser General Public License for more //////// details. //////// //////// You should have received a copy of the GNU Lesser General //////// Public License along with this source; if not, download it //////// from http://www.opencores.org/lgpl.shtml //////// //////////////////////////////////////////////////////////////////////////package axis_video_frame_bfm_pkg;typedef enum{RIGHT_DOWN,RIGHT_UP,LEFT_DOWN,LEFT_UP} avf_direction_t;typedef struct{avf_direction_t direction;int delay = 0;} avf_tile_config_t;// --------------------------------------------------------------------//import q_pkg::*;import video_frame_pkg::*;// --------------------------------------------------------------------//class avf_config_class;int width;int height;int bytes_per_pixel;int bits_per_pixel;int pixels_per_clk;string name;int vertical_blanking;avf_tile_config_t tile[];//--------------------------------------------------------------------functionnew(int width,int height,int bytes_per_pixel,int bits_per_pixel,int pixels_per_clk,string name,int vertical_blanking,avf_tile_config_t tile[]);this.width = width;this.height = height;this.bytes_per_pixel = bytes_per_pixel;this.bits_per_pixel = bits_per_pixel;this.pixels_per_clk = pixels_per_clk;this.name = name;this.vertical_blanking = vertical_blanking;this.tile = tile;$display("^^^ %16.t | %m", $time);endfunction: new// --------------------------------------------------------------------//task automaticavf_direction(input avf_direction_t direction,output frame_coordinate_t inc);case(direction)RIGHT_DOWN: inc = '{ 1, 1};RIGHT_UP: inc = '{ 1, -1};LEFT_DOWN: inc = '{-1, 1};LEFT_UP: inc = '{-1, -1};default: $display("^^^ %16.t | %m | ERROR!!! Incorrect AVF direction.", $time );endcaseendtask: avf_direction// --------------------------------------------------------------------//task automaticavf_calculate(input avf_direction_t direction,output frame_coordinate_t start,output frame_coordinate_t inc,output int x_end,output int y_end,output int x_eol);case(direction)RIGHT_DOWN: start = '{0 , 0 };RIGHT_UP: start = '{0 , height - 1 };LEFT_DOWN: start = '{width - 1 , 0 };LEFT_UP: start = '{width - 1 , height - 1 };default: $display("^^^ %16.t | %m | [%04d, %04d] | ERROR!!! Incorrect AVF direction.", $time, start.x, start.y );endcaseavf_direction(direction, inc);x_end = (start.x + (width * inc.x));y_end = (start.y + (height * inc.y));inc.x *= pixels_per_clk; // increment stride by number of outputsx_eol = x_end - inc.x;endtask: avf_calculateendclass: avf_config_class//--------------------------------------------------------------------//class avf_tx_bfm_class #(BYTES_PER_PIXEL, PIXELS_PER_CLK, AVF_U)extends blocking_transmission_q_class #(video_frame_class);localparam AVF_N = BYTES_PER_PIXEL * PIXELS_PER_CLK; // data bus width in byteslocalparam AVF_B = BYTES_PER_PIXEL * 8; // bits per pixel on TDATAvirtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_if;string avf_name = "";string avf_type = "";avf_config_class c_h;avf_tile_config_t tile;video_frame_class f_h;// --------------------------------------------------------------------//function void axis_default;avf_axis_if.cb_m.tvalid <= 0;avf_axis_if.cb_m.tdata <= 'hx;avf_axis_if.cb_m.tlast <= 'hx;avf_axis_if.cb_m.tuser <= 'hx;endfunction: axis_default// --------------------------------------------------------------------//task automaticoutput_pixels(input int l, input int p);for(int i = 0; i < PIXELS_PER_CLK; i++)avf_axis_if.cb_m.tdata[i*AVF_B +: AVF_B] <= f_h.lines[l].pixel[p + i];endtask: output_pixels// --------------------------------------------------------------------//task automaticavf_tx(input avf_direction_t direction, input int unsigned avf_delay);frame_coordinate_t start;frame_coordinate_t inc;int x_end;int y_end;int x_eol;int pixel_count = 0;int l;int p;c_h.avf_calculate(.start(start),.direction(direction),.inc(inc),.x_end(x_end),.y_end(y_end),.x_eol(x_eol));@(avf_axis_if.cb_m);repeat(avf_delay) @(avf_axis_if.cb_m);avf_axis_if.cb_m.tvalid <= 1; // assert first pixelavf_axis_if.cb_m.tuser[0] <= 1;avf_axis_if.cb_m.tuser[1] <= 1;avf_axis_if.cb_m.tuser[2] <= 0;avf_axis_if.cb_m.tlast <= 0;output_pixels(start.y, start.x);for(l = start.y; y_end != l; l = l + inc.y)for(p = start.x; x_end != p; p = p + inc.x)beginif((l == start.y) & (p == start.x)) // first pixel already assertedcontinue;@(avf_axis_if.cb_m iff avf_axis_if.cb_m.tready)beginavf_axis_if.cb_m.tvalid <= 1;output_pixels(l, p);avf_axis_if.cb_m.tuser[0] <= 0;if(p == start.x)avf_axis_if.cb_m.tuser[1] <= 1;elseavf_axis_if.cb_m.tuser[1] <= 0;if(p == x_eol)avf_axis_if.cb_m.tlast <= 1;elseavf_axis_if.cb_m.tlast <= 0;if((l == y_end - 1) && (p == x_eol))avf_axis_if.cb_m.tuser[2] <= 1;endend@(avf_axis_if.cb_m);wait(avf_axis_if.cb_m.tready);axis_default();endtask: avf_tx// --------------------------------------------------------------------//taskavf_fork_tx;forkavf_tx(tile.direction, tile.delay);join_none#0;endtask: avf_fork_tx// --------------------------------------------------------------------//event tx_frame_done;task automatictransmit(ref Q_T tr_h);f_h = tr_h;avf_fork_tx();wait fork;repeat(c_h.vertical_blanking) @(avf_axis_if.cb_m);->tx_frame_done;endtask: transmit//--------------------------------------------------------------------//functionnew(int index,avf_config_class c_h,input string avf_type,virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_if);super.new();this.avf_axis_if = avf_axis_if;this.c_h = c_h;this.tile = c_h.tile[index];this.avf_name = $sformatf("%s%0d", c_h.name, index);this.avf_type = avf_type.toupper();f_h = new();f_h.init(.pixels_per_line(c_h.width),.lines_per_frame(c_h.height),.bits_per_pixel(c_h.bits_per_pixel),.name(avf_name));axis_default();endfunction: new// --------------------------------------------------------------------//endclass: avf_tx_bfm_class//--------------------------------------------------------------------//class avf_rx_bfm_class #(BYTES_PER_PIXEL, PIXELS_PER_CLK, AVF_U)extends blocking_receiver_q_class #(video_frame_class);localparam AVF_N = BYTES_PER_PIXEL * PIXELS_PER_CLK; // data bus width in byteslocalparam AVF_B = BYTES_PER_PIXEL * 8; // bits per pixel on TDATAvirtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_if;string avf_name = "";string avf_type = "";avf_config_class c_h;avf_tile_config_t tile;video_frame_class f_h;// --------------------------------------------------------------------//function void axis_default;avf_axis_if.cb_s.tready <= 1;endfunction: axis_default// --------------------------------------------------------------------//task automaticset_tready(input tready);avf_axis_if.cb_s.tready <= tready;endtask: set_tready// --------------------------------------------------------------------//task automaticavf_rx(input avf_direction_t direction);frame_coordinate_t start;frame_coordinate_t inc;int x_end;int y_end;int x_eol;int pixel_count = 0;int l;int p;c_h.avf_calculate(.start(start),.direction(direction),.inc(inc),.x_end(x_end),.y_end(y_end),.x_eol(x_eol));wait(avf_axis_if.cb_s.tuser[0] & avf_axis_if.cb_s.tvalid & avf_axis_if.cb_m.tready);for(l = start.y; y_end != l; l = l + inc.y)for(p = start.x; x_end != p; p = p + inc.x)beginwait(avf_axis_if.cb_s.tvalid & avf_axis_if.cb_m.tready);for(int i = 0; i < PIXELS_PER_CLK; i++)f_h.lines[l].pixel[p + i] = avf_axis_if.cb_s.tdata[i*AVF_B +: AVF_B];if(p == x_eol)if(~avf_axis_if.cb_s.tlast)$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]);if(avf_axis_if.cb_s.tlast)if(p != x_eol)$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]);@(avf_axis_if.cb_s);endendtask: avf_rx// --------------------------------------------------------------------//task automaticavf_fork_rx;forkavf_rx(tile.direction);join_none#0;endtask: avf_fork_rx// --------------------------------------------------------------------//event rx_frame_done;virtual taskreceive(ref Q_T tr_h);avf_fork_rx();wait fork;tr_h = f_h.clone();->rx_frame_done;endtask: receive//--------------------------------------------------------------------//functionnew(int index,avf_config_class c_h,input string avf_type,virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_if);super.new();this.avf_axis_if = avf_axis_if;this.c_h = c_h;this.tile = c_h.tile[index];this.avf_name = $sformatf("%s%0d", c_h.name, index);this.avf_type = avf_type.toupper();f_h = new();f_h.init(.pixels_per_line(c_h.width),.lines_per_frame(c_h.height),.bits_per_pixel(c_h.bits_per_pixel),.name(avf_name));axis_default();endfunction: new// --------------------------------------------------------------------//endclass: avf_rx_bfm_class// --------------------------------------------------------------------//class avf_tx_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U);localparam AVF_N = BYTES_PER_PIXEL * OUTPUTS_PER_TILE; // data bus width in byteslocalparam AVF_B = BYTES_PER_PIXEL * 8; // bits per pixel on TDATAint number_of_tx_tiles;virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_out_if[];avf_tx_bfm_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U) tx_bfm_h[];video_frame_class clone_h;// --------------------------------------------------------------------//virtual task automaticmake_frame(string pattern,int pixel = 0);case(pattern.tolower)"constant": foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_constant(pixel);"counting": foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_counting();"horizontal": foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_horizontal();"vertical": foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_vertical();"random": foreach(tx_bfm_h[i]) tx_bfm_h[i].f_h.make_random();default: $display("^^^ %16.t | %m | ERROR! %s pattern not supported", $time, pattern);endcaseendtask: make_frame// --------------------------------------------------------------------//virtual taskwait_for_tx_frames(input int unsigned count);repeat(count)@(tx_bfm_h[0].tx_frame_done);endtask: wait_for_tx_frames//--------------------------------------------------------------------//function new(avf_config_class c_h,virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_out_if[]);this.number_of_tx_tiles = $size(avf_axis_out_if);this.avf_axis_out_if = avf_axis_out_if;this.tx_bfm_h = new[number_of_tx_tiles];foreach(tx_bfm_h[i])tx_bfm_h[i] = new(i, c_h, "TX", avf_axis_out_if[i]);endfunction: new// --------------------------------------------------------------------//endclass: avf_tx_class// --------------------------------------------------------------------//class avf_rx_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U);localparam AVF_N = BYTES_PER_PIXEL * OUTPUTS_PER_TILE; // data bus width in byteslocalparam AVF_B = BYTES_PER_PIXEL * 8; // bits per pixel on TDATAint number_of_rx_tiles;virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_in_if[];avf_rx_bfm_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U) rx_bfm_h[];video_frame_class clone_h;// --------------------------------------------------------------------//virtual taskwait_for_rx_frames(input int unsigned count);repeat(count)@(rx_bfm_h[0].rx_frame_done);endtask: wait_for_rx_frames//--------------------------------------------------------------------//function new(avf_config_class c_h,virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_in_if[]);this.number_of_rx_tiles = $size(avf_axis_in_if);this.avf_axis_in_if = avf_axis_in_if;this.rx_bfm_h = new[number_of_rx_tiles];foreach(rx_bfm_h[i])rx_bfm_h[i] = new(i, c_h, "RX", avf_axis_in_if[i]);endfunction: new// --------------------------------------------------------------------//endclass: avf_rx_class// --------------------------------------------------------------------//endpackage: axis_video_frame_bfm_pkg
