URL
https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk
Subversion Repositories qaz_libs
[/] [qaz_libs/] [trunk/] [PCIe/] [sim/] [src/] [riffa_bfm_class_pkg.sv] - Rev 39
Compare with Previous | Blame | View Log
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2017 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 riffa_bfm_class_pkg;
// --------------------------------------------------------------------
//
import q_pkg::*;
// --------------------------------------------------------------------
//
class riffa_transaction_class #(N);
rand logic [31:0] len;
rand logic [30:0] off;
rand logic last;
rand logic [(8*N)-1:0] data[];
//--------------------------------------------------------------------
//
function int get_data_size(int len);
int words = ((len * 4) % N == 0) ? ((len * 4) / N) : ((len * 4) / N) + 1;
// $display("^^^ %16.t | N = %d", $time, N);
// $display("^^^ %16.t | len = %d", $time, len);
// $display("^^^ %16.t | mod = %d", $time, (len * 4) % N);
// $display("^^^ %16.t | words = %d", $time, words);
return(words);
endfunction: get_data_size
//--------------------------------------------------------------------
//
function void constant(int len, int off, bit last, logic [(8*N)-1:0] value);
this.data = new[get_data_size(len)];
this.len = len;
this.off = off;
this.last = last;
foreach(this.data[i])
this.data[i] = value;
endfunction: constant
//--------------------------------------------------------------------
//
function void counting(int len, int off, bit last);
this.data = new[get_data_size(len)];
this.len = len;
this.off = off;
this.last = last;
foreach(this.data[i])
this.data[i] = i;
endfunction: counting
//--------------------------------------------------------------------
//
function void hex(string str, int off, bit last);
string rev_str;
string char;
int w, c;
this.len = (str.len() % (2 * 4)) == 0
? (str.len() / (2 * 4))
: (str.len() / (2 * 4)) + 1;
this.data = new[get_data_size(this.len)];
this.off = off;
this.last = last;
rev_str = {<<8{str}}; // reverse string
for(w = 0; w < rev_str.len(); w += (N * 2))
for(c = 0; c < (N * 2); c++)
begin
char = string'(rev_str.getc(w + c));
if(char == "")
this.data[w / (N * 2)][(c * 4) +: 4] = 0;
else
this.data[w / (N * 2)][(c * 4) +: 4] = char.atohex();
end
endfunction: hex
//--------------------------------------------------------------------
//
function void random(int len, int off, bit last);
this.data = new[get_data_size(len)];
assert(this.randomize() with
{
this.len == len; // why not working?
this.off == off;
this.last == last;
});
this.len = len;
this.off = off;
this.last = last;
endfunction: random
//--------------------------------------------------------------------
//
function void compare(riffa_transaction_class #(N) to, int max_mismatches = 8);
int error_count = 0;
$display("!!! %16.t | %m", $time);
if(this.len != to.len)
$display("!!! %16.t | ERROR! len mismatch", $time);
if(this.off != to.off)
$display("!!! %16.t | ERROR! off mismatch", $time);
if(this.last != to.last)
$display("!!! %16.t | ERROR! last mismatch", $time);
foreach(this.data[i])
begin
if(error_count > max_mismatches)
break;
if(this.data[i] !== to.data[i])
begin
$display("!!! %16.t | ERROR! | 0x%x | this != to | 0x%x != 0x%x", $time, i, this.data[i], to.data[i]);
error_count++;
end
end
endfunction: compare
// // --------------------------------------------------------------------
// //
// function void copy(ref riffa_transaction_class #(N) from);
// this.len = from.len;
// this.off = from.off;
// this.last = from.last;
// endfunction: copy
// // --------------------------------------------------------------------
// //
// function riffa_transaction_class #(N) clone();
// clone = new(0, 0, 0);
// clone.copy(this);
// endfunction: clone
//--------------------------------------------------------------------
function new(int len, int off, bit last);
this.data = new[get_data_size(len)];
this.len = len;
this.off = off;
this.last = last;
endfunction: new
// --------------------------------------------------------------------
//
endclass: riffa_transaction_class
// --------------------------------------------------------------------
// root port tx
class rp_tx_bfm_class #(N)
extends blocking_transmission_q_class #(riffa_transaction_class #(N));
virtual riffa_chnl_if #(.N(N)) chnl_bus;
// --------------------------------------------------------------------
//
task set_default;
chnl_bus.cb_rp_tx.rx <= 0;
chnl_bus.cb_rp_tx.rx_last <= 'bx;
chnl_bus.cb_rp_tx.rx_len <= 'bx;
chnl_bus.cb_rp_tx.rx_off <= 'bx;
chnl_bus.cb_rp_tx.rx_data <= 'bx;
chnl_bus.cb_rp_tx.rx_data_valid <= 0;
endtask: set_default
// --------------------------------------------------------------------
//
event tx_done;
task transmit(ref Q_T tr_h);
@(chnl_bus.cb_rp_tx);
chnl_bus.cb_rp_tx.rx_len <= tr_h.len; // must be => 4
chnl_bus.cb_rp_tx.rx_off <= tr_h.off;
chnl_bus.cb_rp_tx.rx_last <= tr_h.last;
chnl_bus.cb_rp_tx.rx <= 1;
@(chnl_bus.cb_rp_tx iff chnl_bus.cb_rp_tx.rx_ack);
chnl_bus.cb_rp_tx.rx_data_valid <= 1;
foreach(tr_h.data[i])
begin
chnl_bus.cb_rp_tx.rx_data <= tr_h.data[i];
@(chnl_bus.cb_rp_tx iff chnl_bus.cb_rp_tx.rx_data_ren);
end
set_default();
->tx_done;
endtask: transmit
//--------------------------------------------------------------------
//
function new(virtual riffa_chnl_if #(.N(N)) chnl_bus);
this.chnl_bus = chnl_bus;
fork
set_default();
join_none
endfunction: new
// --------------------------------------------------------------------
//
endclass: rp_tx_bfm_class
// --------------------------------------------------------------------
// root port rx
class rp_rx_bfm_class #(N)
extends blocking_transmission_q_class #(riffa_transaction_class #(N));
virtual riffa_chnl_if #(.N(N)) chnl_bus;
mailbox #(riffa_transaction_class #(N)) rx_q;
// --------------------------------------------------------------------
//
task set_default;
chnl_bus.cb_rp_rx.tx_ack <= 0;
chnl_bus.cb_rp_rx.tx_data_ren <= 0;
endtask: set_default
// --------------------------------------------------------------------
//
event rx_done;
task automatic transmit(ref Q_T tr_h);
int last;
int len;
int off;
@(chnl_bus.cb_rp_rx iff chnl_bus.cb_rp_rx.tx);
last = chnl_bus.cb_rp_rx.tx_last;
len = chnl_bus.cb_rp_rx.tx_len; // must be => 4
off = chnl_bus.cb_rp_rx.tx_off;
tr_h = new(len, off, last);
chnl_bus.cb_rp_rx.tx_ack <= 1;
chnl_bus.cb_rp_rx.tx_data_ren <= 1;
fork
@(chnl_bus.cb_rp_rx)
chnl_bus.cb_rp_rx.tx_ack <= 0;
join_none
foreach(tr_h.data[i])
begin
@(chnl_bus.cb_rp_rx iff chnl_bus.cb_rp_rx.tx_data_valid)
tr_h.data[i] <= chnl_bus.cb_rp_rx.tx_data;
// $display("^^^ %16.t | %d | %h", $time, i, chnl_bus.cb_rp_rx.tx_data);
end
rx_q.put(tr_h);
set_default();
->rx_done;
endtask: transmit
//--------------------------------------------------------------------
//
function new(virtual riffa_chnl_if #(.N(N)) chnl_bus);
this.chnl_bus = chnl_bus;
this.rx_q = new();
fork
set_default();
join_none
endfunction: new
// --------------------------------------------------------------------
//
endclass: rp_rx_bfm_class
// --------------------------------------------------------------------
//
endpackage: riffa_bfm_class_pkg