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

powered by: WebSVN 2.1.0

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