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/axi4_lib/sim/src
- from Rev 29 to Rev 31
- ↔ Reverse comparison
Rev 29 → Rev 31
/BP065-BU-01000-r0p1-00rel0/BP065-BU-01000-r0p1-00rel0.txt
0,0 → 1,6
|
|
|
goto http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0576b/index.html to download. requires |
an free account to login. |
|
/BP065-BU-01000-r0p1-00rel0/axi4_checker.sv
38,8 → 38,7
MAXWAITS = 16, |
RecommendOn = 1'b1, |
RecMaxWaitOn = 1'b1, |
EXMON_WIDTH = 4, |
PROTOCOL = 2'b00 |
EXMON_WIDTH = 4 |
) |
( |
axi4_if axi4_in |
165,11 → 164,7
.RecMaxWaitOn(RecMaxWaitOn), // = 1'b1; |
|
// Set the protocol - used to disable some AXI4 checks for ACE |
//PROTOCOL define the protocol |
// `define AXI4PC_AMBA_AXI4 2'b00 |
// `define AXI4PC_AMBA_ACE 2'b01 |
// `define AXI4PC_AMBA_ACE_LITE 2'b10 |
.PROTOCOL(PROTOCOL), // = `AXI4PC_AMBA_AXI4; |
// .PROTOCOL(PROTOCOL), // = `AXI4PC_AMBA_AXI4; |
|
// Set ADDR_WIDTH to the address-bus width required |
.ADDR_WIDTH(A), // = 32; // address bus width, default = 32-bit |
/axi4_bfm_pkg.sv
0,0 → 1,563
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 axi4_bfm_pkg; |
|
// -------------------------------------------------------------------- |
// |
import tb_bfm_pkg::*; |
import axi4_transaction_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
class ar_master_transaction_class #(A = 32, N = 8, I = 1) |
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I))); |
|
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m; |
|
|
//-------------------------------------------------------------------- |
function new |
( |
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m |
); |
|
super.new(); |
this.axi4_m = axi4_m; |
|
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
function void |
ar_default; |
|
axi4_m.cb_m.araddr <= 'bx; |
axi4_m.cb_m.arburst <= 'bx; |
axi4_m.cb_m.arcache <= 'bx; |
axi4_m.cb_m.arid <= 'bx; |
axi4_m.cb_m.arlen <= 'bx; |
axi4_m.cb_m.arlock <= 'bx; |
axi4_m.cb_m.arprot <= 'bx; |
axi4_m.cb_m.arqos <= 'bx; |
axi4_m.cb_m.arregion <= 'bx; |
axi4_m.cb_m.arsize <= 'bx; |
axi4_m.cb_m.arvalid <= 0; |
|
endfunction: ar_default |
|
|
// -------------------------------------------------------------------- |
// |
task automatic |
transaction |
( |
ref T tr_h |
); |
|
->this.start; |
|
repeat(tr_h.delay_h.next()) @(axi4_m.cb_m); |
|
axi4_m.cb_m.araddr <= tr_h.addr; |
axi4_m.cb_m.arid <= tr_h.id; |
axi4_m.cb_m.arlen <= tr_h.len; |
axi4_m.cb_m.arsize <= tr_h.size; |
|
axi4_m.cb_m.arburst <= tr_h.burst; |
axi4_m.cb_m.arcache <= tr_h.cache; |
axi4_m.cb_m.arlock <= tr_h.lock; |
axi4_m.cb_m.arprot <= tr_h.prot; |
axi4_m.cb_m.arqos <= tr_h.qos; |
axi4_m.cb_m.arregion <= tr_h.region; |
axi4_m.cb_m.arvalid <= 1; |
|
$display("^^^ %16.t | %m | master AR transaction @ 0x%08x |", $time, tr_h.addr); |
|
repeat(1) @(axi4_m.cb_m); |
wait(axi4_m.cb_m.arready); |
|
axi4_m.zero_cycle_delay(); |
ar_default(); |
|
->this.done; |
|
endtask: transaction |
|
|
// -------------------------------------------------------------------- |
// |
endclass: ar_master_transaction_class |
|
|
// -------------------------------------------------------------------- |
// |
class r_master_transaction_class #(A = 32, N = 8, I = 1) |
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I))); |
|
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m; |
|
|
//-------------------------------------------------------------------- |
function new |
( |
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m |
); |
|
super.new(); |
this.axi4_m = axi4_m; |
|
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
function void |
r_default; |
|
axi4_m.cb_m.rready <= 0; |
|
endfunction: r_default |
|
|
// -------------------------------------------------------------------- |
// |
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 |
repeat(tr_h.delay_h.next()) @(axi4_m.cb_m); |
axi4_m.cb_m.rready <= 1; |
repeat(1) @(axi4_m.cb_m); |
|
wait(axi4_m.cb_m.rvalid); |
axi4_m.zero_cycle_delay(); |
|
tr_h.data_h.w[i] = axi4_m.cb_m.rdata; |
|
$display("^^^ %16.t | %m | master R transaction | %d | 0x%016x |", $time, i, tr_h.data_h.w[i]); |
r_default(); |
end |
|
->this.done; |
|
endtask: transaction |
|
|
// -------------------------------------------------------------------- |
// |
endclass: r_master_transaction_class |
|
|
// -------------------------------------------------------------------- |
// |
class aw_master_transaction_class #(A = 32, N = 8, I = 1) |
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I))); |
|
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m; |
|
|
//-------------------------------------------------------------------- |
function new |
( |
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m |
); |
|
super.new(); |
this.axi4_m = axi4_m; |
|
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
function void |
aw_default; |
|
axi4_m.cb_m.awaddr <= 'bx; |
axi4_m.cb_m.awburst <= 'bx; |
axi4_m.cb_m.awcache <= 'bx; |
axi4_m.cb_m.awid <= 'bx; |
axi4_m.cb_m.awlen <= 'bx; |
axi4_m.cb_m.awlock <= 'bx; |
axi4_m.cb_m.awprot <= 'bx; |
axi4_m.cb_m.awqos <= 'bx; |
axi4_m.cb_m.awregion <= 'bx; |
axi4_m.cb_m.awsize <= 'bx; |
axi4_m.cb_m.awvalid <= 0; |
|
endfunction: aw_default |
|
// -------------------------------------------------------------------- |
// |
task automatic |
transaction |
( |
ref T tr_h |
); |
|
->this.start; |
|
repeat(tr_h.delay_h.next()) @(axi4_m.cb_m); |
|
axi4_m.cb_m.awaddr <= tr_h.addr; |
axi4_m.cb_m.awid <= tr_h.id; |
axi4_m.cb_m.awlen <= tr_h.len; |
axi4_m.cb_m.awsize <= tr_h.size; |
|
axi4_m.cb_m.awburst <= tr_h.burst; |
axi4_m.cb_m.awcache <= tr_h.cache; |
axi4_m.cb_m.awlock <= tr_h.lock; |
axi4_m.cb_m.awprot <= tr_h.prot; |
axi4_m.cb_m.awqos <= tr_h.qos; |
axi4_m.cb_m.awregion <= tr_h.region; |
axi4_m.cb_m.awvalid <= 1; |
|
$display("^^^ %16.t | %m | master AW transaction @ 0x%08x |", $time, tr_h.addr); |
|
repeat(1) @(axi4_m.cb_m); |
wait(axi4_m.cb_m.awready); |
|
axi4_m.zero_cycle_delay(); |
aw_default(); |
|
->this.done; |
|
endtask: transaction |
|
|
// -------------------------------------------------------------------- |
// |
endclass: aw_master_transaction_class |
|
|
// -------------------------------------------------------------------- |
// |
class w_master_transaction_class #(A = 32, N = 8, I = 1) |
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I))); |
|
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m; |
|
|
//-------------------------------------------------------------------- |
function new |
( |
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m |
); |
|
super.new(); |
this.axi4_m = axi4_m; |
|
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
function void |
w_default; |
|
axi4_m.cb_m.wdata <= 'bx; |
axi4_m.cb_m.wlast <= 'bx; |
axi4_m.cb_m.wstrb <= {N{1'b1}}; |
axi4_m.cb_m.wvalid <= 0; |
|
endfunction: w_default |
|
|
// -------------------------------------------------------------------- |
// |
task automatic |
transaction |
( |
ref T tr_h |
); |
|
->this.start; |
|
foreach(tr_h.payload_h.w[i]) |
begin |
repeat(tr_h.delay_h.next()) @(axi4_m.cb_m); |
|
axi4_m.cb_m.wdata <= tr_h.payload_h.w[i]; |
// axi4_m.cb_m.wstrb <= tr_h.strb; // need to fix |
|
if(i < tr_h.payload_h.w.size - 1) |
axi4_m.cb_m.wlast <= 0; |
else |
axi4_m.cb_m.wlast <= 1; |
|
axi4_m.cb_m.wvalid <= 1; |
|
repeat(1) @(axi4_m.cb_m); |
wait(axi4_m.cb_m.wready); |
|
axi4_m.zero_cycle_delay(); |
$display("^^^ %16.t | %m | master W transaction | %d | 0x%016x |", $time, i, tr_h.payload_h.w[i]); |
w_default(); |
end |
|
->this.done; |
|
endtask: transaction |
|
|
// -------------------------------------------------------------------- |
// |
endclass: w_master_transaction_class |
|
|
// -------------------------------------------------------------------- |
// |
class b_master_transaction_class #(A = 32, N = 8, I = 1) |
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I))); |
|
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m; |
|
|
//-------------------------------------------------------------------- |
function new |
( |
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m |
); |
|
super.new(); |
this.axi4_m = axi4_m; |
|
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
function void |
b_default; |
|
axi4_m.cb_m.bready <= 0; |
|
endfunction: b_default |
|
|
// -------------------------------------------------------------------- |
// |
task automatic |
transaction |
( |
ref T tr_h |
); |
|
->this.start; |
|
repeat(tr_h.delay_h.next()) @(axi4_m.cb_m); |
axi4_m.cb_m.bready <= 1; |
repeat(1) @(axi4_m.cb_m); |
|
wait(axi4_m.cb_m.bvalid); |
axi4_m.zero_cycle_delay(); |
|
$display("^^^ %16.t | %m | master B transaction | 0x%x |", $time, axi4_m.cb_m.bresp); |
b_default(); |
|
->this.done; |
|
endtask: transaction |
|
|
// -------------------------------------------------------------------- |
// |
endclass: b_master_transaction_class |
|
|
// -------------------------------------------------------------------- |
// |
class axi4_master_bfm_class #(A = 32, N = 8, I = 1); |
|
ar_master_transaction_class #(.A(A), .N(N), .I(I)) ar_h; |
r_master_transaction_class #(.A(A), .N(N), .I(I)) r_h; |
aw_master_transaction_class #(.A(A), .N(N), .I(I)) aw_h; |
w_master_transaction_class #(.A(A), .N(N), .I(I)) w_h; |
b_master_transaction_class #(.A(A), .N(N), .I(I)) b_h; |
|
axi4_transaction_class tr_h; |
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m; |
|
|
//-------------------------------------------------------------------- |
function new |
( |
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m |
); |
|
this.axi4_m = axi4_m; |
|
ar_h = new(axi4_m); |
r_h = new(axi4_m); |
aw_h = new(axi4_m); |
w_h = new(axi4_m); |
b_h = new(axi4_m); |
|
ar_h.init(); |
ar_h.ar_default(); |
|
r_h.init(); |
r_h.r_default(); |
|
aw_h.init(); |
aw_h.aw_default(); |
|
w_h.init(); |
w_h.w_default(); |
|
b_h.init(); |
b_h.b_default(); |
|
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
function void |
init; |
|
endfunction: init |
|
|
// -------------------------------------------------------------------- |
// |
task |
basic_read |
( |
input logic [(A-1):0] araddr, |
input logic [7:0] arlen, |
output logic [(8*N)-1:0] data[], |
output logic [1:0] rresp |
); |
|
this.tr_h = new; |
this.tr_h.basic_read(araddr, arlen); |
|
ar_h.put(tr_h); |
r_h.put(tr_h); |
|
@(r_h.done); |
data = tr_h.data_h.w; |
rresp = tr_h.resp; |
|
endtask: basic_read |
|
|
// -------------------------------------------------------------------- |
// |
task |
basic_random_read_burst |
( |
output logic [(8*N)-1:0] data[], |
output logic [1:0] rresp |
); |
|
this.tr_h = new; |
this.tr_h.basic_random_burst; |
|
ar_h.put(tr_h); |
r_h.put(tr_h); |
|
@(r_h.done); |
data = tr_h.data_h.w; |
rresp = tr_h.resp; |
|
endtask: basic_random_read_burst |
|
|
// -------------------------------------------------------------------- |
// |
task |
basic_write |
( |
input logic [(A-1):0] awaddr, |
input logic [7:0] awlen, |
input logic [(8*N)-1:0] data[], |
output logic [1:0] bresp |
); |
|
this.tr_h = new; |
this.tr_h.basic_write(awaddr, awlen); |
|
foreach(this.tr_h.payload_h.w[i]) |
this.tr_h.payload_h.w[i] = data[i]; |
|
aw_h.put(tr_h); |
w_h.put(tr_h); |
b_h.put(tr_h); |
|
@(b_h.done); |
bresp = tr_h.resp; |
|
endtask: basic_write |
|
|
// -------------------------------------------------------------------- |
// |
task |
basic_random_write_burst |
( |
output logic [1:0] bresp |
); |
|
this.tr_h = new; |
this.tr_h.basic_random_burst; |
|
aw_h.put(tr_h); |
w_h.put(tr_h); |
b_h.put(tr_h); |
|
@(b_h.done); |
bresp = tr_h.resp; |
|
endtask: basic_random_write_burst |
|
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_master_bfm_class |
|
|
// -------------------------------------------------------------------- |
// |
endpackage: axi4_bfm_pkg |
|
|
/axi4_models/axi4_arbiter_pkg.sv
0,0 → 1,474
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 axi4_arbiter_pkg; |
|
// -------------------------------------------------------------------- |
// |
import axi4_models_pkg::*; |
import bfm_pkg::*; |
import logger_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
virtual class base_request_class #(A, N, I); |
|
string kind; |
int id = -1; |
|
//-------------------------------------------------------------------- |
// |
pure virtual function void write_ax_if(axi4_channel_if_class #(A, N, I) channel); |
pure virtual function void copy_ax_if(axi4_channel_if_class #(A, N, I) channel); |
|
|
// -------------------------------------------------------------------- |
// |
endclass: base_request_class |
|
|
// -------------------------------------------------------------------- |
// |
class write_request_class #(A, N, I) |
extends base_request_class #(A, N, I); |
|
logic [(A-1):0] awaddr; |
logic [1:0] awburst; |
logic [(I-1):0] awid; |
logic [7:0] awlen; |
logic [2:0] awsize; |
logic [3:0] awcache; |
logic awlock; |
logic [2:0] awprot; |
logic [3:0] awqos; |
logic [3:0] awregion; |
|
|
// -------------------------------------------------------------------- |
// |
function void write_ax_if(axi4_channel_if_class #(A, N, I) channel); |
axi4_aw_if_class #(A, N, I) aw_if_h; |
$cast(aw_if_h, channel); |
aw_if_h.awaddr = awaddr; |
aw_if_h.awburst = awburst; |
aw_if_h.awid = awid; |
aw_if_h.awlen = awlen; |
aw_if_h.awsize = awsize; |
aw_if_h.awcache = awcache; |
aw_if_h.awlock = awlock; |
aw_if_h.awprot = awprot; |
aw_if_h.awqos = awqos; |
aw_if_h.awregion = awregion; |
endfunction: write_ax_if |
|
|
// -------------------------------------------------------------------- |
// |
function void copy_ax_if(axi4_channel_if_class #(A, N, I) channel); |
axi4_aw_if_class #(A, N, I) aw_if_h; |
$cast(aw_if_h, channel); |
awaddr = aw_if_h.awaddr; |
awburst = aw_if_h.awburst; |
awid = aw_if_h.awid; |
awlen = aw_if_h.awlen; |
awsize = aw_if_h.awsize; |
awcache = aw_if_h.awcache; |
awlock = aw_if_h.awlock; |
awprot = aw_if_h.awprot; |
awqos = aw_if_h.awqos; |
awregion = aw_if_h.awregion; |
endfunction: copy_ax_if |
|
|
//-------------------------------------------------------------------- |
function new(int id); |
super.new; |
this.kind = "WRITE"; |
this.id = id; |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: write_request_class |
|
|
// -------------------------------------------------------------------- |
// |
class read_request_class #(A, N, I) |
extends base_request_class #(A, N, I); |
|
logic [(A-1):0] araddr; |
logic [1:0] arburst; |
logic [(I-1):0] arid; |
logic [7:0] arlen; |
logic [2:0] arsize; |
logic [3:0] arcache; |
logic arlock; |
logic [2:0] arprot; |
logic [3:0] arqos; |
logic [3:0] arregion; |
|
// -------------------------------------------------------------------- |
// |
function void write_ax_if(axi4_channel_if_class #(A, N, I) channel); |
axi4_ar_if_class #(A, N, I) ar_if_h; |
$cast(ar_if_h, channel); |
ar_if_h.araddr = araddr; |
ar_if_h.arburst = arburst; |
ar_if_h.arid = arid; |
ar_if_h.arlen = arlen; |
ar_if_h.arsize = arsize; |
ar_if_h.arcache = arcache; |
ar_if_h.arlock = arlock; |
ar_if_h.arprot = arprot; |
ar_if_h.arqos = arqos; |
ar_if_h.arregion = arregion; |
endfunction: write_ax_if |
|
|
// -------------------------------------------------------------------- |
// |
function void copy_ax_if(axi4_channel_if_class #(A, N, I) channel); |
axi4_ar_if_class #(A, N, I) ar_if_h; |
$cast(ar_if_h, channel); |
araddr = ar_if_h.araddr; |
arburst = ar_if_h.arburst; |
arid = ar_if_h.arid; |
arlen = ar_if_h.arlen; |
arsize = ar_if_h.arsize; |
arcache = ar_if_h.arcache; |
arlock = ar_if_h.arlock; |
arprot = ar_if_h.arprot; |
arqos = ar_if_h.arqos; |
arregion = ar_if_h.arregion; |
endfunction: copy_ax_if |
|
|
//-------------------------------------------------------------------- |
function new(int id); |
super.new; |
this.kind = "READ"; |
this.id = id; |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: read_request_class |
|
|
// -------------------------------------------------------------------- |
// |
class requester_class #(A, N, I) |
extends axi4_slave_model_class #(A, N, I); |
|
mailbox #(base_request_class #(A, N, I)) q; |
semaphore read_done; |
semaphore write_done; |
int id = -1; |
logger_class log; |
|
|
// -------------------------------------------------------------------- |
// |
task automatic run_read_interface; |
read_request_class #(A, N, I) r_req_h; |
read_done = new; |
forever |
@(axi4_s.cb_s) |
begin |
ar_q_h.q.get(ar_if_h); |
log.debug($sformatf("%m | start")); |
log.debug($sformatf("%m | araddr = 0x%h", ar_if_h.araddr)); |
log.debug($sformatf("%m | arlen = 0x%h", ar_if_h.arlen)); |
r_req_h = new(id); |
r_req_h.copy_ax_if(ar_if_h); |
q.put(r_req_h); |
read_done.get(); |
log.debug($sformatf("%m | done")); |
end |
endtask: run_read_interface |
|
|
// -------------------------------------------------------------------- |
// |
task run_write_interface; |
write_request_class #(A, N, I) w_req_h; |
write_done = new; |
forever |
@(axi4_s.cb_s) |
begin |
aw_q_h.q.get(aw_if_h); |
log.debug($sformatf("%m | start")); |
log.debug($sformatf("%m | awaddr = 0x%h", aw_if_h.awaddr)); |
log.debug($sformatf("%m | awlen = 0x%h", aw_if_h.awlen)); |
w_req_h = new(id); |
w_req_h.copy_ax_if(aw_if_h); |
q.put(w_req_h); |
write_done.get(); |
log.debug($sformatf("%m | done")); |
end |
endtask: run_write_interface |
|
|
// -------------------------------------------------------------------- |
// |
task run_model; |
wait(axi4_s.cb_s.aresetn); |
axi4_s.zero_cycle_delay(); |
|
aw_q_h.run_q(); |
w_q_h.run_q(); |
b_q_h.run_q(); |
ar_q_h.run_q(); |
r_q_h.run_q(); |
|
fork |
run_read_interface(); |
join_none |
|
fork |
run_write_interface(); |
join_none |
|
endtask: run_model |
|
|
//-------------------------------------------------------------------- |
function new(int id, virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_s); |
super.new(axi4_s); |
this.aw_q_h = new(axi4_s, 2); |
this.w_q_h = new(axi4_s, 16); |
this.b_q_h = new(axi4_s, 2); |
this.ar_q_h = new(axi4_s, 2); |
this.r_q_h = new(axi4_s, 16); |
this.id = id; |
this.q = new(1); |
this.log = new(); |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: requester_class |
|
|
// -------------------------------------------------------------------- |
// |
class axi4_granter_class #(A, N, I) |
extends axi4_master_model_class #(A, N, I); |
|
logger_class log; |
|
|
// -------------------------------------------------------------------- |
// |
task run_model; |
wait(axi4_m.cb_s.aresetn); |
axi4_m.zero_cycle_delay(); |
|
aw_q_h.run_q(); |
w_q_h.run_q(); |
b_q_h.run_q(); |
ar_q_h.run_q(); |
r_q_h.run_q(); |
endtask: run_model |
|
|
//-------------------------------------------------------------------- |
function new(virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m); |
super.new(axi4_m); |
this.aw_q_h = new(axi4_m, 2); |
this.w_q_h = new(axi4_m, 16); |
this.b_q_h = new(axi4_m, 2); |
this.ar_q_h = new(axi4_m, 2); |
this.r_q_h = new(axi4_m, 16); |
this.log = new(); |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_granter_class |
|
|
// -------------------------------------------------------------------- |
// |
class axi4_arbiter_class #(A, N, I); |
|
axi4_granter_class #(A, N, I) g_h; |
requester_class #(A, N, I) r_h[]; |
mailbox #(int) grant; |
int count = -1; |
int current = 0, previous; |
logger_class log; |
|
|
// -------------------------------------------------------------------- |
// |
task automatic do_read(requester_class #(A, N, I) r_h); |
int id; |
read_request_class #(A, N, I) r_req_h; |
base_request_class #(A, N, I) request; |
log.debug($sformatf("%m | read grant for %d", r_h.id)); |
r_h.q.get(request); |
$cast(r_req_h, request); |
|
g_h.ar_if_h = new(g_h.axi4_m); |
r_req_h.write_ax_if(g_h.ar_if_h); |
g_h.ar_q_h.q.put(g_h.ar_if_h); |
|
for(int i = 0; i < r_h.ar_if_h.arlen + 1; i++) |
begin |
g_h.r_if_h = new(g_h.axi4_m); |
r_h.r_if_h = new(r_h.axi4_s); |
g_h.r_q_h.q.get(g_h.r_if_h); |
r_h.r_if_h.copy(g_h.r_if_h); |
r_h.r_q_h.q.put(r_h.r_if_h); |
@(r_h.axi4_s.cb_s); |
end |
|
r_h.read_done.put(); |
grant.get(id); |
log.debug($sformatf("%m | read grant for %d done", id)); |
endtask: do_read |
|
|
// -------------------------------------------------------------------- |
// |
task automatic do_write(requester_class #(A, N, I) r_h); |
int id; |
write_request_class #(A, N, I) w_req_h; |
base_request_class #(A, N, I) request; |
log.debug($sformatf("%m | write grant for %d", r_h.id)); |
r_h.q.get(request); |
$cast(w_req_h, request); |
|
g_h.aw_if_h = new(g_h.axi4_m); |
w_req_h.write_ax_if(g_h.aw_if_h); |
g_h.aw_q_h.q.put(g_h.aw_if_h); |
|
for(int i = 0; i < r_h.aw_if_h.awlen + 1; i++) |
begin |
r_h.w_if_h = new(r_h.axi4_s); |
g_h.w_if_h = new(g_h.axi4_m); |
r_h.w_q_h.q.get(r_h.w_if_h); |
g_h.w_if_h.copy(r_h.w_if_h); |
g_h.w_q_h.q.put(g_h.w_if_h); |
@(r_h.axi4_s.cb_s); |
end |
|
g_h.b_q_h.q.get(g_h.b_if_h); |
r_h.b_if_h = new(r_h.axi4_s); |
r_h.b_if_h.copy(g_h.b_if_h); |
r_h.b_q_h.q.put(r_h.b_if_h); |
r_h.write_done.put(); |
grant.get(id); |
log.debug($sformatf("%m | write grant for %d done", id)); |
endtask: do_write |
|
|
// -------------------------------------------------------------------- |
// |
task automatic give_grant(requester_class #(A, N, I) r_h); |
base_request_class #(A, N, I) request; |
grant.put(r_h.id); |
r_h.q.peek(request); |
log.debug($sformatf("%m | %d got grant for %s", r_h.id, request.kind)); |
|
if(request.kind.toupper == "WRITE") |
do_write(r_h); |
else if(request.kind.toupper == "READ") |
do_read(r_h); |
else |
$stop; |
|
current = (current + count + 1) % count; |
log.debug($sformatf("%m | new current = %d", current)); |
endtask: give_grant |
|
|
// -------------------------------------------------------------------- |
// |
task automatic do_arbitration; |
wait(g_h.axi4_m.cb_m.aresetn); |
g_h.axi4_m.zero_cycle_delay(); |
forever |
@(g_h.axi4_m.cb_m) |
begin |
for(int i = current; i < current + count; i++) |
if(r_h[i % count].q.num > 0) |
begin |
give_grant(r_h[i % count]); |
break; |
end |
end |
endtask: do_arbitration |
|
|
//-------------------------------------------------------------------- |
function void debug_enable; |
log.debug_enable(); |
g_h.log.debug_enable(); |
foreach(r_h[i]) |
r_h[i].log.debug_enable(); |
endfunction: debug_enable |
|
|
//-------------------------------------------------------------------- |
function new |
( |
virtual axi4_if #(A, N, I) axi4_s[], |
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m |
); |
this.grant = new(1); |
this.g_h = new(axi4_m); |
this.count = axi4_s.size; |
this.r_h = new[axi4_s.size]; |
this.log = new; |
|
foreach(axi4_s[i]) |
r_h[i] = new(i, axi4_s[i]); |
|
fork |
do_arbitration(); |
join_none |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_arbiter_class |
|
|
// -------------------------------------------------------------------- |
// |
endpackage: axi4_arbiter_pkg |
|
/axi4_models/axi4_memory_pkg.sv
0,0 → 1,369
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 axi4_memory_pkg; |
|
// -------------------------------------------------------------------- |
// |
import axi4_models_pkg::*; |
import bfm_pkg::*; |
import logger_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
class memory_tr_class #(A, N, I, type WORD_T = byte) |
extends transaction_class #(memory_tr_class #(A, N, I)); |
|
rand int addr; |
rand int size; |
rand byte data[]; |
|
constraint default_addr |
{ |
addr[$clog2(N*8)-1:0] == 0; |
} |
|
constraint default_size |
{ |
size dist {N := 40, [N*2:N*15] := 40, [N*16:N*255] := 20}; |
} |
|
|
//-------------------------------------------------------------------- |
// |
function void init(int addr, int size); |
this.data = new[size]; |
this.addr = addr; |
this.size = size; |
endfunction: init |
|
|
//-------------------------------------------------------------------- |
// |
function void random(int addr, int size); |
this.data = new[size]; |
assert(this.randomize() with |
{ |
this.addr == addr; // why not working? |
this.size == size; |
}); |
this.addr = addr; |
this.size = size; |
endfunction: random |
|
|
// -------------------------------------------------------------------- |
// |
task constant(int addr, int size, byte value[]); |
init(addr, size); |
this.data = new[size]; |
for(int i = 0; i < size; i += value.size) |
foreach(value[k]) |
data[i + k] = value[k]; |
endtask: constant |
|
|
// -------------------------------------------------------------------- |
// |
task automatic counting(int addr, int count); |
byte word[]; |
int word_size = $bits(WORD_T) / 8; // word size in bytes |
init(addr, count * word_size); |
for(WORD_T i = 0; i < count; i++) |
begin |
word = {<< byte{i}}; |
foreach(word[k]) |
data[addr + (i * word_size) + k] = word[k]; |
end |
endtask: counting |
|
|
// -------------------------------------------------------------------- |
// |
function void copy(TR_T from); |
init(from.addr, from.size); |
this.data = new[from.size]; |
foreach(from.data[i]) |
this.data[i] = from.data[i]; |
endfunction: copy |
|
|
//-------------------------------------------------------------------- |
function new; |
a_word_t_mod_n: assert($bits(WORD_T) % 8 == 0) else $fatal; |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: memory_tr_class |
|
|
// -------------------------------------------------------------------- |
// |
class axi4_memory_class #(A, N, I, type WORD_T = byte) |
extends axi4_slave_model_class #(.A(A), .N(N), .I(I)); |
|
logger_class log; |
byte memory [*]; |
|
|
// -------------------------------------------------------------------- |
// |
function void clear_all; |
memory.delete; |
endfunction: clear_all |
|
|
// -------------------------------------------------------------------- |
// |
function void compare(memory_tr_class #(A, N, I, WORD_T) tr_h); |
foreach(tr_h.data[i]) |
if(memory.exists(tr_h.addr + i)) |
begin |
if(memory[tr_h.addr + i] != tr_h.data[i]) |
log.error($sformatf("%m | 1 memory[0x%8.h] = 0x%2.h | 0x%2.h", tr_h.addr + i, memory[tr_h.addr + i], tr_h.data[i])); |
end |
else |
log.error($sformatf("%m | 2 memory[0x%8.h] = 0x%2.h | 0x%2.h", tr_h.addr + i, 'bx, tr_h.data[i])); |
endfunction: compare |
|
|
// -------------------------------------------------------------------- |
// |
task display_memory(int offset, int count); |
for(int i = 0; i < count; i++) |
if(memory.exists(offset + i)) |
$display("^^^ %16.t | %m | memory[0x%8.x] = 0x%2.x", $time, offset + i, memory[offset + i]); |
else |
$display("^^^ %16.t | %m | memory[0x%8.x] = 0x%2.x", $time, offset + i, 8'hxx); |
endtask: display_memory |
|
|
// -------------------------------------------------------------------- |
// |
task constant_fill(int offset, int count, int value); |
for(int i = 0; i < count; i++) |
memory[offset + i] = value; |
endtask: constant_fill |
|
|
// -------------------------------------------------------------------- |
// |
task counting_fill(int offset, int count); |
for(int i = 0; i < count; i++) |
memory[offset + i] = i; |
endtask: counting_fill |
|
|
// -------------------------------------------------------------------- |
// |
task dump_words(int offset, ref byte data[]); |
foreach(data[i]) |
if(memory.exists(offset + i)) |
data[i] = memory[offset + i]; |
else |
data[i] = 'bx; |
endtask: dump_words |
|
|
// -------------------------------------------------------------------- |
// |
function reg [7:0] dump(int offset); |
if(memory.exists(offset)) |
return(memory[offset]); |
else |
return('bx); |
endfunction: dump |
|
|
// -------------------------------------------------------------------- |
// |
task load_words(int offset, byte data[]); |
foreach(data[i]) |
memory[offset + i] = data[i]; |
endtask: load_words |
|
|
// -------------------------------------------------------------------- |
// |
task load(int offset, reg [7:0] data); |
memory[offset] = data; |
endtask: load |
|
|
// -------------------------------------------------------------------- |
// |
task run_read_interface; |
int result; |
logic [9:0] delay = 0; |
int memory_addr; |
|
forever |
@(axi4_s.cb_s) |
begin |
result = ar_q_h.q.try_peek(ar_if_h); |
if(result != 0) |
begin |
log.debug($sformatf("araddr = 0x%h", ar_if_h.araddr)); |
log.debug($sformatf("arlen = 0x%h", ar_if_h.arlen)); |
delay = $urandom_range(9, 0); |
if(delay > 6) |
repeat($urandom_range(50, 1)) |
@(axi4_s.cb_s); |
|
for(int i = 0; i < ar_if_h.arlen + 1; i++) |
begin |
memory_addr = ar_if_h.araddr + (i * (2 ** ar_if_h.arsize)); |
for(int i = 0; i < ar_if_h.N; i++) |
begin |
if(memory.exists(memory_addr)) |
r_if_h.rdata[i*8 +: 8] = memory[memory_addr]; |
else |
r_if_h.rdata[i*8 +: 8] = 8'hxx; |
|
memory_addr++; |
end |
log.debug($sformatf("rdata = 0x%h", r_if_h.rdata)); |
|
if(i == ar_if_h.arlen) |
begin |
ar_q_h.q.get(ar_if_h); |
r_if_h.rlast = 1; |
end |
else |
r_if_h.rlast = 0; |
|
r_if_h.rid = 0; |
r_if_h.rresp = 0; |
|
r_q_h.q.put(r_if_h); |
r_if_h = new(axi4_s); |
|
@(axi4_s.cb_s); |
end |
r_if_h.rlast = 0; |
end |
end |
endtask: run_read_interface |
|
|
// -------------------------------------------------------------------- |
// |
task run_write_interface; |
|
int result; |
logic [9:0] delay = 0; |
int memory_addr; |
|
forever |
@(axi4_s.cb_s) |
begin |
result = aw_q_h.q.try_peek(aw_if_h); |
if(result != 0) |
begin |
memory_addr = aw_if_h.awaddr; |
log.debug($sformatf("awaddr = 0x%h", aw_if_h.awaddr)); |
|
delay = $urandom_range(9, 0); |
if(delay > 6) |
repeat($urandom_range(8, 1)) |
@(axi4_s.cb_s); |
|
for(int i = 0; i < aw_if_h.awlen + 1; i++) |
begin |
w_q_h.q.get(w_if_h); |
log.debug($sformatf("wdata = 0x%h", w_if_h.wdata)); |
for(int k = 0; k < aw_if_h.N; k++) |
begin |
memory[memory_addr] = w_if_h.wdata[k*8 +: 8]; |
memory_addr++; |
end |
|
if(i == aw_if_h.awlen) |
begin |
b_if_h.bresp = 0; |
b_if_h.bid = aw_if_h.awid; |
b_q_h.q.put(b_if_h); |
b_if_h = new(axi4_s); |
aw_q_h.q.get(aw_if_h); |
end |
|
@(axi4_s.cb_s); |
end |
end |
end |
|
endtask: run_write_interface |
|
|
// -------------------------------------------------------------------- |
// |
task run_model; |
wait(axi4_s.cb_s.aresetn); |
axi4_s.zero_cycle_delay(); |
|
aw_q_h.run_q(); |
w_q_h.run_q(); |
b_q_h.run_q(); |
ar_q_h.run_q(); |
r_q_h.run_q(); |
|
fork |
run_write_interface(); |
join_none |
|
fork |
run_read_interface(); |
join_none |
endtask: run_model |
|
|
//-------------------------------------------------------------------- |
function new(virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_s); |
super.new(axi4_s); |
a_word_t_mod_n: assert($bits(WORD_T) % 8 == 0) else $fatal; |
this.aw_q_h = new(axi4_s, 2); |
this.w_q_h = new(axi4_s, 16); |
this.b_q_h = new(axi4_s, 2); |
this.ar_q_h = new(axi4_s, 2); |
this.r_q_h = new(axi4_s, 16); |
this.log = new(); |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_memory_class |
|
|
// -------------------------------------------------------------------- |
// |
endpackage: axi4_memory_pkg |
|
/axi4_models/axi4_models_pkg.sv
0,0 → 1,822
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 axi4_models_pkg; |
|
// -------------------------------------------------------------------- |
// |
virtual class axi4_channel_if_class #(A, N, I); |
|
virtual axi4_if #(A, N, I) axi4_bus; |
event valid; |
|
|
// -------------------------------------------------------------------- |
// |
pure virtual function void set_master_default; |
pure virtual function void set_slave_default; |
pure virtual function void copy(axi4_channel_if_class #(A, N, I) from); |
pure virtual function void copy_if; |
pure virtual function void drive_if; |
pure virtual function void set_ready(bit value); |
pure virtual function bit is_valid; |
pure virtual function void set_valid(bit value); |
pure virtual function bit is_ready; |
pure virtual function bit is_transfer; |
|
|
//-------------------------------------------------------------------- |
function new(virtual axi4_if #(A, N, I) axi4_bus); |
this.axi4_bus = axi4_bus; |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_channel_if_class |
|
|
// -------------------------------------------------------------------- |
// |
class axi4_channel_sink_q_class #(A, N, I, type T = logic); |
|
virtual axi4_if #(A, N, I) axi4_bus; |
T c_if_h; |
int q_size; |
mailbox #(T) q; |
|
|
// -------------------------------------------------------------------- |
// |
function automatic void run_q; |
int result; |
c_if_h.set_ready(1'b1); |
|
fork |
forever |
@(axi4_bus.cb_s) |
begin |
if(c_if_h.is_transfer) |
begin |
result = q.try_put(c_if_h); |
if(result == 0) |
$error; |
|
c_if_h.copy_if(); |
c_if_h = new(axi4_bus); |
end |
|
if(q.num >= q_size) |
c_if_h.set_ready(1'b0); |
else |
c_if_h.set_ready(1'b1); |
end |
join_none |
endfunction: run_q |
|
|
//-------------------------------------------------------------------- |
function new( virtual axi4_if #(A, N, I) axi4_bus, int q_size); |
this.axi4_bus = axi4_bus; |
this.q_size = q_size; |
this.q = new(q_size); |
this.c_if_h = new(axi4_bus); |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_channel_sink_q_class |
|
|
// -------------------------------------------------------------------- |
// |
class axi4_channel_source_q_class #(A, N, I, type T = logic); |
|
virtual axi4_if #(A, N, I) axi4_bus; |
T c_if_h; |
int q_size; |
mailbox #(T) q; |
|
|
// -------------------------------------------------------------------- |
// |
function automatic void run_q; |
int result; |
c_if_h.set_valid(1'b0); |
|
fork |
forever |
@(axi4_bus.cb_s) |
begin |
if(c_if_h.is_transfer) |
begin |
result = q.try_get(c_if_h); |
if(result == 0) |
$stop; |
end |
|
result = q.try_peek(c_if_h); |
if(result == 0) |
c_if_h.set_valid(1'b0); |
else |
begin |
c_if_h.set_valid(1'b1); |
c_if_h.drive_if(); |
end |
end |
join_none |
endfunction: run_q |
|
|
//-------------------------------------------------------------------- |
function new(virtual axi4_if #(A, N, I) axi4_bus, int q_size); |
this.axi4_bus = axi4_bus; |
this.q_size = q_size; |
this.q = new(q_size); |
this.c_if_h = new(axi4_bus); |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_channel_source_q_class |
|
|
// -------------------------------------------------------------------- |
// |
class axi4_aw_if_class #(A, N, I) |
extends axi4_channel_if_class #(A, N, I); |
|
logic [(A-1):0] awaddr; |
logic [1:0] awburst; |
logic [(I-1):0] awid; |
logic [7:0] awlen; |
logic [2:0] awsize; |
logic [3:0] awcache; |
logic awlock; |
logic [2:0] awprot; |
logic [3:0] awqos; |
logic [3:0] awregion; |
|
|
// -------------------------------------------------------------------- |
// |
function void set_master_default; |
axi4_bus.cb_m.awvalid <= 0; |
endfunction: set_master_default |
|
|
// -------------------------------------------------------------------- |
// |
function void set_slave_default; |
axi4_bus.cb_s.awready <= 0; |
endfunction: set_slave_default |
|
|
// -------------------------------------------------------------------- |
// |
function void copy(axi4_channel_if_class #(A, N, I) from); |
axi4_aw_if_class #(A, N, I) child; |
$cast(child, from); |
awaddr = child.awaddr; |
awburst = child.awburst; |
awid = child.awid; |
awlen = child.awlen; |
awsize = child.awsize; |
awcache = child.awcache; |
awlock = child.awlock; |
awprot = child.awprot; |
awqos = child.awqos; |
awregion = child.awregion; |
endfunction: copy |
|
|
// -------------------------------------------------------------------- |
// |
function void copy_if; |
awaddr = axi4_bus.cb_s.awaddr; |
awburst = axi4_bus.cb_s.awburst; |
awid = axi4_bus.cb_s.awid; |
awlen = axi4_bus.cb_s.awlen; |
awsize = axi4_bus.cb_s.awsize; |
awcache = axi4_bus.cb_s.awcache; |
awlock = axi4_bus.cb_s.awlock; |
awprot = axi4_bus.cb_s.awprot; |
awqos = axi4_bus.cb_s.awqos; |
awregion = axi4_bus.cb_s.awregion; |
endfunction: copy_if |
|
|
// -------------------------------------------------------------------- |
// |
function void drive_if; |
axi4_bus.cb_m.awaddr <= awaddr; |
axi4_bus.cb_m.awburst <= awburst; |
axi4_bus.cb_m.awid <= awid; |
axi4_bus.cb_m.awlen <= awlen; |
axi4_bus.cb_m.awsize <= awsize; |
axi4_bus.cb_m.awcache <= awcache; |
axi4_bus.cb_m.awlock <= awlock; |
axi4_bus.cb_m.awprot <= awprot; |
axi4_bus.cb_m.awqos <= awqos; |
axi4_bus.cb_m.awregion <= awregion; |
endfunction: drive_if |
|
|
// -------------------------------------------------------------------- |
// |
function void set_ready(bit value); |
axi4_bus.cb_s.awready <= value; |
endfunction: set_ready |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_valid; |
return(axi4_bus.cb_s.awvalid); |
endfunction: is_valid |
|
|
// -------------------------------------------------------------------- |
// |
function void set_valid(bit value); |
axi4_bus.cb_m.awvalid <= value; |
endfunction: set_valid |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_ready; |
return(axi4_bus.cb_m.awready); |
endfunction: is_ready |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_transfer; |
return(axi4_bus.cb_m.awready & axi4_bus.cb_s.awvalid); |
endfunction: is_transfer |
|
|
//-------------------------------------------------------------------- |
function new(virtual axi4_if #(A, N, I) axi4_bus); |
super.new(axi4_bus); |
endfunction: new |
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_aw_if_class |
|
|
// -------------------------------------------------------------------- |
// |
class axi4_ar_if_class #(A, N, I) |
extends axi4_channel_if_class #(A, N, I); |
|
logic [(A-1):0] araddr; |
logic [1:0] arburst; |
logic [(I-1):0] arid; |
logic [7:0] arlen; |
logic [2:0] arsize; |
logic [3:0] arcache; |
logic arlock; |
logic [2:0] arprot; |
logic [3:0] arqos; |
logic [3:0] arregion; |
|
|
// -------------------------------------------------------------------- |
// |
virtual function void set_master_default; |
axi4_bus.cb_m.arvalid <= 0; |
endfunction: set_master_default |
|
|
// -------------------------------------------------------------------- |
// |
virtual function void set_slave_default; |
axi4_bus.cb_s.arready <= 0; |
endfunction: set_slave_default |
|
|
// -------------------------------------------------------------------- |
// |
virtual function void copy(axi4_channel_if_class #(A, N, I) from); |
axi4_ar_if_class #(A, N, I) child; |
$cast(child, from); |
araddr = child.araddr; |
arburst = child.arburst; |
arid = child.arid; |
arlen = child.arlen; |
arsize = child.arsize; |
arcache = child.arcache; |
arlock = child.arlock; |
arprot = child.arprot; |
arqos = child.arqos; |
arregion = child.arregion; |
endfunction: copy |
|
|
// -------------------------------------------------------------------- |
// |
virtual function void copy_if; |
araddr = axi4_bus.cb_s.araddr; |
arburst = axi4_bus.cb_s.arburst; |
arid = axi4_bus.cb_s.arid; |
arlen = axi4_bus.cb_s.arlen; |
arsize = axi4_bus.cb_s.arsize; |
arcache = axi4_bus.cb_s.arcache; |
arlock = axi4_bus.cb_s.arlock; |
arprot = axi4_bus.cb_s.arprot; |
arqos = axi4_bus.cb_s.arqos; |
arregion = axi4_bus.cb_s.arregion; |
endfunction: copy_if |
|
|
// -------------------------------------------------------------------- |
// |
virtual function void drive_if; |
axi4_bus.cb_m.araddr <= araddr; |
axi4_bus.cb_m.arburst <= arburst; |
axi4_bus.cb_m.arid <= arid; |
axi4_bus.cb_m.arlen <= arlen; |
axi4_bus.cb_m.arsize <= arsize; |
axi4_bus.cb_m.arcache <= arcache; |
axi4_bus.cb_m.arlock <= arlock; |
axi4_bus.cb_m.arprot <= arprot; |
axi4_bus.cb_m.arqos <= arqos; |
axi4_bus.cb_m.arregion <= arregion; |
endfunction: drive_if |
|
|
// -------------------------------------------------------------------- |
// |
virtual function void set_ready(bit value); |
axi4_bus.cb_s.arready <= value; |
endfunction: set_ready |
|
|
// -------------------------------------------------------------------- |
// |
virtual function bit is_valid; |
return(axi4_bus.cb_s.arvalid); |
endfunction: is_valid |
|
|
// -------------------------------------------------------------------- |
// |
function void set_valid(bit value); |
axi4_bus.cb_m.arvalid <= value; |
endfunction: set_valid |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_ready; |
return(axi4_bus.cb_m.arready); |
endfunction: is_ready |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_transfer; |
return(axi4_bus.cb_m.arready & axi4_bus.cb_s.arvalid); |
endfunction: is_transfer |
|
|
//-------------------------------------------------------------------- |
function new(virtual axi4_if #(A, N, I) axi4_bus); |
super.new(axi4_bus); |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_ar_if_class |
|
|
// -------------------------------------------------------------------- |
// |
class axi4_w_if_class #(A, N, I) |
extends axi4_channel_if_class #(A, N, I); |
|
logic [(8*N)-1:0] wdata; |
logic [(I-1):0] wid; |
logic wlast; |
logic [N-1:0] wstrb; |
|
|
// -------------------------------------------------------------------- |
// |
function void set_master_default; |
axi4_bus.cb_m.wvalid <= 0; |
endfunction: set_master_default |
|
|
// -------------------------------------------------------------------- |
// |
function void set_slave_default; |
axi4_bus.cb_s.wready <= 0; |
endfunction: set_slave_default |
|
|
// -------------------------------------------------------------------- |
// |
function void copy(axi4_channel_if_class #(A, N, I) from); |
axi4_w_if_class #(A, N, I) child; |
$cast(child, from); |
wdata = child.wdata; |
wid = child.wid; |
wlast = child.wlast; |
wstrb = child.wstrb; |
endfunction: copy |
|
|
// -------------------------------------------------------------------- |
// |
function void copy_if; |
wdata = axi4_bus.cb_s.wdata; |
wid = axi4_bus.cb_s.wid; |
wlast = axi4_bus.cb_s.wlast; |
wstrb = axi4_bus.cb_s.wstrb; |
endfunction: copy_if |
|
|
// -------------------------------------------------------------------- |
// |
function void drive_if; |
axi4_bus.cb_m.wdata <= wdata; |
axi4_bus.cb_m.wid <= wid; |
axi4_bus.cb_m.wlast <= wlast; |
axi4_bus.cb_m.wstrb <= wstrb; |
endfunction: drive_if |
|
|
// -------------------------------------------------------------------- |
// |
function void set_ready(bit value); |
axi4_bus.cb_s.wready <= value; |
endfunction: set_ready |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_valid; |
return(axi4_bus.cb_s.wvalid); |
endfunction: is_valid |
|
|
// -------------------------------------------------------------------- |
// |
function void set_valid(bit value); |
axi4_bus.cb_m.wvalid <= value; |
endfunction: set_valid |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_ready; |
return(axi4_bus.cb_m.wready); |
endfunction: is_ready |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_transfer; |
return(axi4_bus.cb_m.wready & axi4_bus.cb_s.wvalid); |
endfunction: is_transfer |
|
|
//-------------------------------------------------------------------- |
function new(virtual axi4_if #(A, N, I) axi4_bus); |
super.new(axi4_bus); |
endfunction: new |
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_w_if_class |
|
|
// -------------------------------------------------------------------- |
// |
class axi4_b_if_class #(A, N, I) |
extends axi4_channel_if_class #(A, N, I); |
|
logic [(I-1):0] bid; |
logic [1:0] bresp; |
|
|
// -------------------------------------------------------------------- |
// |
function void set_master_default; |
axi4_bus.cb_m.bready <= 0; |
endfunction: set_master_default |
|
|
// -------------------------------------------------------------------- |
// |
function void set_slave_default; |
axi4_bus.cb_s.bvalid <= 0; |
endfunction: set_slave_default |
|
|
// -------------------------------------------------------------------- |
// |
function void copy(axi4_channel_if_class #(A, N, I) from); |
axi4_b_if_class #(A, N, I) child; |
$cast(child, from); |
bid = child.bid; |
bresp = child.bresp; |
endfunction: copy |
|
|
// -------------------------------------------------------------------- |
// |
function void copy_if; |
bid = axi4_bus.cb_m.bid; |
bresp = axi4_bus.cb_m.bresp; |
endfunction: copy_if |
|
|
// -------------------------------------------------------------------- |
// |
function void drive_if; |
axi4_bus.cb_s.bid <= bid; |
axi4_bus.cb_s.bresp <= bresp; |
endfunction: drive_if |
|
|
// -------------------------------------------------------------------- |
// |
function void set_ready(bit value); |
axi4_bus.cb_m.bready <= value; |
endfunction: set_ready |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_valid; |
return(axi4_bus.cb_m.bvalid); |
endfunction: is_valid |
|
|
// -------------------------------------------------------------------- |
// |
function void set_valid(bit value); |
axi4_bus.cb_s.bvalid <= value; |
endfunction: set_valid |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_ready; |
return(axi4_bus.cb_s.bready); |
endfunction: is_ready |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_transfer; |
return(axi4_bus.cb_s.bready & axi4_bus.cb_m.bvalid); |
endfunction: is_transfer |
|
|
//-------------------------------------------------------------------- |
function new(virtual axi4_if #(A, N, I) axi4_bus); |
super.new(axi4_bus); |
endfunction: new |
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_b_if_class |
|
// -------------------------------------------------------------------- |
// |
class axi4_r_if_class #(A, N, I) |
extends axi4_channel_if_class #(A, N, I); |
|
logic [(8*N)-1:0] rdata; |
logic [(I-1):0] rid; |
logic rlast; |
logic [1:0] rresp; |
|
|
// -------------------------------------------------------------------- |
// |
function void set_master_default; |
axi4_bus.cb_m.rready <= 0; |
endfunction: set_master_default |
|
|
// -------------------------------------------------------------------- |
// |
function void set_slave_default; |
axi4_bus.cb_s.rvalid <= 0; |
endfunction: set_slave_default |
|
|
// -------------------------------------------------------------------- |
// |
function void copy(axi4_channel_if_class #(A, N, I) from); |
axi4_r_if_class #(A, N, I) child; |
$cast(child, from); |
rdata = child.rdata; |
rid = child.rid; |
rlast = child.rlast; |
rresp = child.rresp; |
endfunction: copy |
|
|
// -------------------------------------------------------------------- |
// |
function void copy_if; |
rdata = axi4_bus.cb_m.rdata; |
rid = axi4_bus.cb_m.rid; |
rlast = axi4_bus.cb_m.rlast; |
rresp = axi4_bus.cb_m.rresp; |
endfunction: copy_if |
|
|
// -------------------------------------------------------------------- |
// |
function void drive_if; |
axi4_bus.cb_s.rdata <= rdata; |
axi4_bus.cb_s.rid <= rid; |
axi4_bus.cb_s.rlast <= rlast; |
axi4_bus.cb_s.rresp <= rresp; |
endfunction: drive_if |
|
|
// -------------------------------------------------------------------- |
// |
function void set_ready(bit value); |
axi4_bus.cb_m.rready <= value; |
endfunction: set_ready |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_valid; |
return(axi4_bus.cb_m.rvalid); |
endfunction: is_valid |
|
|
// -------------------------------------------------------------------- |
// |
function void set_valid(bit value); |
axi4_bus.cb_s.rvalid <= value; |
endfunction: set_valid |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_ready; |
return(axi4_bus.cb_s.rready); |
endfunction: is_ready |
|
|
// -------------------------------------------------------------------- |
// |
function bit is_transfer; |
return(axi4_bus.cb_s.rready & axi4_bus.cb_m.rvalid); |
endfunction: is_transfer |
|
|
//-------------------------------------------------------------------- |
function new(virtual axi4_if #(A, N, I) axi4_bus); |
super.new(axi4_bus); |
endfunction: new |
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_r_if_class |
|
|
// -------------------------------------------------------------------- |
// |
virtual class axi4_master_model_class #(A, N, I); |
|
virtual axi4_if #(A, N, I) axi4_m; |
axi4_aw_if_class #(A, N, I) aw_if_h; |
axi4_channel_source_q_class #(A, N, I, axi4_aw_if_class #(A, N, I)) aw_q_h; |
axi4_w_if_class #(A, N, I) w_if_h; |
axi4_channel_source_q_class #(A, N, I, axi4_w_if_class #(A, N, I)) w_q_h; |
axi4_b_if_class #(A, N, I) b_if_h; |
axi4_channel_sink_q_class #(A, N, I, axi4_b_if_class #(A, N, I)) b_q_h; |
axi4_ar_if_class #(A, N, I) ar_if_h; |
axi4_channel_source_q_class #(A, N, I, axi4_ar_if_class #(A, N, I)) ar_q_h; |
axi4_r_if_class #(A, N, I) r_if_h; |
axi4_channel_sink_q_class #(A, N, I, axi4_r_if_class #(A, N, I)) r_q_h; |
|
|
// -------------------------------------------------------------------- |
// |
pure virtual task run_model; |
|
|
//-------------------------------------------------------------------- |
function new(virtual axi4_if #(A, N, I) axi4_m); |
this.axi4_m = axi4_m; |
this.aw_if_h = new(axi4_m); |
aw_if_h.set_master_default(); |
this.w_if_h = new(axi4_m); |
w_if_h.set_master_default(); |
this.b_if_h = new(axi4_m); |
b_if_h.set_master_default(); |
this.ar_if_h = new(axi4_m); |
ar_if_h.set_master_default(); |
this.r_if_h = new(axi4_m); |
r_if_h.set_master_default(); |
|
fork |
run_model(); |
join_none |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_master_model_class |
|
|
// -------------------------------------------------------------------- |
// |
virtual class axi4_slave_model_class #(A, N, I); |
|
virtual axi4_if #(A, N, I) axi4_s; |
axi4_aw_if_class #(A, N, I) aw_if_h; |
axi4_channel_sink_q_class #(A, N, I, axi4_aw_if_class #(A, N, I)) aw_q_h; |
axi4_w_if_class #(A, N, I) w_if_h; |
axi4_channel_sink_q_class #(A, N, I, axi4_w_if_class #(A, N, I)) w_q_h; |
axi4_b_if_class #(A, N, I) b_if_h; |
axi4_channel_source_q_class #(A, N, I, axi4_b_if_class #(A, N, I)) b_q_h; |
axi4_ar_if_class #(A, N, I) ar_if_h; |
axi4_channel_sink_q_class #(A, N, I, axi4_ar_if_class #(A, N, I)) ar_q_h; |
axi4_r_if_class #(A, N, I) r_if_h; |
axi4_channel_source_q_class #(A, N, I, axi4_r_if_class #(A, N, I)) r_q_h; |
|
|
// -------------------------------------------------------------------- |
// |
pure virtual task run_model; |
|
|
//-------------------------------------------------------------------- |
function new(virtual axi4_if #(A, N, I) axi4_s); |
|
this.axi4_s = axi4_s; |
this.aw_if_h = new(axi4_s); |
aw_if_h.set_slave_default(); |
this.w_if_h = new(axi4_s); |
w_if_h.set_slave_default(); |
this.b_if_h = new(axi4_s); |
b_if_h.set_slave_default(); |
this.ar_if_h = new(axi4_s); |
ar_if_h.set_slave_default(); |
this.r_if_h = new(axi4_s); |
r_if_h.set_slave_default(); |
|
fork |
run_model(); |
join_none |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: axi4_slave_model_class |
|
|
// -------------------------------------------------------------------- |
// |
endpackage: axi4_models_pkg |
|
|
/axi4_models/tb_axi4_multi_port_memory.sv
0,0 → 1,89
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
module |
tb_axi4_multi_port_memory |
#( |
A = 32, // address bus width |
N = 8, // data bus width in bytes |
I = 1, // ID width |
PORTS, |
MAXWAITS = 256, |
type WORD_T = byte |
) |
( |
axi4_if axi4_s[PORTS], |
|
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// |
import axis_bfm_pkg::*; |
import axi4_memory_pkg::*; |
import axi4_arbiter_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
axi4_if #(.A(A), .N(N), .I(I)) axi4_bus(.*); |
|
|
// -------------------------------------------------------------------- |
// |
axi4_arbiter_class #(A, N, I) arb_h; |
axi4_memory_class #(A, N, I, WORD_T) m_h; |
|
initial |
begin |
arb_h = new(axi4_s, axi4_bus); |
m_h = new(axi4_bus); |
end |
|
|
// -------------------------------------------------------------------- |
// |
axi4_checker #(.A(A), .N(N), .MAXWAITS(MAXWAITS)) |
axi4_bus_checker(.axi4_in(axi4_bus)); |
|
|
// -------------------------------------------------------------------- |
// |
generate |
begin: axi4_s_cherkers |
for(genvar j = 0; j < PORTS; j++) |
axi4_checker #(.A(A), .N(N), .MAXWAITS(MAXWAITS)) |
axi4_checker_i(.axi4_in(axi4_s[j])); |
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
endmodule |
|
/tb_axi4_memory.sv
0,0 → 1,129
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
|
module tb_top(); |
|
// -------------------------------------------------------------------- |
// test bench clock & reset |
wire clk_100mhz; |
wire tb_clk = clk_100mhz; |
wire tb_rst; |
wire aclk = tb_clk; |
wire aresetn = ~tb_rst; |
|
tb_base #(.PERIOD(10_000)) tb(clk_100mhz, tb_rst); |
|
|
// -------------------------------------------------------------------- |
// |
localparam A = 32; |
localparam N = 8; |
|
|
// -------------------------------------------------------------------- |
// |
axi4_if #(.A(A), .N(N)) |
axi4_s(.*); |
|
|
// -------------------------------------------------------------------- |
// |
|
|
// -------------------------------------------------------------------- |
// sim models |
// | | | | | | | | | | | | | | | | | |
// \|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/ |
// ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' |
|
// -------------------------------------------------------------------- |
// |
axi4_checker #(.A(A), .N(N)) |
axi4_s_check(.axi4_in(axi4_s)); |
|
|
// // -------------------------------------------------------------------- |
// // |
// axi4_master_bfm_if #(.A(A), .N(N)) |
// tb_axi4_m(.axi4_s(axi4_s), .*); |
|
|
// -------------------------------------------------------------------- |
// |
import axi4_bfm_pkg::*; |
|
axi4_master_bfm_class bfm; |
|
initial |
bfm = new(axi4_s); |
|
|
// -------------------------------------------------------------------- |
// |
import axi4_memory_pkg::*; |
|
axi4_memory_class axi4_memory; |
|
initial |
axi4_memory = new(axi4_s); |
|
|
// ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' |
// /|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\ |
// | | | | | | | | | | | | | | | | | |
// sim models |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// debug wires |
|
|
// -------------------------------------------------------------------- |
// test |
the_test test( tb_clk, tb_rst ); |
|
initial |
begin |
|
test.run_the_test(); |
|
$display("^^^---------------------------------"); |
$display("^^^ %16.t | Testbench done.", $time); |
$display("^^^---------------------------------"); |
|
$display("^^^---------------------------------"); |
|
$stop(); |
|
end |
|
endmodule |
|
|
|
/tb_axi4_to_axis_agent_class_pkg.sv
0,0 → 1,130
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_axi4_to_axis_agent_class_pkg; |
|
// -------------------------------------------------------------------- |
// |
import axi4_memory_pkg::*; |
import axis_bfm_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
class tb_axi4_to_axis_agent_class #(N, A, I, D, U); |
|
axi4_memory_class #(A, N, I) m_h; |
axis_rx_bfm_class #(N, I, D, U) s_h; |
memory_tr_class #(A, N, I) m_tr_h, m_tr_clone_h; |
axis_tr_class #(N, I, D, U) s_tr_h; |
|
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m; |
virtual axis_if #(.N(N), .I(I), .D(D), .U(U)) axis_out; |
|
mailbox #(memory_tr_class #(A, N, I)) q; |
|
|
// -------------------------------------------------------------------- |
// |
task wait_for_sof; |
@(posedge axis_out.cb_s.tuser); |
$display("^^^ %16.t | %m", $time); |
endtask: wait_for_sof |
|
|
// -------------------------------------------------------------------- |
// |
task random_transaction(int addr, int size); |
m_tr_h = new(); |
m_tr_h.random(addr, size); |
m_tr_clone_h = m_tr_h.clone(); |
q.put(m_tr_clone_h); |
m_h.load_words(addr, m_tr_h.data); |
endtask: random_transaction |
|
|
// -------------------------------------------------------------------- |
// |
task automatic |
compare; |
|
$display("^^^ %16.t | %m", $time); |
$display("^^^ %16.t | q.num = %d", $time, q.num); |
$display("^^^ %16.t | s_h.q.num = %d", $time, s_h.q.num); |
$display("^^^ %16.t | m_tr_h.data.size = %d", $time, m_tr_h.data.size); |
|
q.get(m_tr_h); |
|
for(int i = 0; i < m_tr_h.data.size; i += N) |
begin |
if(s_h.q.try_get(s_tr_h) == 0) |
begin |
$display("!!! %16.t | ERROR!!! try_get(s_tr_h) == 0", $time); |
break; |
end |
|
for(int k = 0; k < N; k++) |
begin |
if(s_tr_h.tdata[k*8 +: 8] != m_tr_h.data[i + k]) |
begin |
$display("!!! %16.t | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^", $time); |
$display("!!! %16.t | ERROR!!! mismatch | i = %d | k = %d", $time, i, k); |
$display("!!! %16.t | %x | %x |", $time, s_tr_h.tdata[k*8 +: 8], m_tr_h.data[i + k]); |
$stop; |
end |
end |
end |
|
$display("^^^ %16.t | %m | done!", $time); |
|
endtask: compare |
|
|
//-------------------------------------------------------------------- |
// |
function new |
( |
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m, |
virtual axis_if #(.N(N), .I(I), .D(D), .U(U)) axis_out |
); |
|
this.axi4_m = axi4_m; |
this.axis_out = axis_out; |
m_h = new(axi4_m); |
s_h = new(axis_out); |
q = new(); |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: tb_axi4_to_axis_agent_class |
|
// -------------------------------------------------------------------- |
// |
endpackage: tb_axi4_to_axis_agent_class_pkg |