URL
https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk
Subversion Repositories qaz_libs
[/] [qaz_libs/] [trunk/] [axi4_lib/] [sim/] [src/] [legacy/] [axi4_bfm/] [axi4_slave_bfm_if.sv] - Rev 45
Compare with Previous | Blame | View Log
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2015 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
interface
axi4_slave_bfm_if
#(
A = 32, // address bus width
N = 8, // data bus width in bytes
I = 1 // ID width
)
(
axi4_if axi4_m,
input aresetn,
input aclk
);
logic [(A-1):0] araddr;
logic [1:0] arburst;
logic [3:0] arcache;
logic [(I-1):0] arid;
logic [7:0] arlen;
logic arlock;
logic [2:0] arprot;
logic [3:0] arqos;
logic arready;
logic [3:0] arregion;
logic [2:0] arsize;
logic arvalid;
logic [(A-1):0] awaddr;
logic [1:0] awburst;
logic [3:0] awcache;
logic [(I-1):0] awid;
logic [7:0] awlen;
logic awlock;
logic [2:0] awprot;
logic [3:0] awqos;
logic awready;
logic [3:0] awregion;
logic [2:0] awsize;
logic awvalid;
logic [(I-1):0] bid;
logic bready;
logic [1:0] bresp;
logic bvalid;
logic [(8*N)-1:0] rdata;
logic [(I-1):0] rid;
logic rlast;
logic rready;
logic [1:0] rresp;
logic rvalid;
logic [(8*N)-1:0] wdata;
logic [(I-1):0] wid;
logic wlast;
logic wready;
logic [N-1:0] wstrb;
logic wvalid;
// --------------------------------------------------------------------
//
default clocking cb @(posedge aclk);
input arid;
input araddr;
input arburst;
input arcache;
input awid;
input arlen;
input arlock;
input arprot;
input arqos;
output arready;
input arregion;
input arsize;
input arvalid;
input awaddr;
input awburst;
input awcache;
input awlen;
input awlock;
input awprot;
input awqos;
output awready;
input awregion;
input awsize;
input awvalid;
input bready;
output bid;
output bresp;
output bvalid;
output rdata;
output rid;
output rlast;
input rready;
output rresp;
output rvalid;
input wdata;
input wid;
input wlast;
output wready;
input wstrb;
input wvalid;
input aresetn;
input aclk;
endclocking
// --------------------------------------------------------------------
//
assign arid = axi4_m.arid;
assign araddr = axi4_m.araddr;
assign arburst = axi4_m.arburst;
assign arcache = axi4_m.arcache;
assign awid = axi4_m.awid;
assign arlen = axi4_m.arlen;
assign arlock = axi4_m.arlock;
assign arprot = axi4_m.arprot;
assign arqos = axi4_m.arqos;
assign axi4_m.arready = arready;
assign arregion = axi4_m.arregion;
assign arsize = axi4_m.arsize;
assign arvalid = axi4_m.arvalid;
assign awaddr = axi4_m.awaddr;
assign awburst = axi4_m.awburst;
assign awcache = axi4_m.awcache;
assign awlen = axi4_m.awlen;
assign awlock = axi4_m.awlock;
assign awprot = axi4_m.awprot;
assign awqos = axi4_m.awqos;
assign axi4_m.awready = awready;
assign awregion = axi4_m.awregion;
assign awsize = axi4_m.awsize;
assign awvalid = axi4_m.awvalid;
assign bready = axi4_m.bready;
assign axi4_m.bid = bid;
assign axi4_m.bresp = bresp;
assign axi4_m.bvalid = bvalid;
assign axi4_m.rdata = rdata;
assign axi4_m.rid = rid;
assign axi4_m.rlast = rlast;
assign rready = axi4_m.rready;
assign axi4_m.rresp = rresp;
assign axi4_m.rvalid = rvalid;
assign wdata = axi4_m.wdata;
assign wlast = axi4_m.wlast;
assign axi4_m.wready = wready;
assign wstrb = axi4_m.wstrb;
assign wvalid = axi4_m.wvalid;
// --------------------------------------------------------------------
//
function void
ar_default;
cb.arready <= 0;
endfunction: ar_default
// --------------------------------------------------------------------
//
function void
aw_default;
cb.awready <= 0;
endfunction: aw_default
// --------------------------------------------------------------------
//
function void
r_default;
cb.rdata <= 'bx;
cb.rid <= 'bx;
cb.rlast <= 'bx;
cb.rresp <= 0;
cb.rvalid <= 0;
endfunction: r_default
// --------------------------------------------------------------------
//
function void
w_default;
cb.wready <= 0;
endfunction: w_default
// --------------------------------------------------------------------
//
function void
b_default;
cb.bid <= 0;
cb.bresp <= 0;
cb.bvalid <= 0;
endfunction: b_default
// --------------------------------------------------------------------
//
function void
init;
ar_default();
r_default();
aw_default();
w_default();
b_default();
endfunction: init
// --------------------------------------------------------------------
//
task
zero_cycle_delay;
##0;
endtask: zero_cycle_delay
// --------------------------------------------------------------------
//
import tb_bfm_pkg::*;
import axi4_transaction_pkg::*;
// --------------------------------------------------------------------
//
class r_slave_transaction_class #(A = 32, N = 8, I = 1)
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
->this.start;
foreach(tr_h.payload_h.w[i])
begin
##(tr_h.delay_h.next());
cb.rdata <= tr_h.payload_h.w[i];
cb.rresp <= tr_h.resp;
cb.rid <= tr_h.id;
if(i < tr_h.payload_h.w.size - 1)
cb.rlast <= 0;
else
cb.rlast <= 1;
cb.rvalid <= 1;
##1;
wait(cb.rready);
##0;
$display("^^^ %16.t | %m | slave R transaction | %d | 0x%016x |", $time, i, tr_h.payload_h.w[i]);
r_default();
end
->this.done;
endtask: transaction
// --------------------------------------------------------------------
//
endclass: r_slave_transaction_class
// --------------------------------------------------------------------
//
r_slave_transaction_class #(.A(A), .N(N), .I(I)) r_h;
class ar_slave_transaction_class #(A = 32, N = 8, I = 1)
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
->this.start;
##(tr_h.delay_h.next());
cb.arready <= 1;
##1;
wait(cb.arvalid);
##0;
r_h.put(tr_h);
ar_default();
$display("^^^ %16.t | %m | slave AR transaction @ 0x%08x | 0x%016x |", $time, tr_h.addr, tr_h.payload_h.w[0]);
->this.done;
endtask: transaction
// --------------------------------------------------------------------
//
endclass: ar_slave_transaction_class
// --------------------------------------------------------------------
//
class aw_slave_transaction_class #(A = 32, N = 8, I = 1)
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));
semaphore aw_semaphore;
//--------------------------------------------------------------------
function new;
super.new();
this.aw_semaphore = new(0);
endfunction: new
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
->this.start;
##(tr_h.delay_h.next());
cb.awready <= 1;
##1;
wait(cb.awvalid);
##0;
this.aw_semaphore.put();
aw_default();
$display("^^^ %16.t | %m | slave AW transaction @ 0x%08x | 0x%016x |", $time, tr_h.addr, tr_h.payload_h.w[0]);
->this.done;
endtask: transaction
// --------------------------------------------------------------------
//
endclass: aw_slave_transaction_class
// --------------------------------------------------------------------
//
aw_slave_transaction_class #(.A(A), .N(N), .I(I)) aw_h;
class b_slave_transaction_class #(A = 32, N = 8, I = 1)
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
->this.start;
// Error: AXI4_ERRS_BRESP_AW: A slave must not give a write response before the write address.
// Spec: section A3.3.1 and figure A3-7.
aw_h.aw_semaphore.get(); // better way to do this???
##(tr_h.delay_h.next());
cb.bresp <= tr_h.resp;
cb.bid <= tr_h.id;
cb.bvalid <= 1;
##1;
wait(cb.bready);
##0;
$display("^^^ %16.t | %m | slave B transaction |", $time);
b_default();
->this.done;
endtask: transaction
// --------------------------------------------------------------------
//
endclass: b_slave_transaction_class
// --------------------------------------------------------------------
//
b_slave_transaction_class #(.A(A), .N(N), .I(I)) b_h;
class w_slave_transaction_class #(A = 32, N = 8, I = 1)
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
->this.start;
tr_h.data_h = new(tr_h.len);
foreach(tr_h.payload_h.w[i])
begin
##(tr_h.delay_h.next());
cb.wready <= 1;
##1;
wait(cb.wvalid);
##0;
tr_h.data_h.w[i] <= cb.wdata;
$display("^^^ %16.t | %m | slave W transaction | %d | 0x%016x |", $time, i, cb.wdata);
w_default();
end
b_h.put(tr_h);
->this.done;
endtask: transaction
// --------------------------------------------------------------------
//
endclass: w_slave_transaction_class
// --------------------------------------------------------------------
//
ar_slave_transaction_class #(.A(A), .N(N), .I(I)) ar_h;
w_slave_transaction_class #(.A(A), .N(N), .I(I)) w_h;
initial
begin
init();
ar_h = new;
ar_h.init();
r_h = new;
r_h.init();
aw_h = new;
aw_h.init();
w_h = new;
w_h.init();
b_h = new;
b_h.init();
end
// --------------------------------------------------------------------
//
endinterface