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
    from Rev 31 to Rev 45
    Reverse comparison

Rev 31 → Rev 45

/src/legacy/axi4_bfm/axi4_master_bfm_if.sv
0,0 → 1,526
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2015 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
 
interface
axi4_master_bfm_if
#(
A = 32, // address bus width
N = 8, // data bus width in bytes
I = 1 // ID width
)
(
axi4_if axi4_s,
input aresetn,
input aclk
);
 
logic [(A-1):0] araddr;
logic [1:0] arburst;
logic [3:0] arcache;
logic [(I-1):0] arid;
logic [7:0] arlen;
logic arlock;
logic [2:0] arprot;
logic [3:0] arqos;
logic arready;
logic [3:0] arregion;
logic [2:0] arsize;
logic arvalid;
logic [(A-1):0] awaddr;
logic [1:0] awburst;
logic [3:0] awcache;
logic [(I-1):0] awid;
logic [7:0] awlen;
logic awlock;
logic [2:0] awprot;
logic [3:0] awqos;
logic awready;
logic [3:0] awregion;
logic [2:0] awsize;
logic awvalid;
logic [(I-1):0] bid;
logic bready;
logic [1:0] bresp;
logic bvalid;
logic [(8*N)-1:0] rdata;
logic [(I-1):0] rid;
logic rlast;
logic rready;
logic [1:0] rresp;
logic rvalid;
logic [(8*N)-1:0] wdata;
logic [(I-1):0] wid;
logic wlast;
logic wready;
logic [N-1:0] wstrb;
logic wvalid;
 
 
// --------------------------------------------------------------------
//
default clocking cb @(posedge aclk);
output arid;
output araddr;
output arburst;
output arcache;
output awid;
output arlen;
output arlock;
output arprot;
output arqos;
input arready;
output arregion;
output arsize;
output arvalid;
output awaddr;
output awburst;
output awcache;
output awlen;
output awlock;
output awprot;
output awqos;
input awready;
output awregion;
output awsize;
output awvalid;
output bready;
input bid;
input bresp;
input bvalid;
input rdata;
input rid;
input rlast;
output rready;
input rresp;
input rvalid;
output wdata;
output wlast;
input wready;
output wstrb;
output wvalid;
input aresetn;
input aclk;
endclocking
 
 
// --------------------------------------------------------------------
//
assign axi4_s.arid = arid;
assign axi4_s.araddr = araddr;
assign axi4_s.arburst = arburst;
assign axi4_s.arcache = arcache;
assign axi4_s.awid = awid;
assign axi4_s.arlen = arlen;
assign axi4_s.arlock = arlock;
assign axi4_s.arprot = arprot;
assign axi4_s.arqos = arqos;
assign arready = axi4_s.arready;
assign axi4_s.arregion = arregion;
assign axi4_s.arsize = arsize;
assign axi4_s.arvalid = arvalid;
assign axi4_s.awaddr = awaddr;
assign axi4_s.awburst = awburst;
assign axi4_s.awcache = awcache;
assign axi4_s.awlen = awlen;
assign axi4_s.awlock = awlock;
assign axi4_s.awprot = awprot;
assign axi4_s.awqos = awqos;
assign awready = axi4_s.awready;
assign axi4_s.awregion = awregion;
assign axi4_s.awsize = awsize;
assign axi4_s.awvalid = awvalid;
assign axi4_s.bready = bready;
assign bid = axi4_s.bid;
assign bresp = axi4_s.bresp;
assign bvalid = axi4_s.bvalid;
assign rdata = axi4_s.rdata;
assign rid = axi4_s.rid;
assign rlast = axi4_s.rlast;
assign axi4_s.rready = rready;
assign rresp = axi4_s.rresp;
assign rvalid = axi4_s.rvalid;
assign axi4_s.wdata = wdata;
assign axi4_s.wlast = wlast;
assign wready = axi4_s.wready;
assign axi4_s.wstrb = wstrb;
assign axi4_s.wvalid = wvalid;
 
 
// --------------------------------------------------------------------
//
function void
ar_default;
 
cb.araddr <= 'bx;
cb.arburst <= 'bx;
cb.arcache <= 'bx;
cb.arid <= 'bx;
cb.arlen <= 'bx;
cb.arlock <= 'bx;
cb.arprot <= 'bx;
cb.arqos <= 'bx;
cb.arregion <= 'bx;
cb.arsize <= 'bx;
cb.arvalid <= 0;
 
endfunction: ar_default
 
 
// --------------------------------------------------------------------
//
function void
aw_default;
 
cb.awaddr <= 'bx;
cb.awburst <= 'bx;
cb.awcache <= 'bx;
cb.awid <= 'bx;
cb.awlen <= 'bx;
cb.awlock <= 'bx;
cb.awprot <= 'bx;
cb.awqos <= 'bx;
cb.awregion <= 'bx;
cb.awsize <= 'bx;
cb.awvalid <= 0;
 
endfunction: aw_default
 
 
// --------------------------------------------------------------------
//
function void
r_default;
 
cb.rready <= 0;
 
endfunction: r_default
 
 
// --------------------------------------------------------------------
//
function void
w_default;
 
cb.wdata <= 'bx;
cb.wlast <= 'bx;
cb.wstrb <= {N{1'b1}};
cb.wvalid <= 0;
 
endfunction: w_default
 
 
// --------------------------------------------------------------------
//
function void
b_default;
 
cb.bready <= 0;
 
endfunction: b_default
 
 
// --------------------------------------------------------------------
//
function void
init;
 
ar_default();
r_default();
aw_default();
w_default();
b_default();
 
endfunction: init
 
 
// --------------------------------------------------------------------
//
task
zero_cycle_delay;
 
##0;
 
endtask: zero_cycle_delay
 
 
// --------------------------------------------------------------------
//
import tb_bfm_pkg::*;
import axi4_transaction_pkg::*;
 
 
// --------------------------------------------------------------------
//
class 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)));
 
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
 
->this.start;
 
##(tr_h.delay_h.next());
 
cb.araddr <= tr_h.addr;
cb.arid <= tr_h.id;
cb.arlen <= tr_h.len;
cb.arsize <= tr_h.size;
 
cb.arburst <= tr_h.burst;
cb.arcache <= tr_h.cache;
cb.arlock <= tr_h.lock;
cb.arprot <= tr_h.prot;
cb.arqos <= tr_h.qos;
cb.arregion <= tr_h.region;
cb.arvalid <= 1;
 
$display("^^^ %16.t | %m | master AR transaction @ 0x%08x |", $time, tr_h.addr);
 
##1;
wait(cb.arready);
 
##0;
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)));
 
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
 
->this.start;
 
tr_h.data_h = new(tr_h.len);
 
foreach(tr_h.payload_h.w[i])
begin
##(tr_h.delay_h.next());
cb.rready <= 1;
##1;
 
wait(cb.rvalid);
##0;
 
tr_h.data_h.w[i] = cb.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)));
 
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
 
->this.start;
 
##(tr_h.delay_h.next());
 
cb.awaddr <= tr_h.addr;
cb.awid <= tr_h.id;
cb.awlen <= tr_h.len;
cb.awsize <= tr_h.size;
 
cb.awburst <= tr_h.burst;
cb.awcache <= tr_h.cache;
cb.awlock <= tr_h.lock;
cb.awprot <= tr_h.prot;
cb.awqos <= tr_h.qos;
cb.awregion <= tr_h.region;
cb.awvalid <= 1;
 
$display("^^^ %16.t | %m | master AW transaction @ 0x%08x |", $time, tr_h.addr);
 
##1;
wait(cb.awready);
 
##0;
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)));
 
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
 
->this.start;
 
foreach(tr_h.payload_h.w[i])
begin
##(tr_h.delay_h.next());
 
cb.wdata <= tr_h.payload_h.w[i];
// cb.wstrb <= tr_h.strb; // need to fix
 
if(i < tr_h.payload_h.w.size - 1)
cb.wlast <= 0;
else
cb.wlast <= 1;
 
cb.wvalid <= 1;
 
##1;
wait(cb.wready);
 
##0;
$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)));
 
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
 
->this.start;
 
##(tr_h.delay_h.next());
cb.bready <= 1;
##1;
 
wait(cb.bvalid);
##0;
 
$display("^^^ %16.t | %m | master B transaction | 0x%x |", $time, cb.bresp);
b_default();
 
->this.done;
 
endtask: transaction
 
 
// --------------------------------------------------------------------
//
endclass: b_master_transaction_class
 
 
// --------------------------------------------------------------------
//
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;
 
initial
begin
init();
ar_h = new;
ar_h.init();
r_h = new;
r_h.init();
aw_h = new;
aw_h.init();
w_h = new;
w_h.init();
b_h = new;
b_h.init();
end
 
 
// --------------------------------------------------------------------
//
 
endinterface
 
 
/src/legacy/axi4_bfm/axi4_simple_agent_pkg.sv
0,0 → 1,153
//////////////////////////////////////////////////////////////////////
//// ////
//// 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_simple_agent_pkg;
 
// --------------------------------------------------------------------
//
import axi4_transaction_pkg::*;
 
 
// --------------------------------------------------------------------
//
class axi4_simple_agent_class #(A = 32, N = 8, I = 1);
 
axi4_transaction_class tr_h;
virtual axi4_master_bfm_if #(.A(A), .N(N), .I(I)) axi4_m;
virtual axi4_slave_bfm_if #(.A(A), .N(N), .I(I)) axi4_s;
 
 
//--------------------------------------------------------------------
function new
(
virtual axi4_master_bfm_if #(.A(A), .N(N), .I(I)) axi4_m,
virtual axi4_slave_bfm_if #(.A(A), .N(N), .I(I)) axi4_s
);
 
this.axi4_m = axi4_m;
this.axi4_s = axi4_s;
 
endfunction: new
 
 
// --------------------------------------------------------------------
//
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);
 
axi4_m.ar_h.put(tr_h);
axi4_s.ar_h.put(tr_h);
axi4_m.r_h.put(tr_h);
 
@(axi4_m.r_h.done);
data = tr_h.data_h.w;
rresp = tr_h.resp;
 
endtask: basic_read
 
 
// --------------------------------------------------------------------
//
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];
 
axi4_m.aw_h.put(tr_h);
axi4_s.aw_h.put(tr_h);
axi4_m.w_h.put(tr_h);
axi4_s.w_h.put(tr_h);
axi4_m.b_h.put(tr_h);
 
@(axi4_s.b_h.done);
bresp = tr_h.resp;
 
endtask: basic_write
 
 
// --------------------------------------------------------------------
//
task
basic_random_write
(
input logic [(A-1):0] awaddr,
input logic [7:0] awlen,
output logic [1:0] bresp
);
 
this.tr_h = new;
this.tr_h.basic_write(awaddr, awlen);
 
axi4_m.aw_h.put(tr_h);
axi4_s.aw_h.put(tr_h);
axi4_m.w_h.put(tr_h);
axi4_s.w_h.put(tr_h);
axi4_m.b_h.put(tr_h);
 
@(axi4_s.b_h.done);
bresp = tr_h.resp;
 
endtask: basic_random_write
 
 
// --------------------------------------------------------------------
//
function void
init;
 
endfunction: init
 
 
// --------------------------------------------------------------------
//
endclass: axi4_simple_agent_class
 
 
// --------------------------------------------------------------------
//
endpackage: axi4_simple_agent_pkg
 
/src/legacy/axi4_bfm/axi4_slave_bfm_if.sv
0,0 → 1,514
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2015 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
 
interface
axi4_slave_bfm_if
#(
A = 32, // address bus width
N = 8, // data bus width in bytes
I = 1 // ID width
)
(
axi4_if axi4_m,
input aresetn,
input aclk
);
 
logic [(A-1):0] araddr;
logic [1:0] arburst;
logic [3:0] arcache;
logic [(I-1):0] arid;
logic [7:0] arlen;
logic arlock;
logic [2:0] arprot;
logic [3:0] arqos;
logic arready;
logic [3:0] arregion;
logic [2:0] arsize;
logic arvalid;
logic [(A-1):0] awaddr;
logic [1:0] awburst;
logic [3:0] awcache;
logic [(I-1):0] awid;
logic [7:0] awlen;
logic awlock;
logic [2:0] awprot;
logic [3:0] awqos;
logic awready;
logic [3:0] awregion;
logic [2:0] awsize;
logic awvalid;
logic [(I-1):0] bid;
logic bready;
logic [1:0] bresp;
logic bvalid;
logic [(8*N)-1:0] rdata;
logic [(I-1):0] rid;
logic rlast;
logic rready;
logic [1:0] rresp;
logic rvalid;
logic [(8*N)-1:0] wdata;
logic [(I-1):0] wid;
logic wlast;
logic wready;
logic [N-1:0] wstrb;
logic wvalid;
 
 
// --------------------------------------------------------------------
//
default clocking cb @(posedge aclk);
input arid;
input araddr;
input arburst;
input arcache;
input awid;
input arlen;
input arlock;
input arprot;
input arqos;
output arready;
input arregion;
input arsize;
input arvalid;
input awaddr;
input awburst;
input awcache;
input awlen;
input awlock;
input awprot;
input awqos;
output awready;
input awregion;
input awsize;
input awvalid;
input bready;
output bid;
output bresp;
output bvalid;
output rdata;
output rid;
output rlast;
input rready;
output rresp;
output rvalid;
input wdata;
input wid;
input wlast;
output wready;
input wstrb;
input wvalid;
input aresetn;
input aclk;
endclocking
 
 
// --------------------------------------------------------------------
//
assign arid = axi4_m.arid;
assign araddr = axi4_m.araddr;
assign arburst = axi4_m.arburst;
assign arcache = axi4_m.arcache;
assign awid = axi4_m.awid;
assign arlen = axi4_m.arlen;
assign arlock = axi4_m.arlock;
assign arprot = axi4_m.arprot;
assign arqos = axi4_m.arqos;
assign axi4_m.arready = arready;
assign arregion = axi4_m.arregion;
assign arsize = axi4_m.arsize;
assign arvalid = axi4_m.arvalid;
assign awaddr = axi4_m.awaddr;
assign awburst = axi4_m.awburst;
assign awcache = axi4_m.awcache;
assign awlen = axi4_m.awlen;
assign awlock = axi4_m.awlock;
assign awprot = axi4_m.awprot;
assign awqos = axi4_m.awqos;
assign axi4_m.awready = awready;
assign awregion = axi4_m.awregion;
assign awsize = axi4_m.awsize;
assign awvalid = axi4_m.awvalid;
assign bready = axi4_m.bready;
assign axi4_m.bid = bid;
assign axi4_m.bresp = bresp;
assign axi4_m.bvalid = bvalid;
assign axi4_m.rdata = rdata;
assign axi4_m.rid = rid;
assign axi4_m.rlast = rlast;
assign rready = axi4_m.rready;
assign axi4_m.rresp = rresp;
assign axi4_m.rvalid = rvalid;
assign wdata = axi4_m.wdata;
assign wlast = axi4_m.wlast;
assign axi4_m.wready = wready;
assign wstrb = axi4_m.wstrb;
assign wvalid = axi4_m.wvalid;
 
 
// --------------------------------------------------------------------
//
function void
ar_default;
 
cb.arready <= 0;
 
endfunction: ar_default
 
 
// --------------------------------------------------------------------
//
function void
aw_default;
 
cb.awready <= 0;
 
endfunction: aw_default
 
 
// --------------------------------------------------------------------
//
function void
r_default;
 
cb.rdata <= 'bx;
cb.rid <= 'bx;
cb.rlast <= 'bx;
cb.rresp <= 0;
cb.rvalid <= 0;
 
endfunction: r_default
 
 
// --------------------------------------------------------------------
//
function void
w_default;
 
cb.wready <= 0;
 
endfunction: w_default
 
 
// --------------------------------------------------------------------
//
function void
b_default;
 
cb.bid <= 0;
cb.bresp <= 0;
cb.bvalid <= 0;
 
endfunction: b_default
 
 
// --------------------------------------------------------------------
//
function void
init;
 
ar_default();
r_default();
aw_default();
w_default();
b_default();
 
endfunction: init
 
 
// --------------------------------------------------------------------
//
task
zero_cycle_delay;
 
##0;
 
endtask: zero_cycle_delay
 
 
// --------------------------------------------------------------------
//
import tb_bfm_pkg::*;
import axi4_transaction_pkg::*;
 
 
// --------------------------------------------------------------------
//
class r_slave_transaction_class #(A = 32, N = 8, I = 1)
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));
 
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
 
->this.start;
 
foreach(tr_h.payload_h.w[i])
begin
##(tr_h.delay_h.next());
 
cb.rdata <= tr_h.payload_h.w[i];
cb.rresp <= tr_h.resp;
cb.rid <= tr_h.id;
 
if(i < tr_h.payload_h.w.size - 1)
cb.rlast <= 0;
else
cb.rlast <= 1;
 
cb.rvalid <= 1;
##1;
 
wait(cb.rready);
##0;
 
$display("^^^ %16.t | %m | slave R transaction | %d | 0x%016x |", $time, i, tr_h.payload_h.w[i]);
r_default();
end
 
->this.done;
 
endtask: transaction
 
 
// --------------------------------------------------------------------
//
endclass: r_slave_transaction_class
 
 
// --------------------------------------------------------------------
//
r_slave_transaction_class #(.A(A), .N(N), .I(I)) r_h;
 
class ar_slave_transaction_class #(A = 32, N = 8, I = 1)
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));
 
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
 
->this.start;
 
##(tr_h.delay_h.next());
 
cb.arready <= 1;
##1;
 
wait(cb.arvalid);
 
##0;
r_h.put(tr_h);
ar_default();
 
$display("^^^ %16.t | %m | slave AR transaction @ 0x%08x | 0x%016x |", $time, tr_h.addr, tr_h.payload_h.w[0]);
 
->this.done;
 
endtask: transaction
 
 
// --------------------------------------------------------------------
//
endclass: ar_slave_transaction_class
 
 
// --------------------------------------------------------------------
//
class aw_slave_transaction_class #(A = 32, N = 8, I = 1)
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));
 
semaphore aw_semaphore;
 
 
//--------------------------------------------------------------------
function new;
 
super.new();
this.aw_semaphore = new(0);
 
endfunction: new
 
 
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
 
->this.start;
 
##(tr_h.delay_h.next());
 
cb.awready <= 1;
##1;
 
wait(cb.awvalid);
 
##0;
this.aw_semaphore.put();
aw_default();
 
$display("^^^ %16.t | %m | slave AW transaction @ 0x%08x | 0x%016x |", $time, tr_h.addr, tr_h.payload_h.w[0]);
 
->this.done;
 
endtask: transaction
 
// --------------------------------------------------------------------
//
endclass: aw_slave_transaction_class
 
 
// --------------------------------------------------------------------
//
aw_slave_transaction_class #(.A(A), .N(N), .I(I)) aw_h;
 
class b_slave_transaction_class #(A = 32, N = 8, I = 1)
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));
 
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
 
->this.start;
 
// Error: AXI4_ERRS_BRESP_AW: A slave must not give a write response before the write address.
// Spec: section A3.3.1 and figure A3-7.
aw_h.aw_semaphore.get(); // better way to do this???
 
##(tr_h.delay_h.next());
 
cb.bresp <= tr_h.resp;
cb.bid <= tr_h.id;
 
cb.bvalid <= 1;
##1;
 
wait(cb.bready);
##0;
 
$display("^^^ %16.t | %m | slave B transaction |", $time);
b_default();
 
->this.done;
 
endtask: transaction
 
// --------------------------------------------------------------------
//
endclass: b_slave_transaction_class
 
 
// --------------------------------------------------------------------
//
b_slave_transaction_class #(.A(A), .N(N), .I(I)) b_h;
 
class w_slave_transaction_class #(A = 32, N = 8, I = 1)
extends tb_blocking_transaction_q_class #(axi4_transaction_class #(.A(A), .N(N), .I(I)));
 
// --------------------------------------------------------------------
//
task automatic
transaction
(
ref T tr_h
);
 
->this.start;
 
tr_h.data_h = new(tr_h.len);
 
foreach(tr_h.payload_h.w[i])
begin
##(tr_h.delay_h.next());
 
cb.wready <= 1;
##1;
 
wait(cb.wvalid);
##0;
 
tr_h.data_h.w[i] <= cb.wdata;
$display("^^^ %16.t | %m | slave W transaction | %d | 0x%016x |", $time, i, cb.wdata);
w_default();
end
 
b_h.put(tr_h);
 
->this.done;
 
endtask: transaction
 
 
// --------------------------------------------------------------------
//
endclass: w_slave_transaction_class
 
 
// --------------------------------------------------------------------
//
ar_slave_transaction_class #(.A(A), .N(N), .I(I)) ar_h;
w_slave_transaction_class #(.A(A), .N(N), .I(I)) w_h;
 
initial
begin
init();
ar_h = new;
ar_h.init();
r_h = new;
r_h.init();
aw_h = new;
aw_h.init();
w_h = new;
w_h.init();
b_h = new;
b_h.init();
end
 
 
// --------------------------------------------------------------------
//
 
endinterface
 
 
/src/legacy/axi4_bfm/axi4_transaction_pkg.sv
0,0 → 1,253
//////////////////////////////////////////////////////////////////////
//// ////
//// 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_transaction_pkg;
 
// --------------------------------------------------------------------
//
class axi4_delay_class;
 
rand int unsigned delay;
 
 
// --------------------------------------------------------------------
//
function int unsigned
next;
 
assert(this.randomize() with{delay dist {0 := 40, [1:3] := 40, [4:7] := 20};});
return(delay);
 
endfunction: next
 
 
// --------------------------------------------------------------------
//
endclass: axi4_delay_class
 
 
// --------------------------------------------------------------------
//
class axi4_payload_class #(N = 8);
 
rand logic [(8*N)-1:0] w[];
 
 
// --------------------------------------------------------------------
//
function
new
(
logic [7:0] len = 0
);
 
this.w = new[len + 1];
 
endfunction: new
 
 
// --------------------------------------------------------------------
//
function void
random
(
logic [7:0] len = 0
);
 
this.w = new[len + 1];
assert(this.randomize());
 
endfunction: random
 
 
// --------------------------------------------------------------------
//
endclass: axi4_payload_class
 
 
// --------------------------------------------------------------------
//
class axi4_transaction_class #(A = 32, N = 8, I = 1);
 
axi4_delay_class delay_h;
axi4_payload_class #(.N(N)) payload_h;
axi4_payload_class #(.N(N)) data_h;
rand logic [(A-1):0] addr = 'bz;
rand logic [1:0] burst = 2'b01;
rand logic [7:0] len = 0;
rand logic [2:0] size = $clog2(N);
rand logic [(I-1):0] id = 0;
rand logic [1:0] resp = 0;
 
logic [3:0] cache = 0;
logic lock = 0;
logic [2:0] prot = 0;
logic [3:0] qos = 0;
logic [3:0] region = 0;
 
constraint default_len
{
len dist {0 := 40, [1:15] := 40, [16:255] := 20};
}
 
 
// --------------------------------------------------------------------
//
function
new
(
logic [7:0] len = 0
);
 
this.payload_h = new(len + 1);
this.delay_h = new;
 
endfunction: new
 
 
// --------------------------------------------------------------------
//
function void
basic_random;
 
assert(this.randomize() with
{
this.id == 0;
this.resp == 0;
this.burst == 2'b01;
this.len == 0;
this.size == $clog2(N);
});
 
this.payload_h.random(this.len);
 
endfunction: basic_random
 
 
// --------------------------------------------------------------------
//
function void
basic_random_burst;
 
assert(this.randomize() with
{
this.addr[$clog2(N*8)-1:0] == 0;
this.id == 0;
this.resp == 0;
this.burst == 2'b01;
this.size == $clog2(N);
this.len dist {0 := 40, [1:3] := 40, [4:15] := 20};
});
 
this.payload_h.random(this.len);
 
endfunction: basic_random_burst
 
 
// --------------------------------------------------------------------
//
function void
basic_read
(
logic [(A-1):0] addr,
logic [7:0] len = 0
);
 
this.id = 0;
this.resp = 0;
this.burst = 2'b01;
this.size = $clog2(N);
this.addr = addr;
this.len = len;
this.payload_h.random(len);
 
endfunction: basic_read
 
 
// --------------------------------------------------------------------
//
function void
basic_write
(
logic [(A-1):0] addr,
logic [7:0] len = 0
);
 
this.id = 0;
this.resp = 0;
this.burst = 2'b01;
this.size = $clog2(N);
this.addr = addr;
this.len = len;
this.payload_h.random(len);
 
endfunction: basic_write
 
 
// --------------------------------------------------------------------
//
function void copy
(
axi4_transaction_class #(.A(A), .N(N), .I(I)) from
);
 
this.addr = from.addr;
this.burst = from.burst;
this.len = from.len;
this.size = from.size;
this.id = from.id;
this.resp = from.resp;
this.cache = from.cache;
this.lock = from.lock;
this.prot = from.prot;
this.qos = from.qos;
this.region = from.region;
 
endfunction: copy
 
 
// --------------------------------------------------------------------
//
virtual function axi4_transaction_class #(.A(A), .N(N), .I(I)) clone;
 
clone = new();
clone.copy(this);
return(clone);
 
endfunction: clone
 
 
// --------------------------------------------------------------------
//
endclass: axi4_transaction_class
 
 
// --------------------------------------------------------------------
//
endpackage: axi4_transaction_pkg
 
/src/legacy/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
 
 
/src/legacy/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
 
/src/legacy/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
 
/src/legacy/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
 
 
/src/legacy/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
 

powered by: WebSVN 2.1.0

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