URL
https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk
Subversion Repositories qaz_libs
Compare Revisions
- This comparison shows the changes necessary to convert path
/qaz_libs/trunk/BFM/src/axis_video_frame
- from Rev 42 to Rev 45
- ↔ Reverse comparison
Rev 42 → Rev 45
/avf_config.svh
0,0 → 1,73
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class avf_config #(N, U); |
|
virtual axis_if #(.N(N), .U(U)) vif; |
protected uvm_active_passive_enum is_active; // UVM_ACTIVE or UVM_PASSIVE |
int pixels_per_line; |
int lines_per_frame; |
int bits_per_pixel; |
int bytes_per_pixel; |
int pixels_per_clk; |
string name; |
|
// -------------------------------------------------------------------- |
function void init |
( int pixels_per_line |
, int lines_per_frame |
, int bits_per_pixel |
, string name = "" |
); |
this.pixels_per_line = pixels_per_line; |
this.lines_per_frame = lines_per_frame; |
this.bits_per_pixel = bits_per_pixel; |
this.name = name; |
this.bytes_per_pixel = (bits_per_pixel % 8 == 0) |
? (bits_per_pixel / 8) |
: (bits_per_pixel / 8) + 1; |
assert(N % bytes_per_pixel == 0) else |
`uvm_fatal("avf_config", "N % bytes_per_pixel != 0") |
this.pixels_per_clk = N / bytes_per_pixel; |
endfunction: init |
|
// -------------------------------------------------------------------- |
function new |
( virtual axis_if #(.N(N), .U(U)) vif |
, uvm_active_passive_enum is_active = UVM_ACTIVE |
); |
this.vif = vif; |
this.is_active = is_active; |
endfunction : new |
|
// -------------------------------------------------------------------- |
function uvm_active_passive_enum get_is_active(); |
return is_active; |
endfunction : get_is_active |
|
// -------------------------------------------------------------------- |
endclass : avf_config |
/avf_master_agent.svh
0,0 → 1,67
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class avf_master_agent #(N, U) |
extends uvm_agent; |
`uvm_component_param_utils(avf_master_agent #(N, U)) |
|
// -------------------------------------------------------------------- |
avf_config #(N, U) cfg_h; |
avf_master_sequencer sequencer_h; |
avf_master_driver #(N, U) driver_h; |
avf_monitor #(N, U) monitor_h; |
|
// -------------------------------------------------------------------- |
virtual function void build_phase(uvm_phase phase); |
super.build_phase(phase); |
if(is_active == UVM_ACTIVE) |
begin |
driver_h = avf_master_driver #(N, U)::type_id::create("driver_h", this); |
sequencer_h = avf_master_sequencer::type_id::create("sequencer_h", this); |
end |
monitor_h = avf_monitor #(N, U)::type_id::create("monitor_h", this); |
endfunction |
|
// -------------------------------------------------------------------- |
virtual function void connect_phase(uvm_phase phase); |
super.connect_phase(phase); |
if(is_active == UVM_ACTIVE) |
begin |
driver_h.vif = cfg_h.vif; |
driver_h.seq_item_port.connect(sequencer_h.seq_item_export); |
end |
monitor_h.vif = cfg_h.vif; |
monitor_h.cfg_h = cfg_h; |
endfunction |
|
// -------------------------------------------------------------------- |
function new(string name, uvm_component parent); |
super.new(name, parent); |
endfunction |
|
// -------------------------------------------------------------------- |
endclass : avf_master_agent |
/avf_master_driver.svh
0,0 → 1,124
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class avf_master_driver #(N, U) |
extends uvm_driver #(avf_sequence_item); |
`uvm_component_param_utils(avf_master_driver #(N, U)) |
|
// -------------------------------------------------------------------- |
virtual axis_if #(.N(N), .U(U)) vif; |
video_frame_class f_h; |
|
//-------------------------------------------------------------------- |
function void set_default; |
vif.cb_m.tvalid <= 0; |
vif.cb_m.tdata <= 'x; |
vif.cb_m.tstrb <= {N{1'b1}}; |
vif.cb_m.tkeep <= {N{1'b1}}; |
vif.cb_m.tlast <= 'x; |
vif.cb_m.tid <= 0; |
vif.cb_m.tdest <= 0; |
vif.cb_m.tuser <= 'x; |
endfunction: set_default |
|
//-------------------------------------------------------------------- |
virtual task run_phase(uvm_phase phase); |
avf_sequence_item item; |
logic [(8*N)-1:0] tdata; |
int offset; |
|
super.run_phase(phase); |
|
set_default(); |
|
forever |
begin |
wait(vif.aresetn); |
seq_item_port.get_next_item(item); |
|
while(item.frame_buffer.try_get(f_h)) |
begin |
vif.zero_cycle_delay(); |
repeat(item.delay_h.get(item.sof_delay)) |
@(vif.cb_m); |
vif.cb_m.tvalid <= 1; |
|
foreach(f_h.lines[l]) |
for(int p = 0; p < f_h.pixels_per_line; p += f_h.pixels_per_clk) |
begin |
if(l == 0 && p == 0) |
vif.cb_m.tuser[0] <= 1; |
else |
vif.cb_m.tuser[0] <= 0; |
|
if(p == 0) |
vif.cb_m.tuser[1] <= 1; |
else |
vif.cb_m.tuser[1] <= 0; |
|
if(p + f_h.pixels_per_clk >= f_h.pixels_per_line && l + 1 >= f_h.lines_per_frame) |
vif.cb_m.tuser[2] <= 1; |
else |
vif.cb_m.tuser[2] <= 0; |
|
if(p + f_h.pixels_per_clk >= f_h.pixels_per_line) |
vif.cb_m.tlast <= 1; |
else |
vif.cb_m.tlast <= 0; |
|
for(int i = 0; i < f_h.pixels_per_clk; i++) |
begin |
offset = i * f_h.bytes_per_pixel * 8; |
for(int k = 0; k < f_h.bytes_per_pixel; k++) |
tdata[offset + (k * 8) +: 8] = f_h.lines[l].pixel[p + i][k * 8 +: 8]; |
end |
|
vif.cb_m.tdata <= tdata; |
@(vif.cb_m iff vif.cb_m.tready); |
|
vif.cb_m.tvalid <= 0; |
repeat(item.get_delay(vif.cb_s.tlast, vif.cb_s.tuser[2])) |
@(vif.cb_m); |
vif.cb_m.tvalid <= 1; |
end |
|
vif.cb_m.tuser[2] <= 0; |
vif.cb_m.tlast <= 0; |
vif.cb_m.tvalid <= 0; |
end |
|
seq_item_port.item_done(); |
end |
endtask : run_phase |
|
//-------------------------------------------------------------------- |
function new(string name, uvm_component parent); |
super.new(name, parent); |
endfunction |
|
// -------------------------------------------------------------------- |
endclass : avf_master_driver |
/avf_monitor.svh
0,0 → 1,109
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class avf_monitor #(N, U) extends uvm_component; |
`uvm_component_param_utils(avf_monitor #(N, U)); |
|
virtual axis_if #(.N(N), .U(U)) vif; |
avf_config #(N, U) cfg_h; |
uvm_analysis_port #(avf_sequence_item) ap; |
uvm_analysis_port #(avf_sequence_item) req; |
|
// -------------------------------------------------------------------- |
function new (string name, uvm_component parent); |
super.new(name,parent); |
endfunction |
|
// -------------------------------------------------------------------- |
function void build_phase(uvm_phase phase); |
ap = new("ap", this); |
req = new("req", this); |
endfunction : build_phase |
|
// -------------------------------------------------------------------- |
task run_phase(uvm_phase phase); |
avf_sequence_item req_item; |
avf_sequence_item ap_item; |
bit sof_received = 0; |
int l, p; |
int offset; |
|
forever @(vif.cb_m iff vif.cb_m.aresetn === 1) |
begin |
if(vif.cb_s.tvalid & ~vif.cb_m.tready) |
begin |
req_item = avf_sequence_item::type_id::create("req_item"); |
req_item.kind = AVF_REQUEST; |
req.write(req_item); |
end |
|
if(vif.cb_s.tvalid & vif.cb_m.tready) |
begin |
if(vif.cb_s.tuser[0]) // SOF |
begin |
ap_item = avf_sequence_item::type_id::create("ap_item"); |
ap_item.kind = AVF_TRANSACTION; |
ap_item.f_h = new(); |
ap_item.f_h.init( cfg_h.pixels_per_line |
, cfg_h.lines_per_frame |
, cfg_h.bits_per_pixel |
, cfg_h.pixels_per_clk |
, cfg_h.name |
); |
sof_received = 1; |
p = 0; |
l = 0; |
end |
|
if(sof_received) |
begin |
|
for(int i = 0; i < ap_item.f_h.pixels_per_clk; i++, p++) |
begin |
offset = i * ap_item.f_h.bytes_per_pixel * 8; |
for(int k = 0; k < ap_item.f_h.bytes_per_pixel; k++) |
ap_item.f_h.lines[l].pixel[p][k * 8 +: 8] = vif.cb_s.tdata[offset + (k * 8) +: 8]; |
end |
|
if(p >= ap_item.f_h.pixels_per_line) |
begin |
p = 0; |
l++; |
end |
|
if(vif.cb_s.tuser[2]) // EOF |
begin |
ap.write(ap_item); |
sof_received = 0; |
end |
end |
end |
end |
endtask : run_phase |
|
// -------------------------------------------------------------------- |
endclass : avf_monitor |
/avf_pkg.sv
0,0 → 1,56
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 avf_pkg; |
import uvm_pkg::*; |
`include "uvm_macros.svh" |
import tb_pkg::*; |
import video_frame_pkg::*; |
|
// -------------------------------------------------------------------- |
`include "avf_config.svh" |
`include "avf_sequence_item.svh" |
`include "avf_monitor.svh" |
`include "avf_scoreboard.svh" |
|
// -------------------------------------------------------------------- |
typedef uvm_sequencer #(avf_sequence_item) avf_master_sequencer; |
`include "avf_master_driver.svh" |
`include "avf_master_agent.svh" |
|
// -------------------------------------------------------------------- |
`include "avf_slave_sequencer.svh" |
`include "avf_slave_driver.svh" |
`include "avf_slave_agent.svh" |
`include "s_avf_slave_base.svh" |
|
// -------------------------------------------------------------------- |
`include "s_avf_api.svh" |
`include "s_avf_base.svh" |
|
// -------------------------------------------------------------------- |
endpackage : avf_pkg |
/avf_scoreboard.svh
0,0 → 1,88
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class avf_scoreboard extends uvm_subscriber #(avf_sequence_item); |
`uvm_component_utils(avf_scoreboard); |
|
// -------------------------------------------------------------------- |
function new (string name, uvm_component parent); |
super.new(name, parent); |
endfunction : new |
|
// -------------------------------------------------------------------- |
function void build_phase(uvm_phase phase); |
endfunction : build_phase |
|
// // -------------------------------------------------------------------- |
// mailbox #(avf_sequence_item) mb = new(); |
// avf_sequence_item c_t; |
// avf_sequence_item item; |
// int m_matches = 0; |
// int m_mismatches = 0; |
|
// function void write(avf_sequence_item t); |
|
// $cast(c_t, t.clone); |
|
// if((c_t.command = FIFO_WR) || (c_t.command = FIFO_BOTH)) |
// mb.try_put(c_t); |
|
// if((c_t.command = FIFO_RD) || (c_t.command = FIFO_BOTH)) |
// mb.try_get(item); |
|
// if(~c_t.compare(item)) |
// begin |
// uvm_report_info(get_name(), $sformatf("^^^ %16.t | %m | MISMATCH!!! | %s", $time, {20{"-"}})); |
// uvm_report_info(get_name(), c_t.convert2string); |
// uvm_report_info(get_name(), item.convert2string); |
// m_mismatches++; |
// end |
// else |
// m_matches++; |
// endfunction : write |
|
// -------------------------------------------------------------------- |
// |
function void print_video_frame(ref video_frame_class f_h); |
string s; |
f_h.print_config(); |
$display(f_h.convert2string()); |
endfunction : print_video_frame |
|
// -------------------------------------------------------------------- |
function void write(avf_sequence_item t); |
print_video_frame(t.f_h); |
endfunction : write |
|
// -------------------------------------------------------------------- |
function void report_phase(uvm_phase phase); |
// uvm_report_info(get_name(), $sformatf("Matches : %0d", m_matches)); |
// uvm_report_info(get_name(), $sformatf("Mismatches: %0d", m_mismatches)); |
endfunction |
|
// -------------------------------------------------------------------- |
endclass : avf_scoreboard |
/avf_sequence_item.svh
0,0 → 1,120
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
// -------------------------------------------------------------------- |
typedef enum {AVF_REQUEST, AVF_TRANSACTION} avf_sequence_item_t; |
|
// -------------------------------------------------------------------- |
class avf_sequence_item |
extends uvm_sequence_item; |
`uvm_object_utils(avf_sequence_item) |
|
// -------------------------------------------------------------------- |
avf_sequence_item_t kind = AVF_TRANSACTION; |
video_frame_class f_h; |
mailbox #(video_frame_class) frame_buffer; |
random_delay delay_h; |
random_delay_type_e sof_delay = REGULAR; |
random_delay_type_e eol_delay = REGULAR; |
random_delay_type_e eof_delay = REGULAR; |
random_delay_type_e pixel_delay = SPORADIC; |
random_delay_type_e slave_delay = REGULAR; |
|
// -------------------------------------------------------------------- |
function int unsigned get_delay(bit eol, bit eof); |
if(eof) |
return(delay_h.get(eof_delay)); |
else if(eol) |
return(delay_h.get(eol_delay)); |
else |
return(delay_h.get(pixel_delay)); |
endfunction : get_delay |
|
// -------------------------------------------------------------------- |
function new(string name = ""); |
super.new(name); |
delay_h = new(); |
endfunction : new |
|
// // -------------------------------------------------------------------- |
// function bit do_compare(uvm_object rhs, uvm_comparer comparer); |
// avf_sequence_item tested; |
// bit same; |
|
// if (rhs==null) |
// `uvm_fatal(get_type_name(), "| %m | comparison to a null pointer"); |
|
// if (!$cast(tested,rhs)) |
// same = 0; |
// else |
// same = super.do_compare(rhs, comparer); |
|
// return same; |
// endfunction : do_compare |
|
// // -------------------------------------------------------------------- |
// function void do_copy(uvm_object rhs); |
// avf_sequence_item item; |
// assert(rhs != null) else |
// `uvm_fatal(get_type_name(), "| %m | copy null transaction"); |
// super.do_copy(rhs); |
// assert($cast(item,rhs)) else |
// `uvm_fatal(get_type_name(), "| %m | failed cast"); |
// delay = item.delay; |
// command = item.command; |
// wr_full = item.wr_full; |
// rd_empty = item.rd_empty; |
// wr_data = item.wr_data; |
// rd_data = item.rd_data; |
// count = item.count; |
// endfunction : do_copy |
|
// // -------------------------------------------------------------------- |
// function string convert2string(); |
// string s0, s1, s2, s3; |
// s0 = $sformatf( "| %m | wr | rd | full | empty |\n"); |
// s1 = $sformatf( "| %m | %1h | %1h | %1h | %1h |\n" |
// , (command == FIFO_WR) || (command == FIFO_BOTH) |
// , (command == FIFO_RD) || (command == FIFO_BOTH) |
// , wr_full |
// , rd_empty |
// ); |
// s2 = $sformatf("| %m | wr_data: %h\n" , wr_data); |
// s3 = $sformatf("| %m | rd_data: %h\n" , rd_data); |
|
// if(command == FIFO_NULL) |
// return {s1, s0}; |
// else if(command == FIFO_BOTH) |
// return {s3, s2, s1, s0}; |
// else if(command == FIFO_WR) |
// return {s2, s1, s0}; |
// else if(command == FIFO_RD) |
// return {s3, s1, s0}; |
// endfunction : convert2string |
|
// -------------------------------------------------------------------- |
endclass : avf_sequence_item |
/avf_slave_agent.svh
0,0 → 1,68
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class avf_slave_agent #(N, U) |
extends uvm_agent; |
`uvm_component_param_utils(avf_slave_agent #(N, U)) |
|
// -------------------------------------------------------------------- |
avf_config #(N, U) cfg_h; |
avf_slave_sequencer sequencer_h; |
avf_slave_driver #(N, U) driver_h; |
avf_monitor #(N, U) monitor_h; |
|
// -------------------------------------------------------------------- |
virtual function void build_phase(uvm_phase phase); |
super.build_phase(phase); |
if(is_active == UVM_ACTIVE) |
begin |
driver_h = avf_slave_driver #(N, U)::type_id::create("driver_h", this); |
sequencer_h = avf_slave_sequencer::type_id::create("sequencer_h", this); |
end |
monitor_h = avf_monitor #(N, U)::type_id::create("monitor_h", this); |
endfunction |
|
// -------------------------------------------------------------------- |
virtual function void connect_phase(uvm_phase phase); |
super.connect_phase(phase); |
if(is_active == UVM_ACTIVE) |
begin |
driver_h.vif = cfg_h.vif; |
driver_h.seq_item_port.connect(sequencer_h.seq_item_export); |
monitor_h.req.connect(sequencer_h.m_request_export); |
end |
monitor_h.vif = cfg_h.vif; |
monitor_h.cfg_h = cfg_h; |
endfunction |
|
// -------------------------------------------------------------------- |
function new(string name, uvm_component parent); |
super.new(name, parent); |
endfunction |
|
// -------------------------------------------------------------------- |
endclass : avf_slave_agent |
/avf_slave_driver.svh
0,0 → 1,72
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class avf_slave_driver #(N, U) |
extends uvm_driver #(avf_sequence_item); |
`uvm_component_param_utils(avf_slave_driver #(N, U)) |
|
// -------------------------------------------------------------------- |
virtual axis_if #(.N(N), .U(U)) vif; |
|
//-------------------------------------------------------------------- |
function void set_default; |
vif.cb_s.tready <= 0; |
endfunction: set_default |
|
//-------------------------------------------------------------------- |
virtual task run_phase(uvm_phase phase); |
avf_sequence_item item; |
super.run_phase(phase); |
|
set_default(); |
|
forever |
begin |
wait(vif.aresetn); |
seq_item_port.get_next_item(item); |
vif.zero_cycle_delay(); |
|
repeat(item.delay_h.get(item.slave_delay)) |
@(vif.cb_m); |
|
vif.cb_s.tready <= 1; |
|
repeat(item.delay_h.get(item.slave_delay)) |
@(vif.cb_m); |
|
vif.cb_s.tready <= 0; |
seq_item_port.item_done(); |
end |
endtask : run_phase |
|
//-------------------------------------------------------------------- |
function new(string name, uvm_component parent); |
super.new(name, parent); |
endfunction |
|
// -------------------------------------------------------------------- |
endclass : avf_slave_driver |
/avf_slave_sequencer.svh
0,0 → 1,48
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class avf_slave_sequencer extends uvm_sequencer #(avf_sequence_item); |
`uvm_component_utils(avf_slave_sequencer) |
|
uvm_analysis_export #(avf_sequence_item) m_request_export; |
uvm_tlm_analysis_fifo #(avf_sequence_item) m_request_fifo; |
|
// -------------------------------------------------------------------- |
function new(string name, uvm_component parent); |
super.new(name, parent); |
m_request_fifo = new("m_request_fifo", this); |
m_request_export = new("m_request_export", this); |
endfunction |
|
// -------------------------------------------------------------------- |
function void connect_phase(uvm_phase phase); |
super.connect_phase(phase); |
m_request_export.connect(m_request_fifo.analysis_export); |
endfunction |
|
// -------------------------------------------------------------------- |
endclass |
/legacy/avf_agent.sv
0,0 → 1,105
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
|
import axis_video_frame_bfm_pkg::*; |
|
module |
avf_agent |
#( |
BYTES_PER_PIXEL = 2, |
AVF_OUTPUTS = 4, |
AVF_TILES = 1, |
AVF_WIDTH = 32, |
AVF_HEIGHT = 16, |
AVF_BITS_PER_PIXEL = 16 |
) |
( |
axis_if axis_out[AVF_TILES], |
axis_if axis_in[AVF_TILES] |
); |
|
// -------------------------------------------------------------------- |
// |
axis_video_frame_bfm_class #(BYTES_PER_PIXEL, AVF_OUTPUTS) f_tx_h[AVF_TILES]; |
|
for(genvar j = 0; j < AVF_TILES; j++) |
initial |
begin |
f_tx_h[j] = new(axis_out[j]); |
|
f_tx_h[j].init |
( |
.avf_width(AVF_WIDTH), |
.avf_height(AVF_HEIGHT), |
.avf_bits_per_pixel(AVF_BITS_PER_PIXEL), |
.avf_name($psprintf("AVF_%0d", j)), |
.avf_type("TX") |
); |
end |
|
|
// -------------------------------------------------------------------- |
// |
axis_video_frame_bfm_class #(BYTES_PER_PIXEL, AVF_OUTPUTS) f_rx_h[AVF_TILES]; |
|
for(genvar j = 0; j < AVF_TILES; j++) |
initial |
begin |
f_rx_h[j] = new(axis_in[j]); |
|
f_rx_h[j].init |
( |
.avf_width(AVF_WIDTH), |
.avf_height(AVF_HEIGHT), |
.avf_bits_per_pixel(AVF_BITS_PER_PIXEL), |
.avf_name($psprintf("AVF_%0d", j)), |
.avf_type("RX") |
); |
end |
|
|
// -------------------------------------------------------------------- |
// |
avf_tx #(BYTES_PER_PIXEL, AVF_OUTPUTS, AVF_TILES) |
avf_tx_bfm(.*); |
|
|
// -------------------------------------------------------------------- |
// |
avf_rx #(BYTES_PER_PIXEL, AVF_OUTPUTS, AVF_TILES) |
avf_rx_bfm(.*); |
|
|
// -------------------------------------------------------------------- |
// |
|
endmodule |
|
|
|
|
/legacy/avf_agent_class_pkg.sv
0,0 → 1,166
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 avf_agent_class_pkg; |
|
// -------------------------------------------------------------------- |
// |
import video_frame_pkg::*; |
import axis_video_frame_bfm_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
class avf_agent_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE = 1, AVF_U = 3); |
|
localparam AVF_N = BYTES_PER_PIXEL * OUTPUTS_PER_TILE; // data bus width in bytes |
localparam AVF_B = BYTES_PER_PIXEL * 8; // bits per pixel on TDATA |
|
virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_in_if[]; |
virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_out_if[]; |
|
avf_config_class c_h; |
|
avf_tx_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U) tx_h; |
avf_rx_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U) rx_h; |
|
video_frame_class clone_h; |
video_frame_class sent_f_h; |
video_frame_class rx_f_h; |
|
mailbox #(video_frame_class) q[]; |
|
|
// -------------------------------------------------------------------- |
// |
virtual task |
queue_frame |
( |
string pattern = "", |
int pixel = 0 |
); |
|
if(pattern != "") |
tx_h.make_frame(pattern, pixel); |
|
foreach(tx_h.tx_bfm_h[i]) |
begin |
clone_h = tx_h.tx_bfm_h[i].f_h.clone(); |
tx_h.tx_bfm_h[i].put(clone_h); |
q[i].put(clone_h); |
end |
|
$display("^^^ %16.t | %m | using %s pattern", $time, pattern); |
|
endtask: queue_frame |
|
|
// -------------------------------------------------------------------- |
// |
virtual task automatic |
compare_frame; |
|
int mismatch_count; |
|
$display("^^^ %16.t | %m", $time); |
|
foreach(rx_h.rx_bfm_h[i]) |
begin |
q[i].get(sent_f_h); |
rx_h.rx_bfm_h[i].get(rx_f_h); |
mismatch_count = sent_f_h.compare(8, rx_f_h); |
end |
|
endtask: compare_frame |
|
|
// -------------------------------------------------------------------- |
// |
virtual task set_tready(input tready); |
$display("^^^ %16.t | %m", $time); |
foreach(rx_h.rx_bfm_h[i]) |
rx_h.rx_bfm_h[i].set_tready(tready); |
endtask: set_tready |
|
|
// -------------------------------------------------------------------- |
// |
virtual task flush_sent_frame; |
$display("^^^ %16.t | %m", $time); |
foreach(rx_h.rx_bfm_h[i]) |
q[i].get(sent_f_h); |
endtask: flush_sent_frame |
|
|
// -------------------------------------------------------------------- |
// |
virtual task rx_flush_frame; |
$display("^^^ %16.t | %m", $time); |
foreach(rx_h.rx_bfm_h[i]) |
rx_h.rx_bfm_h[i].get(rx_f_h); |
endtask: rx_flush_frame |
|
|
//-------------------------------------------------------------------- |
// |
function void init(avf_config_class c_h); |
|
rx_h = new(c_h, avf_axis_in_if); |
tx_h = new(c_h, avf_axis_out_if); |
|
this.q = new[$size(avf_axis_out_if)]; |
foreach(q[i]) |
this.q[i] = new(); |
|
endfunction: init |
|
|
//-------------------------------------------------------------------- |
// |
function new |
( |
virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_in_if[], |
virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_out_if[] |
); |
|
this.avf_axis_in_if = avf_axis_in_if; |
this.avf_axis_out_if = avf_axis_out_if; |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
|
endclass: avf_agent_class |
|
endpackage: avf_agent_class_pkg |
|
|
|
|
|
/legacy/avf_rx.sv
0,0 → 1,134
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
import axis_video_frame_bfm_pkg::*; |
|
module |
avf_rx |
#( |
BYTES_PER_PIXEL = 2, |
AVF_OUTPUTS = 4, |
AVF_TILES = 1 |
) |
( |
ref axis_video_frame_bfm_class f_tx_h[AVF_TILES], |
ref axis_video_frame_bfm_class f_rx_h[AVF_TILES] |
); |
|
// -------------------------------------------------------------------- |
// |
localparam AVF_VERTICAL_BLANKING = 20; |
|
task automatic |
init_avf_rx; |
|
f_rx_h[0].run_rx_q(RIGHT_DOWN); |
f_rx_h[1].run_rx_q(RIGHT_UP); |
f_rx_h[2].run_rx_q(LEFT_DOWN); |
f_rx_h[3].run_rx_q(LEFT_UP); |
|
endtask: init_avf_rx |
|
|
// -------------------------------------------------------------------- |
// |
task |
wait_for_rx_frames |
( |
input int unsigned count |
); |
|
repeat(count) |
@(f_rx_h[0].rx_frame_done); |
|
endtask: wait_for_rx_frames |
|
|
// -------------------------------------------------------------------- |
// |
semaphore get_frame_semaphore = new(1); |
logic get_frame_active = 0; |
|
task automatic |
get_frame; |
|
if(get_frame_semaphore.try_get() == 0) |
begin |
$display("^^^ %16.t | %m | ERROR! Already getting a frame.", $time); |
return; |
end |
|
$display("^^^ %16.t | %m | getting a frame.", $time); |
get_frame_active = 1; |
|
fork |
begin |
|
f_rx_h[0].avf_fork_rx(RIGHT_DOWN); |
f_rx_h[1].avf_fork_rx(RIGHT_UP); |
f_rx_h[2].avf_fork_rx(LEFT_DOWN); |
f_rx_h[3].avf_fork_rx(LEFT_UP); |
|
wait fork; |
get_frame_active = 0; |
$display("^^^ %16.t | %m | Got a frame.", $time); |
get_frame_semaphore.put(); |
|
end |
join_none |
|
|
endtask: get_frame |
|
|
// -------------------------------------------------------------------- |
// |
import video_frame_pkg::*; |
|
function automatic |
int compare_frame; |
|
int mismatch_count[AVF_TILES]; |
|
$display("^^^ %16.t | %m", $time); |
|
foreach(f_rx_h[i]) |
mismatch_count[i] = f_rx_h[i].f_h.compare(8, f_tx_h[i].f_h); |
|
|
endfunction: compare_frame |
|
|
// -------------------------------------------------------------------- |
// |
|
|
endmodule |
|
|
|
|
/legacy/avf_tx.sv
0,0 → 1,171
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
|
import axis_video_frame_bfm_pkg::*; |
|
module |
avf_tx |
#( |
BYTES_PER_PIXEL = 2, |
AVF_OUTPUTS = 4, |
AVF_TILES = 1 |
) |
( |
ref axis_video_frame_bfm_class f_tx_h[AVF_TILES], |
ref axis_video_frame_bfm_class f_rx_h[AVF_TILES] |
); |
|
// -------------------------------------------------------------------- |
// |
localparam AVF_VERTICAL_BLANKING = 20; |
|
task automatic |
init_avf_tx; |
|
foreach(f_tx_h[i]) |
f_tx_h[i].avf_vertical_blanking = AVF_VERTICAL_BLANKING; |
|
f_tx_h[0].run_tx_q(RIGHT_DOWN, 0); |
f_tx_h[1].run_tx_q(RIGHT_UP, 0); |
f_tx_h[2].run_tx_q(LEFT_DOWN, 0); |
f_tx_h[3].run_tx_q(LEFT_UP, 0); |
|
endtask: init_avf_tx |
|
|
// -------------------------------------------------------------------- |
// |
import video_frame_pkg::*; |
|
video_frame_class clone_h; |
|
|
// -------------------------------------------------------------------- |
// |
task automatic |
make_frame |
( |
string pattern, |
int pixel = 0 |
); |
|
case(pattern.tolower) |
"constant": foreach(f_tx_h[i]) f_tx_h[i].f_h.make_constant(pixel); |
"counting": foreach(f_tx_h[i]) f_tx_h[i].f_h.make_counting(); |
"horizontal": foreach(f_tx_h[i]) f_tx_h[i].f_h.make_horizontal(); |
"vertical": foreach(f_tx_h[i]) f_tx_h[i].f_h.make_vertical(); |
"random": foreach(f_tx_h[i]) f_tx_h[i].f_h.make_random(); |
default: $display("^^^ %16.t | %m | ERROR! %s pattern not supported", $time, pattern); |
endcase |
|
endtask: make_frame |
|
|
// -------------------------------------------------------------------- |
// |
|
task automatic |
queue_frame |
( |
string pattern = "" |
); |
|
if(pattern != "") |
make_frame(pattern); |
|
foreach(f_tx_h[i]) |
begin |
clone_h = f_tx_h[i].f_h.clone(); |
f_tx_h[i].avf_q.put(clone_h); |
f_rx_h[i].avf_q.put(clone_h); |
end |
|
$display("^^^ %16.t | %m | using %s pattern", $time, pattern); |
|
endtask: queue_frame |
|
|
// -------------------------------------------------------------------- |
// |
task |
wait_for_tx_frames |
( |
input int unsigned count |
); |
|
repeat(count) |
@(f_tx_h[0].tx_frame_done); |
|
endtask: wait_for_tx_frames |
|
|
// -------------------------------------------------------------------- |
// |
logic put_frame_active = 0; |
semaphore put_frame_semaphore = new(1); |
|
task automatic |
put_frame; |
|
if(put_frame_semaphore.try_get() == 0) |
begin |
$display("^^^ %16.t | %m | ERROR! Already put a frame.", $time); |
return; |
end |
|
$display("^^^ %16.t | %m | Putting a frame.", $time); |
put_frame_active = 1; |
|
fork |
begin |
|
f_tx_h[0].avf_fork_tx(RIGHT_DOWN, 0); |
f_tx_h[1].avf_fork_tx(RIGHT_UP, 0); |
f_tx_h[2].avf_fork_tx(LEFT_DOWN, 0); |
f_tx_h[3].avf_fork_tx(LEFT_UP, 0); |
|
wait fork; |
put_frame_active = 0; |
$display("^^^ %16.t | %m | Put a frame.", $time); |
put_frame_semaphore.put(); |
|
end |
join_none |
|
endtask: put_frame |
|
|
// -------------------------------------------------------------------- |
// |
|
|
endmodule |
|
|
|
|
/legacy/axis_video_frame_bfm_pkg.sv
0,0 → 1,617
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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[]; |
|
|
//-------------------------------------------------------------------- |
function |
new |
( |
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 automatic |
avf_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 ); |
endcase |
|
endtask: avf_direction |
|
|
// -------------------------------------------------------------------- |
// |
task automatic |
avf_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 ); |
endcase |
|
avf_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 outputs |
x_eol = x_end - inc.x; |
|
endtask: avf_calculate |
|
endclass: 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 bytes |
localparam AVF_B = BYTES_PER_PIXEL * 8; // bits per pixel on TDATA |
|
virtual 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 automatic |
output_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 automatic |
avf_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 pixel |
avf_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) |
begin |
|
if((l == start.y) & (p == start.x)) // first pixel already asserted |
continue; |
|
@(avf_axis_if.cb_m iff avf_axis_if.cb_m.tready) |
begin |
avf_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; |
else |
avf_axis_if.cb_m.tuser[1] <= 0; |
|
if(p == x_eol) |
avf_axis_if.cb_m.tlast <= 1; |
else |
avf_axis_if.cb_m.tlast <= 0; |
|
if((l == y_end - 1) && (p == x_eol)) |
avf_axis_if.cb_m.tuser[2] <= 1; |
end |
end |
|
@(avf_axis_if.cb_m); |
wait(avf_axis_if.cb_m.tready); |
axis_default(); |
|
endtask: avf_tx |
|
|
// -------------------------------------------------------------------- |
// |
task |
avf_fork_tx; |
|
fork |
avf_tx(tile.direction, tile.delay); |
join_none |
|
#0; |
|
endtask: avf_fork_tx |
|
|
// -------------------------------------------------------------------- |
// |
event tx_frame_done; |
|
task automatic |
transmit(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 |
|
|
//-------------------------------------------------------------------- |
// |
function |
new |
( |
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 bytes |
localparam AVF_B = BYTES_PER_PIXEL * 8; // bits per pixel on TDATA |
|
virtual 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 automatic |
set_tready(input tready); |
|
avf_axis_if.cb_s.tready <= tready; |
|
endtask: set_tready |
|
|
// -------------------------------------------------------------------- |
// |
task automatic |
avf_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) |
begin |
|
wait(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); |
|
end |
|
endtask: avf_rx |
|
|
// -------------------------------------------------------------------- |
// |
task automatic |
avf_fork_rx; |
|
fork |
avf_rx(tile.direction); |
join_none |
|
#0; |
|
endtask: avf_fork_rx |
|
|
// -------------------------------------------------------------------- |
// |
event rx_frame_done; |
|
virtual task |
receive(ref Q_T tr_h); |
|
avf_fork_rx(); |
wait fork; |
|
tr_h = f_h.clone(); |
->rx_frame_done; |
|
endtask: receive |
|
|
//-------------------------------------------------------------------- |
// |
function |
new |
( |
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 bytes |
localparam AVF_B = BYTES_PER_PIXEL * 8; // bits per pixel on TDATA |
|
int 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 automatic |
make_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); |
endcase |
|
endtask: make_frame |
|
|
// -------------------------------------------------------------------- |
// |
virtual task |
wait_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 bytes |
localparam AVF_B = BYTES_PER_PIXEL * 8; // bits per pixel on TDATA |
|
int 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 task |
wait_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 |
|
/s_avf_api.svh
0,0 → 1,101
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class s_avf_api |
extends uvm_sequence #(avf_sequence_item); |
`uvm_object_utils(s_avf_api) |
|
avf_sequence_item item; |
|
// -------------------------------------------------------------------- |
mailbox #(video_frame_class) frame_buffer; |
int pixels_per_line; |
int lines_per_frame; |
int bits_per_pixel; |
int bytes_per_pixel; |
int pixels_per_clk; |
|
// -------------------------------------------------------------------- |
function void init( int pixels_per_line |
, int lines_per_frame |
, int bits_per_pixel |
, int pixels_per_clk |
); |
this.pixels_per_line = pixels_per_line; |
this.lines_per_frame = lines_per_frame; |
this.bits_per_pixel = bits_per_pixel; |
this.bytes_per_pixel = (bits_per_pixel % 8 == 0) |
? (bits_per_pixel / 8) |
: (bits_per_pixel / 8) + 1; |
this.pixels_per_clk = pixels_per_clk; |
endfunction : init |
|
// -------------------------------------------------------------------- |
task automatic put_frame(string pattern, int pixel = 0); |
video_frame_class f_h = new; |
f_h.init( pixels_per_line |
, lines_per_frame |
, bits_per_pixel |
, pixels_per_clk |
); |
case(pattern.tolower) |
"constant": f_h.make_constant(pixel); |
"counting": f_h.make_counting(); |
"horizontal": f_h.make_horizontal(); |
"vertical": f_h.make_vertical(); |
"random": f_h.make_random(); |
default: `uvm_fatal(get_name(), "Pattern not supported!") |
endcase |
|
frame_buffer.put(f_h); |
uvm_report_info(get_name(), $sformatf("| put_frame(%s)", pattern.tolower)); |
endtask: put_frame |
|
// -------------------------------------------------------------------- |
task send_frame_buffer( uvm_sequencer_base seqr |
, uvm_sequence_base parent = null |
); |
this.start(seqr, parent); |
endtask |
|
// -------------------------------------------------------------------- |
task body(); |
item = avf_sequence_item::type_id::create("avf_sequence_item"); |
start_item(item); |
if(frame_buffer.num() != 0) |
item.frame_buffer = this.frame_buffer; |
finish_item(item); |
endtask |
|
// -------------------------------------------------------------------- |
function new(string name = "s_avf_api"); |
super.new(name); |
frame_buffer = new; |
endfunction |
|
// -------------------------------------------------------------------- |
endclass : s_avf_api |
/s_avf_base.svh
0,0 → 1,54
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class s_avf_base |
extends uvm_sequence #(avf_sequence_item); |
`uvm_object_utils(s_avf_base) |
|
s_avf_api avf_api_h; |
|
// -------------------------------------------------------------------- |
function void init( int pixels_per_line |
, int lines_per_frame |
, int bits_per_pixel |
, int pixels_per_clk |
); |
avf_api_h = s_avf_api::type_id::create("s_avf_api"); |
avf_api_h.init( pixels_per_line |
, lines_per_frame |
, bits_per_pixel |
, pixels_per_clk |
); |
endfunction : init |
|
// -------------------------------------------------------------------- |
function new(string name = "s_avf_base"); |
super.new(name); |
endfunction |
|
// -------------------------------------------------------------------- |
endclass : s_avf_base |
/s_avf_slave_base.svh
0,0 → 1,51
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2018 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class s_avf_slave_base |
extends uvm_sequence #(avf_sequence_item); |
`uvm_object_utils(s_avf_slave_base) |
|
avf_slave_sequencer sequencer_h; |
avf_sequence_item item; |
|
// -------------------------------------------------------------------- |
task body(); |
forever |
begin |
sequencer_h.m_request_fifo.get(item); |
start_item(item); |
finish_item(item); |
end |
endtask: body |
|
// -------------------------------------------------------------------- |
function new(string name = "s_avf_slave_base"); |
super.new(name); |
endfunction |
|
// -------------------------------------------------------------------- |
endclass : s_avf_slave_base |