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
- from Rev 50 to Rev 49
- ↔ Reverse comparison
Rev 50 → Rev 49
/sim/tests/tb_video_frame_dpi/py_raw_to_frame.py
0,0 → 1,92
# |
# //////////////////////////////////////////////////////////////////// |
# // //// |
# // 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 //// |
# // //// |
# //////////////////////////////////////////////////////////////////// |
import sys |
# import sv_video |
import numpy as np |
# import matplotlib.pyplot as plt |
|
print("^^^ | py_raw_to_frame |") |
print('Number of arguments:', len(sys.argv), 'arguments.') |
print('Argument List:', str(sys.argv)) |
|
# dataSend = np.arange(1, 9 + 1, dtype=np.uint32) |
|
# tiny_frame = np.arange(32, 32 + 32, dtype=np.uint32) |
# data_list = tiny_frame.flatten() |
# data_list = tiny_frame.tolist() |
|
# sv_video.py_list_to_c_array(data_list) |
|
# --------------------------------------------------------- |
v_frames = 1 |
v_width = 8 |
v_height = 16 |
|
# # fname = sys.argv[0] |
# fname = 'count.raw' |
# print("file name: ", fname) |
|
# with open(fname, 'r') as infile: |
# data = np.fromfile(infile, dtype='uint16').reshape(v_frames, v_height, v_width) |
|
# np.set_printoptions(formatter={'int':hex}) |
|
# for i in range(v_frames): |
# print(data[i]) |
# fig, ax = plt.subplots() |
# im = ax.imshow(data[i], cmap='gray') |
# ax.set(xticks=[], yticks=[]) |
# fig.colorbar(im) |
# plt.show() |
|
# from __future__ import print_function |
# with open('out.txt', 'w') as f: |
# print('qqq\n', file=f) |
# print(data[0], file=f) |
|
# f = open('out.txt','w') |
# print >>f,'some Text' |
# print >>f, data[0].flatten() |
|
# for i in range(v_frames*v_height*v_width): |
# print >>f, data[0].flatten()[i] |
|
# data = np.arange(v_frames*v_width*v_height, dtype='uint16') |
# data = data.reshape(v_frames, v_height, v_width) |
|
# f = open('count.raw','r') |
data = np.fromfile('count.raw', dtype='uint16') |
|
print(data) |
print(data.shape) |
|
# with open('init_test.do') as fp: |
# for line in fp: |
# print line |
|
|
/src/axis_video_frame/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 |
|
/src/axis_video_frame/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 |
|
|
|
|
|
/src/axis_video_frame/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 |
|
|
|
|
/src/axis_video_frame/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 |
|
|
|
|
/src/axis_video_frame/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 |
|
|
|
|
/src/video_frame/video_frame_class.svh
27,6 → 27,7
|
// -------------------------------------------------------------------- |
class video_frame_class; |
logger_class log; |
rand int frame_id; |
rand int pixels_per_line; |
rand int lines_per_frame; |
58,6 → 59,7
|
//-------------------------------------------------------------------- |
function new; |
this.log = new; |
this.frame_id = 0; |
endfunction: new |
|
70,6 → 72,7
int pixels_per_clk = 1, |
string name = "" |
); |
log.info($sformatf("%m")); |
this.pixels_per_line = pixels_per_line; |
this.lines_per_frame = lines_per_frame; |
this.bits_per_pixel = bits_per_pixel; |
110,6 → 113,7
|
// -------------------------------------------------------------------- |
function void make_constant(int pixel); |
log.info($sformatf("%m")); |
this.lines = new[lines_per_frame]; |
|
foreach(this.lines[l]) |
125,6 → 129,7
|
// -------------------------------------------------------------------- |
function void make_counting(int offset = 0); |
log.info($sformatf("%m")); |
this.lines = new[lines_per_frame]; |
|
foreach(this.lines[l]) |
140,6 → 145,7
|
// -------------------------------------------------------------------- |
function void make_horizontal(); |
log.info($sformatf("%m")); |
this.lines = new[lines_per_frame]; |
|
foreach(this.lines[l]) |
155,6 → 161,7
|
// -------------------------------------------------------------------- |
function void make_vertical(); |
log.info($sformatf("%m")); |
this.lines = new[lines_per_frame]; |
|
foreach(this.lines[l]) |
170,6 → 177,7
|
// -------------------------------------------------------------------- |
function void make_random(); |
log.info($sformatf("%m")); |
this.lines = new[lines_per_frame]; |
|
foreach(this.lines[l]) |
185,6 → 193,7
|
// -------------------------------------------------------------------- |
function void copy(video_frame_class from); |
log.info($sformatf("%m")); |
this.frame_id = from.frame_id; |
this.pixels_per_line = from.pixels_per_line; |
this.lines_per_frame = from.lines_per_frame; |
203,6 → 212,7
|
// -------------------------------------------------------------------- |
virtual function video_frame_class clone; |
log.info($sformatf("%m")); |
clone = new(); |
clone.copy(this); |
endfunction: clone |
209,6 → 219,7
|
// -------------------------------------------------------------------- |
function video_frame_class catenate_horizontally(video_frame_class tail); |
log.info($sformatf("%m")); |
|
if(this.lines_per_frame != tail.lines_per_frame) |
return(null); |
237,6 → 248,7
|
// -------------------------------------------------------------------- |
function void shift_right(ref line_s column); |
log.info($sformatf("%m")); |
|
foreach(this.lines[l]) |
for(int p = pixels_per_line - 1; p > 0; p--) |
246,127 → 258,114
this.lines[l].pixel[0] = column.pixel[l]; |
endfunction: shift_right |
|
// // -------------------------------------------------------------------- |
// function int compare_line |
// ( int line |
// , int max_mismatches |
// , video_frame_class to |
// ); |
// int mismatch_count = 0; |
// -------------------------------------------------------------------- |
function int compare_line |
( int line |
, int max_mismatches |
, video_frame_class to |
); |
int mismatch_count = 0; |
|
// if(to.bits_per_pixel != this.bits_per_pixel) |
// begin |
// log.error($sformatf("to.bits_per_pixel != this.bits_per_pixel | %s", name)); |
// return(-3); |
// end |
if(to.bits_per_pixel != this.bits_per_pixel) |
begin |
log.error($sformatf("to.bits_per_pixel != this.bits_per_pixel | %s", name)); |
return(-3); |
end |
|
// foreach(this.lines[line].pixel[p]) |
// if(to.lines[line].pixel[p] != this.lines[line].pixel[p]) |
// begin |
foreach(this.lines[line].pixel[p]) |
if(to.lines[line].pixel[p] != this.lines[line].pixel[p]) |
begin |
|
// if(max_mismatches > 0) |
// mismatch_count++; |
if(max_mismatches > 0) |
mismatch_count++; |
|
// log.error($sformatf("mismatch @ frame[%4h][%4h] | to == %4h | this == %4h | %s", |
// line, p, to.lines[line].pixel[p], this.lines[line].pixel[p], name)); |
log.error($sformatf("mismatch @ frame[%4h][%4h] | to == %4h | this == %4h | %s", |
line, p, to.lines[line].pixel[p], this.lines[line].pixel[p], name)); |
|
// if(mismatch_count > max_mismatches) |
// return(mismatch_count); |
// end |
if(mismatch_count > max_mismatches) |
return(mismatch_count); |
end |
|
// return(mismatch_count); |
// endfunction: compare_line |
return(mismatch_count); |
endfunction: compare_line |
|
// // -------------------------------------------------------------------- |
// function int compare(int max_mismatches, video_frame_class to); |
// int mismatch_count = 0; |
// log.info($sformatf("%m")); |
// -------------------------------------------------------------------- |
function int compare(int max_mismatches, video_frame_class to); |
int mismatch_count = 0; |
log.info($sformatf("%m")); |
|
// if(to.pixels_per_line != this.pixels_per_line) |
// begin |
// log.error($sformatf("to.pixels_per_line != this.pixels_per_line | %s", name)); |
// return(-1); |
// end |
if(to.pixels_per_line != this.pixels_per_line) |
begin |
log.error($sformatf("to.pixels_per_line != this.pixels_per_line | %s", name)); |
return(-1); |
end |
|
// if(to.lines_per_frame != this.lines_per_frame) |
// begin |
// log.error($sformatf("to.lines_per_frame != this.lines_per_frame | %s", name)); |
// return(-2); |
// end |
if(to.lines_per_frame != this.lines_per_frame) |
begin |
log.error($sformatf("to.lines_per_frame != this.lines_per_frame | %s", name)); |
return(-2); |
end |
|
// if(to.bits_per_pixel != this.bits_per_pixel) |
// begin |
// log.error($sformatf("to.bits_per_pixel != this.bits_per_pixel | %s", name)); |
// return(-3); |
// end |
if(to.bits_per_pixel != this.bits_per_pixel) |
begin |
log.error($sformatf("to.bits_per_pixel != this.bits_per_pixel | %s", name)); |
return(-3); |
end |
|
// foreach(this.lines[l]) |
// begin |
// foreach(this.lines[l].pixel[p]) |
// if(to.lines[l].pixel[p] != this.lines[l].pixel[p]) |
// begin |
// if(max_mismatches > 0) |
// mismatch_count++; |
foreach(this.lines[l]) |
begin |
foreach(this.lines[l].pixel[p]) |
if(to.lines[l].pixel[p] != this.lines[l].pixel[p]) |
begin |
if(max_mismatches > 0) |
mismatch_count++; |
|
// log.error($sformatf("mismatch @ frame[%4h][%4h] | to == %4h | this == %4h | %s", l, p, to.lines[l].pixel[p], this.lines[l].pixel[p], name)); |
log.error($sformatf("mismatch @ frame[%4h][%4h] | to == %4h | this == %4h | %s", l, p, to.lines[l].pixel[p], this.lines[l].pixel[p], name)); |
|
// if(mismatch_count > max_mismatches) |
// return(mismatch_count); |
// end |
// end |
if(mismatch_count > max_mismatches) |
return(mismatch_count); |
end |
end |
|
// return(mismatch_count); |
// endfunction: compare |
return(mismatch_count); |
endfunction: compare |
|
// // -------------------------------------------------------------------- |
// function void print_line(int line, int pixel, int count); |
// log.info($sformatf("%m")); |
// -------------------------------------------------------------------- |
function void print_line(int line, int pixel, int count); |
log.info($sformatf("%m")); |
|
// for(int i = 0; i < count; i++) |
// log.display($sformatf("%4h @ frame[%4h][%4h] | %s", this.lines[line].pixel[(pixel + i)], line, (pixel + i), name)); |
// endfunction: print_line |
for(int i = 0; i < count; i++) |
log.display($sformatf("%4h @ frame[%4h][%4h] | %s", this.lines[line].pixel[(pixel + i)], line, (pixel + i), name)); |
endfunction: print_line |
|
// // -------------------------------------------------------------------- |
// function void print_config(); |
// log.display($sformatf("%m | frame_id = %06d | %s", frame_id, name)); |
// log.display($sformatf("%m | pixels_per_line = %06d | %s", pixels_per_line, name)); |
// log.display($sformatf("%m | lines_per_frame = %06d | %s", lines_per_frame, name)); |
// log.display($sformatf("%m | bits_per_pixel = %06d | %s", bits_per_pixel, name)); |
// log.display($sformatf("%m | pixels_per_clk = %06d | %s", pixels_per_clk, name)); |
// log.display($sformatf("%m | pattern = %s | %s", pattern, name)); |
// endfunction: print_config |
|
// -------------------------------------------------------------------- |
function void print_config(); |
$display($sformatf("%m | frame_id = %06d | %s", frame_id, name)); |
$display($sformatf("%m | pixels_per_line = %06d | %s", pixels_per_line, name)); |
$display($sformatf("%m | lines_per_frame = %06d | %s", lines_per_frame, name)); |
$display($sformatf("%m | bits_per_pixel = %06d | %s", bits_per_pixel, name)); |
$display($sformatf("%m | pixels_per_clk = %06d | %s", pixels_per_clk, name)); |
$display($sformatf("%m | pattern = %s | %s", pattern, name)); |
log.display($sformatf("%m | frame_id = %06d | %s", frame_id, name)); |
log.display($sformatf("%m | pixels_per_line = %06d | %s", pixels_per_line, name)); |
log.display($sformatf("%m | lines_per_frame = %06d | %s", lines_per_frame, name)); |
log.display($sformatf("%m | bits_per_pixel = %06d | %s", bits_per_pixel, name)); |
log.display($sformatf("%m | pixels_per_clk = %06d | %s", pixels_per_clk, name)); |
log.display($sformatf("%m | pattern = %s | %s", pattern, name)); |
endfunction: print_config |
|
// -------------------------------------------------------------------- |
function string convert2string(int grid=8); |
string s0, s1; |
string s; |
string f =""; |
int nibbles = ( bits_per_pixel % 4 == 0) |
? bits_per_pixel / 4 |
: (bits_per_pixel / 4) + 1; |
string fs = $sformatf("%%s%%%0d.h" , (bits_per_pixel % 4 == 0) |
? bits_per_pixel / 4 |
: (bits_per_pixel / 4) + 1 |
); |
foreach(this.lines[l]) |
begin |
s = $sformatf("[%4.d]", l); |
foreach(this.lines[l].pixel[p]) |
s = {s, $sformatf(fs, (p % grid == 0) ? "!" : "|", this.lines[l].pixel[p])}; |
|
foreach(this.lines[l]) begin |
s0 = $sformatf("[%4.d]", l); |
foreach(this.lines[l].pixel[p]) begin |
s1 = $sformatf("%.h", this.lines[l].pixel[p]); |
s1 = s1.substr(nibbles, s1.len()-1); |
s0 = {s0, (p % grid == 0) ? "!" : "|", s1}; |
end |
|
f = {f, s0, "|\n"}; |
f = {f, s, "|\n"}; |
end |
|
return f; |
endfunction: convert2string |
|
// -------------------------------------------------------------------- |
endclass |
endclass: video_frame_class |
/src/video_frame/video_frame_config.svh
57,4 → 57,4
endfunction : init |
|
// -------------------------------------------------------------------- |
endclass |
endclass: video_frame_config |
/src/video_frame/video_frame_pkg.sv
26,6 → 26,7
////////////////////////////////////////////////////////////////////// |
|
package video_frame_pkg; |
import logger_pkg::*; |
|
// -------------------------------------------------------------------- |
typedef struct |
49,4 → 50,4
`include "video_frame_class.svh" |
|
// -------------------------------------------------------------------- |
endpackage |
endpackage: video_frame_pkg |
/src/SPI/spi_driver.svh
25,17 → 25,17
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class spi_driver #(N) |
class spi_driver |
extends uvm_driver #(spi_sequence_item); |
`uvm_component_param_utils(spi_driver #(N)) |
`uvm_component_utils(spi_driver) |
|
// -------------------------------------------------------------------- |
virtual spi_if #(N) vif; |
virtual spi_if vif; |
|
//-------------------------------------------------------------------- |
function void set_default; |
vif.sclk <= 0; |
vif.ss_n <= '1; |
vif.ss_n <= 1; |
vif.mosi <= 'x; |
endfunction: set_default |
|
51,8 → 51,7
index = 0; |
seq_item_port.get_next_item(item); |
|
vif.ss_n <= ~(1 << item.ss_index); |
|
vif.ss_n <= 0; |
vif.mosi <= item.mosi_data[index]; |
#(vif.period / 2); |
|
76,7 → 75,7
end |
|
#(vif.period / 2); |
vif.ss_n <= '1; |
vif.ss_n <= 1; |
|
set_default(); |
seq_item_port.item_done(); |
90,4 → 89,4
endfunction |
|
// -------------------------------------------------------------------- |
endclass |
endclass : spi_driver |
/src/SPI/spi_sequence_item.svh
35,7 → 35,6
// -------------------------------------------------------------------- |
logic miso_data[]; // data from slave to master |
logic mosi_data[]; // data from master to slave |
int ss_index = 0; |
bit read; |
bit write; |
|
57,34 → 56,38
mosi_data[i] = 0; |
endfunction : init |
|
// -------------------------------------------------------------------- |
function void load_mosi_from_file(string file_name); |
byte buffer; |
integer fd; |
integer code; |
integer size; |
// // -------------------------------------------------------------------- |
// function bit do_compare(uvm_object rhs, uvm_comparer comparer); |
// spi_sequence_item tested; |
// bit same; |
|
fd = $fopen(file_name, "rb"); |
code = $fseek(fd, 0, 2); // SEEK_END |
size = $ftell(fd); |
code = $rewind(fd); |
data_width = size*8; |
mosi_data = new[data_width]; |
write = 1; |
// if (rhs==null) |
// `uvm_fatal(get_type_name(), "| %m | comparison to a null pointer"); |
|
for(int i = 0; i < size; i++) begin |
code = $fread(buffer, fd); |
mosi_data[i*8 +: 8] = {>>{buffer}}; |
end |
// if (!$cast(tested,rhs)) |
// same = 0; |
// else |
// same = super.do_compare(rhs, comparer); |
|
$fclose(fd); |
endfunction |
// return same; |
// endfunction : do_compare |
|
// -------------------------------------------------------------------- |
function void load_mosi_from_byte_array(byte byte_array[]); |
foreach(byte_array[i]) |
mosi_data[i*8 +: 8] = {>>{byte_array[i]}}; |
endfunction |
// // -------------------------------------------------------------------- |
// function void do_copy(uvm_object rhs); |
// spi_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(); |
99,7 → 102,8
); |
s0 = {s0, s1}; |
|
if(read) begin |
if(read) |
begin |
data = {>>{miso_data}}; |
|
foreach(data[i]) |
109,7 → 113,8
s0 = {s0, s2}; |
end |
|
if(write) begin |
if(write) |
begin |
data = {>>{mosi_data}}; |
|
foreach(data[i]) |
123,4 → 128,4
endfunction : convert2string |
|
// -------------------------------------------------------------------- |
endclass |
endclass : spi_sequence_item |
/src/SPI/spi_agent.svh
25,24 → 25,32
//// //// |
////////////////////////////////////////////////////////////////////// |
|
class spi_agent #(N=1) |
class spi_agent |
extends uvm_agent; |
`uvm_component_param_utils(spi_agent #(N)) |
`uvm_component_utils(spi_agent) |
|
// -------------------------------------------------------------------- |
virtual spi_if #(N) vif; |
spi_driver #(N) driver_h; |
virtual spi_if vif; |
spi_driver driver_h; |
spi_sequencer sequencer_h; |
// spi_monitor monitor_h; |
|
// -------------------------------------------------------------------- |
virtual function void build_phase(uvm_phase phase); |
driver_h = spi_driver #(N)::type_id::create("driver_h", this); |
// super.build_phase(phase); |
driver_h = spi_driver::type_id::create("driver_h", this); |
// monitor_h = spi_monitor ::type_id::create("monitor_h", this); |
sequencer_h = spi_sequencer::type_id::create("sequencer_h", this); |
|
endfunction |
|
// -------------------------------------------------------------------- |
virtual function void connect_phase(uvm_phase phase); |
// super.connect_phase(phase); |
|
driver_h.vif = vif; |
// monitor_h.vif = vif; |
|
driver_h.seq_item_port.connect(sequencer_h.seq_item_export); |
endfunction |
|
52,4 → 60,4
endfunction |
|
// -------------------------------------------------------------------- |
endclass |
endclass : spi_agent |
/src/SPI/spi_if.sv
25,7 → 25,8
//// //// |
////////////////////////////////////////////////////////////////////// |
|
interface spi_if #(N=1); |
interface |
spi_if(); |
import uvm_pkg::*; |
`include "uvm_macros.svh" |
import tb_spi_pkg::*; |
32,7 → 33,7
|
// -------------------------------------------------------------------- |
logic sclk; |
logic [N-1:0] ss_n; |
logic ss_n; |
logic mosi; |
logic miso; |
|
/src/SPI/tb_spi_pkg.sv
28,12 → 28,28
package tb_spi_pkg; |
import uvm_pkg::*; |
`include "uvm_macros.svh" |
import bfm_pkg::*; |
|
// // -------------------------------------------------------------------- |
// localparam W = 16; |
// localparam D = 8; |
// localparam UB = $clog2(D); |
|
// -------------------------------------------------------------------- |
// typedef enum {FIFO_RD, FIFO_WR, FIFO_BOTH, FIFO_NULL} fifo_command_t; |
|
// -------------------------------------------------------------------- |
`include "spi_sequence_item.svh" |
typedef uvm_sequencer #(spi_sequence_item) spi_sequencer; |
`include "spi_driver.svh" |
// `include "spi_monitor.svh" |
// `include "spi_scoreboard.svh" |
`include "spi_agent.svh" |
// `include "tb_env.svh" |
|
// `include "s_debug.svh" |
// `include "t_top_base.svh" |
// `include "t_debug.svh" |
|
// -------------------------------------------------------------------- |
endpackage |
endpackage : tb_spi_pkg |
/src/tb/legacy/tb_clk.sv
File deleted
/src/tb/legacy/tb_clk_pkg.sv
File deleted
/src/tb/legacy/tb_base.sv
File deleted
/src/tb/legacy/logger_pkg.sv
File deleted
/src/tb/legacy/q_pkg.sv
File deleted
/src/tb/legacy/tb_clk_class.sv
File deleted
/src/tb/legacy/bfm_pkg.sv
File deleted
/src/tb/legacy/tb_bfm_pkg.sv
File deleted
/src/tb/tb_pkg.sv
31,4 → 31,4
`include "random_delay.svh" |
|
// -------------------------------------------------------------------- |
endpackage |
endpackage : tb_pkg |
/src/tb/bfm_pkg.sv
0,0 → 1,106
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 bfm_pkg; |
|
// -------------------------------------------------------------------- |
// |
typedef enum |
{ |
NONE, |
REGULAR |
// BURSTY |
} traffic_type_e; |
|
// -------------------------------------------------------------------- |
// |
class delay_class; |
|
rand int unsigned delay = 0; |
|
// -------------------------------------------------------------------- |
// |
virtual function void set_delay(traffic_type_e kind = REGULAR); |
case(kind) |
NONE: delay = 0; |
REGULAR: assert(this.randomize() with{delay dist {0 := 60, [1:3] := 30, [4:7] := 10};}); |
default: delay = 0; |
endcase |
endfunction: set_delay |
|
// -------------------------------------------------------------------- |
// |
virtual function int next(traffic_type_e kind = REGULAR); |
set_delay(kind); |
return(delay); |
endfunction: next |
|
// -------------------------------------------------------------------- |
// |
endclass: delay_class |
|
// -------------------------------------------------------------------- |
// |
virtual class transaction_class #(parameter type TR_T); |
|
delay_class delay_h; |
|
// -------------------------------------------------------------------- |
// |
function void random; |
assert(this.randomize()); |
endfunction: random |
|
//-------------------------------------------------------------------- |
// |
function new; |
delay_h = new(); |
endfunction: new |
|
// -------------------------------------------------------------------- |
// |
pure virtual function void copy(TR_T from); |
|
// -------------------------------------------------------------------- |
// |
function automatic TR_T clone; |
TR_T child; |
clone = new(); |
$cast(child, this); |
clone.copy(child); |
return(clone); |
endfunction: clone |
|
// -------------------------------------------------------------------- |
// |
endclass: transaction_class |
|
//-------------------------------------------------------------------- |
// |
endpackage: bfm_pkg |
|
/src/tb/logger_pkg.sv
0,0 → 1,136
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 logger_pkg; |
|
// -------------------------------------------------------------------- |
// |
typedef enum |
{ |
FATAL, |
ERROR, |
WARNING, |
INFO |
} logger_severity_t; |
|
|
// -------------------------------------------------------------------- |
// |
class logger_class; |
|
logger_severity_t verbosity = WARNING; |
bit log_debug = 0; |
string time_string; |
int error_count = 0; |
int max_error_display = 8; |
bit stop_at_max_error = 1; |
|
// -------------------------------------------------------------------- |
// |
function void |
set_verbosity(logger_severity_t level); |
verbosity = level; |
endfunction: set_verbosity |
|
|
// -------------------------------------------------------------------- |
// |
function void |
debug_enable; |
log_debug = 1; |
endfunction: debug_enable |
|
|
// -------------------------------------------------------------------- |
// |
function void debug(string message); |
time_string = $sformatf("??? %16.t | ", $time); |
if(log_debug == 1) |
$display({time_string, message}); |
endfunction: debug |
|
|
// -------------------------------------------------------------------- |
// |
function void display(string message); |
time_string = $sformatf("--- %16.t | ", $time); |
$display({time_string, message}); |
endfunction: display |
|
|
// -------------------------------------------------------------------- |
// |
function void info(string message); |
time_string = $sformatf("^^^ %16.t | ", $time); |
if(verbosity >= INFO) |
$display({time_string, message}); |
endfunction: info |
|
|
// -------------------------------------------------------------------- |
// |
function void warning(string message); |
time_string = $sformatf("*** %16.t | ", $time); |
if(verbosity >= WARNING) |
$display({time_string, message}); |
endfunction: warning |
|
|
// -------------------------------------------------------------------- |
// |
function void error(string message); |
time_string = $sformatf("!!! %16.t | ", $time); |
error_count++; |
if(error_count > max_error_display) |
if(stop_at_max_error) |
$stop; |
else |
return; |
|
if(verbosity >= ERROR) |
$display({time_string, message}); |
endfunction: error |
|
|
// -------------------------------------------------------------------- |
// |
function void fatal(string message); |
if(verbosity >= FATAL) |
$fatal(1, message); |
endfunction: fatal |
|
|
//-------------------------------------------------------------------- |
// |
endclass: logger_class |
|
|
//-------------------------------------------------------------------- |
// |
endpackage: logger_pkg |
|
/src/tb/q_pkg.sv
0,0 → 1,147
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 q_pkg; |
|
// -------------------------------------------------------------------- |
// |
virtual class q_base_class #(parameter type Q_T = logic); |
|
Q_T tr_h; |
mailbox #(Q_T) q; |
|
// -------------------------------------------------------------------- |
// |
pure virtual task run_q; |
|
|
// -------------------------------------------------------------------- |
// |
task put(ref Q_T tr_h); |
q.put(tr_h); |
endtask: put |
|
|
// -------------------------------------------------------------------- |
// |
task get(ref Q_T tr_h); |
q.get(tr_h); |
endtask: get |
|
|
//-------------------------------------------------------------------- |
function new; |
this.q = new(); |
fork |
forever |
run_q(); |
join_none |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: q_base_class |
|
|
// -------------------------------------------------------------------- |
// |
virtual class nonblocking_transmission_q_class #(parameter type Q_T = logic) |
extends q_base_class #(Q_T); |
|
// -------------------------------------------------------------------- |
// |
pure virtual task transmit(ref Q_T tr_h); |
pure virtual task idle(); |
|
|
// -------------------------------------------------------------------- |
// |
task automatic run_q; |
if(q.try_get(tr_h) != 0) |
transmit(tr_h); |
else |
idle(); |
endtask: run_q |
|
|
// -------------------------------------------------------------------- |
// |
endclass: nonblocking_transmission_q_class |
|
|
// -------------------------------------------------------------------- |
// |
virtual class blocking_transmission_q_class #(parameter type Q_T = logic) |
extends q_base_class #(Q_T); |
|
// -------------------------------------------------------------------- |
// |
pure virtual task transmit(ref Q_T tr_h); |
|
|
// -------------------------------------------------------------------- |
// |
task run_q; |
q.get(tr_h); |
transmit(tr_h); |
endtask: run_q |
|
|
// -------------------------------------------------------------------- |
// |
endclass: blocking_transmission_q_class |
|
|
// -------------------------------------------------------------------- |
// |
virtual class blocking_receiver_q_class #(parameter type Q_T = logic) |
extends q_base_class #(Q_T); |
|
// -------------------------------------------------------------------- |
// |
pure virtual task receive(ref Q_T tr_h); |
|
|
// -------------------------------------------------------------------- |
// |
task run_q; |
receive(tr_h); |
q.put(tr_h); |
endtask: run_q |
|
|
//-------------------------------------------------------------------- |
// |
endclass: blocking_receiver_q_class |
|
|
//-------------------------------------------------------------------- |
// |
endpackage: q_pkg |
|
/src/tb/tb_base.sv
1,6 → 1,6
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2019 Authors and OPENCORES.ORG //// |
//// Copyright (C) 2015 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
25,62 → 25,82
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`timescale 1ps/1ps |
|
import tb_clk_pkg::*; |
|
|
module |
tb_base |
#( |
N = 1, |
realtime PERIODS[N], |
realtime ASSERT_TIME = (PERIODS[0] * 5) + (PERIODS[0] / 3) |
parameter PERIOD = 0, |
parameter ASSERT_TIME = 0 |
) |
( |
output bit tb_clk[N], |
output bit tb_aresetn, |
output bit tb_reset[N] |
output clock, |
output reg reset |
); |
timeunit 1ns; |
timeprecision 100ps; |
|
// -------------------------------------------------------------------- |
function void assert_reset(realtime reset_assert=ASSERT_TIME); |
// |
task assert_reset |
( |
input time reset_assert |
); |
|
reset = 1; |
$display( "-#- %16.t | %m | reset asserted!", $time ); |
|
#reset_assert; |
|
reset = 0; |
$display( "-#- %16.t | %m | reset deasserted!", $time ); |
|
endtask |
|
|
// -------------------------------------------------------------------- |
// |
task timeout_stop |
( |
input time timeout |
); |
|
$display("-#- %16.t | %m | timeout_stop at %t", $time, timeout); |
|
fork |
begin |
tb_aresetn = 0; |
#reset_assert; |
tb_aresetn = 1; |
end |
#(timeout) $stop; |
join_none |
endfunction |
|
// -------------------------------------------------------------------- |
bit disable_clks[N]; |
endtask |
|
generate |
for(genvar j = 0; j < N; j++) begin |
always |
if(disable_clks[j]) |
tb_clk[j] = 0; |
else |
#(PERIODS[j]/2) tb_clk[j] = ~tb_clk[j]; |
end |
endgenerate |
|
// -------------------------------------------------------------------- |
generate |
for(genvar j = 0; j < N; j++) begin |
bit reset = 1; |
assign tb_reset[j] = reset; |
// |
tb_clk_class tb_clk_c; |
tb_clk_if tb_clk_driver(); |
assign clock = tb_clk_driver.clk; |
time reset_assert = (PERIOD * 5) + (PERIOD / 3); |
logic init_done = 0; |
|
always @(posedge tb_clk[j] or negedge tb_aresetn) |
if(~tb_aresetn) |
reset = 1; |
else |
reset = 0; |
initial |
begin |
|
reset = 1; |
|
tb_clk_c = new( tb_clk_driver ); |
|
if( PERIOD != 0 ) |
tb_clk_c.init_basic_clock( PERIOD ); |
|
if( ASSERT_TIME != 0 ) |
assert_reset( ASSERT_TIME ); |
else if( reset_assert != 0 ) |
assert_reset( reset_assert ); |
|
init_done = 1; |
|
end |
endgenerate |
endmodule |
|
// -------------------------------------------------------------------- |
initial |
assert_reset(); |
|
// -------------------------------------------------------------------- |
endmodule |
/src/tb/tb_bfm_pkg.sv
0,0 → 1,230
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 tb_bfm_pkg; |
|
// -------------------------------------------------------------------- |
// |
class tb_nonblocking_transaction_q_class #(parameter type T = logic); |
|
T tr_h; |
mailbox #(T) q; |
semaphore q_semaphore; |
|
//-------------------------------------------------------------------- |
function new; |
|
this.q = new(); |
this.q_semaphore = new(1); |
|
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
event start; |
event done; |
|
virtual task automatic |
transaction |
( |
ref T tr_h |
); |
|
->start; |
|
$display("^^^ %16.t | %m | ERROR! Task not defined |", $time); |
|
->done; |
|
endtask: transaction |
|
|
// -------------------------------------------------------------------- |
// |
virtual task automatic |
idle; |
|
$display("^^^ %16.t | %m | ERROR! Task not defined |", $time); |
|
endtask: idle |
|
|
// -------------------------------------------------------------------- |
// |
task |
put |
( |
ref T tr_h |
); |
|
$display("^^^ %16.t | %m | ", $time); |
|
q.put(tr_h); |
|
endtask: put |
|
|
// -------------------------------------------------------------------- |
// |
task automatic |
run_q; |
|
if(q_semaphore.try_get() == 0) |
begin |
$display("^^^ %16.t | %m | ERROR! Aready active |", $time); |
return; |
end |
|
$display("^^^ %16.t | %m is active |", $time); |
|
run_q_fork : fork |
forever |
if(q.try_get(tr_h) != 0) |
transaction(tr_h); |
else |
idle(); |
join_none |
|
#0; |
|
endtask: run_q |
|
|
// -------------------------------------------------------------------- |
// |
function void |
init; |
|
fork |
run_q(); |
join_none |
|
$display("^^^ %16.t | %m | initialization", $time); |
|
endfunction: init |
|
endclass: tb_nonblocking_transaction_q_class |
|
|
// -------------------------------------------------------------------- |
// |
class tb_blocking_transaction_q_class #(parameter type T = logic); |
|
T tr_h; |
mailbox #(T) q; |
semaphore q_semaphore; |
|
//-------------------------------------------------------------------- |
function new; |
|
this.q = new(); |
this.q_semaphore = new(1); |
|
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
event start; |
event done; |
|
virtual task automatic |
transaction |
( |
ref T tr_h |
); |
|
->start; |
|
$display("^^^ %16.t | %m | ERROR! Task not defined |", $time); |
|
->done; |
|
endtask: transaction |
|
|
// -------------------------------------------------------------------- |
// |
task |
put |
( |
ref T tr_h |
); |
|
q.put(tr_h); |
|
endtask: put |
|
|
// -------------------------------------------------------------------- |
// |
task automatic |
run_q; |
|
if(q_semaphore.try_get() == 0) |
begin |
$display("^^^ %16.t | %m | ERROR! Aready active |", $time); |
return; |
end |
|
$display("^^^ %16.t | %m is active |", $time); |
|
this.q = new(); |
|
run_q_fork : fork |
forever |
begin |
q.get(tr_h); |
transaction(tr_h); |
end |
join_none |
|
#0; |
|
endtask: run_q |
|
|
// -------------------------------------------------------------------- |
// |
function void |
init; |
|
fork |
run_q(); |
join_none |
|
$display("^^^ %16.t | %m | initialization", $time); |
|
endfunction: init |
|
endclass: tb_blocking_transaction_q_class |
|
|
endpackage: tb_bfm_pkg |
|
/src/tb/tb_clk.sv
0,0 → 1,55
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 tb_clk_pkg::*; |
|
module |
tb_clk |
#( |
parameter PERIOD = 0 |
) |
( |
output clock |
); |
|
tb_clk_class tb_clk_c; |
tb_clk_if tb_clk_driver(); |
assign clock = tb_clk_driver.clk; |
|
initial |
begin |
|
tb_clk_c = new( tb_clk_driver ); |
|
if( PERIOD != 0 ) |
tb_clk_c.init_basic_clock( PERIOD ); |
|
end |
|
endmodule |
|
|
/src/tb/tb_clk_class.sv
0,0 → 1,110
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`timescale 1ps/1ps |
|
|
// -------------------------------------------------------------------- |
// |
interface tb_clk_if; |
logic clk = 0; |
logic enable = 0; |
time period; |
event clk_rise; |
event clk_fall; |
|
modport tb_m |
( |
output clk |
); |
endinterface: tb_clk_if |
|
|
// -------------------------------------------------------------------- |
// |
class |
tb_clk_class; |
|
virtual tb_clk_if tb; |
|
// -------------------------------------------------------------------- |
// |
function |
new |
( |
virtual tb_clk_if tb |
); |
|
this.tb = tb; |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
task |
init_basic_clock |
( |
time period |
); |
|
tb.period = period; |
tb.enable = 1; |
|
$display( "^^^ %16.t | %m | Starting clock with period %t.", $time, period ); |
|
fork |
forever |
if( tb.enable ) |
begin |
#(period/2) tb.clk = 1; |
-> tb.clk_rise; |
#(period/2) tb.clk = 0; |
-> tb.clk_fall; |
end |
join_none |
|
endtask: init_basic_clock |
|
|
// -------------------------------------------------------------------- |
// |
task |
enable_clock |
( |
logic enable |
); |
|
tb.enable = enable; |
|
$display( "^^^ %16.t | %m | Clock Enable = %h.", $time, enable ); |
|
endtask: enable_clock |
|
endclass: tb_clk_class |
|
|
|
/src/tb/tb_clk_pkg.sv
0,0 → 1,118
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`timescale 1ps/1ps |
|
|
// -------------------------------------------------------------------- |
// |
interface tb_clk_if; |
logic clk = 0; |
logic enable = 0; |
time period; |
event clk_rise; |
event clk_fall; |
|
modport tb_m |
( |
output clk |
); |
endinterface: tb_clk_if |
|
|
// -------------------------------------------------------------------- |
// |
package tb_clk_pkg; |
|
// -------------------------------------------------------------------- |
// |
class |
tb_clk_class; |
|
virtual tb_clk_if tb; |
|
// -------------------------------------------------------------------- |
// |
function |
new |
( |
virtual tb_clk_if tb |
); |
|
this.tb = tb; |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
task |
init_basic_clock |
( |
time period |
); |
|
tb.period = period; |
tb.enable = 1; |
|
$display( "^^^ %16.t | %m | Starting clock with period %t.", $time, period ); |
|
fork |
forever |
if( tb.enable ) |
begin |
#(period/2) tb.clk = 1; |
-> tb.clk_rise; |
#(period/2) tb.clk = 0; |
-> tb.clk_fall; |
end |
join_none |
|
endtask: init_basic_clock |
|
|
// -------------------------------------------------------------------- |
// |
task |
enable_clock |
( |
logic enable |
); |
|
tb.enable = enable; |
|
$display( "^^^ %16.t | %m | Clock Enable = %h.", $time, enable ); |
|
endtask: enable_clock |
|
// -------------------------------------------------------------------- |
// |
endclass: tb_clk_class |
|
//-------------------------------------------------------------------- |
// |
endpackage: tb_clk_pkg |
|