OpenCores
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/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
 

powered by: WebSVN 2.1.0

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