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
- from Rev 30 to Rev 31
- ↔ Reverse comparison
Rev 30 → Rev 31
/sim/libs/sim_verilog/axi4_bfm.f
File deleted
/sim/libs/sim_verilog/tb_lib.f
File deleted
/sim/libs/axi4_lib_verilog/axi4_base.f
File deleted
/sim/libs/axi4_lib_verilog/tiny_fifo.f
File deleted
/sim/libs/axi4_lib_verilog/axi4_stream_lib.f
File deleted
/sim/libs/packages_verilog/tb_lib.f
File deleted
/sim/src/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. |
|
/sim/src/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 |
/sim/src/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 |
|
|
/sim/src/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 |
|
/sim/src/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 |
|
/sim/src/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 |
|
|
/sim/src/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 |
|
/sim/src/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 |
|
|
|
/sim/src/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 |
/sim/tests/debug_axi4_memory/init_test.do
0,0 → 1,34
# ------------------------------------ |
# |
# ------------------------------------ |
|
global env |
|
set env(ROOT_DIR) ../../../../.. |
set env(PROJECT_DIR) ../../.. |
set env(SIM_TARGET) fpga |
|
# load sim procedures |
do $env(ROOT_DIR)/qaz_libs/scripts/sim_procs.do |
|
radix -hexadecimal |
|
make_lib work 1 |
|
sim_compile_all packages |
sim_compile_all sim |
sim_compile_all axi4_lib |
|
# simulation $root |
vlog $env(PROJECT_DIR)/sim/src/tb_axi4_memory.sv |
|
# compile test last |
vlog ./the_test.sv |
|
# vopt work.glbl tb_top -L secureip -L simprims_ver -L unisims_ver -f opt_tb_top.f -o opt_tb_top |
|
# run the sim |
sim_run_test |
|
|
|
/sim/tests/debug_axi4_memory/sim.do
0,0 → 1,21
# |
# |
|
|
quit -sim |
|
# vsim opt_tb_top |
|
vsim -novopt -f ./sim.f work.tb_top |
# vsim -novopt -L secureip -L simprims_ver -L unisims_ver work.glbl work.tb_top |
|
# vsim -voptargs="+acc=rn+/tb_top/dut" -L secureip -L simprims_ver -L unisims_ver work.glbl work.tb_top |
# vsim -pli "C:/Xilinx/Vivado/2015.4/lib/win64.o/libxil_vsim.dll" -novopt -L secureip -L simprims_ver -L unisims_ver work.glbl work.tb_top |
|
|
# # log all signals |
# log -r * |
|
# run -all |
|
|
/sim/tests/debug_axi4_memory/sim.f
0,0 → 1,14
# |
# |
|
+nowarn8887 |
|
-novopt |
-t 1ps |
|
-L work |
|
|
|
|
|
/sim/tests/debug_axi4_memory/the_test.sv
0,0 → 1,143
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`timescale 1ps/1ps |
|
|
module |
the_test( |
input tb_clk, |
input tb_rst |
); |
|
// -------------------------------------------------------------------- |
// |
localparam A = tb_top.A; |
localparam N = tb_top.N; |
|
|
// -------------------------------------------------------------------- |
// |
import axi4_transaction_pkg::*; |
axi4_payload_class payload_h; |
|
|
// -------------------------------------------------------------------- |
// |
logic [(8*N)-1:0] data[]; |
logic [1:0] resp; |
|
task run_the_test; |
|
// -------------------------------------------------------------------- |
// insert test below |
// -------------------------------------------------------------------- |
$display("^^^---------------------------------"); |
$display("^^^ %16.t | Testbench begun.\n", $time); |
$display("^^^---------------------------------"); |
// -------------------------------------------------------------------- |
|
tb_top.tb.timeout_stop(10us); |
|
|
// -------------------------------------------------------------------- |
wait(~tb_rst); |
|
|
// -------------------------------------------------------------------- |
#100ns; |
|
// force tb_top.axi4_s.bready = 1; |
|
data = new[16]; |
data[0] = 64'habba_beef_cafe_1a7e; |
tb_top.bfm.basic_write(32'h1234_0000, 0, data, resp); |
|
// -------------------------------------------------------------------- |
#100ns; |
|
repeat(5) |
begin |
tb_top.bfm.basic_random_write_burst(resp); |
end |
|
// -------------------------------------------------------------------- |
#100ns; |
|
repeat(5) |
begin |
tb_top.bfm.basic_random_read_burst(data, resp); |
end |
|
// // -------------------------------------------------------------------- |
// #100ns; |
|
// repeat(5) |
// begin |
// tb_top.bfm.basic_read(32'h1234_0000, 3, data, resp); |
|
// foreach(data[i]) |
// $display("^^^ %16.t | %d | 0x%016x |", $time, i, data[i]); |
// end |
|
// tb_top.bfm.basic_read(32'habcd_0000, 0, data, resp); |
// $display("^^^ %16.t | 0x%016x |", $time, data[0]); |
|
|
// // -------------------------------------------------------------------- |
// tb_top.bfm.basic_read(32'habcd_0000, 0, data, resp); |
// $display("^^^ %16.t | 0x%016x |", $time, data[0]); |
|
// // -------------------------------------------------------------------- |
// #100ns; |
|
// repeat(5) |
// begin |
// tb_top.bfm.basic_random_write(32'habcd_0000, 0, resp); |
// end |
|
// // -------------------------------------------------------------------- |
// #100ns; |
|
// repeat(5) |
// begin |
// tb_top.bfm.basic_random_write(32'habcd_0000, 3, resp); |
// end |
|
// -------------------------------------------------------------------- |
#100ns; |
|
|
// -------------------------------------------------------------------- |
// insert test above |
// -------------------------------------------------------------------- |
|
endtask |
|
|
endmodule |
|
/sim/tests/debug_axi4_memory/wip.do
0,0 → 1,15
# |
|
# vlog -f ../../libs/packages_verilog/tb_lib.f |
vlog -f ../../libs/sim_verilog/axi4_bfm.f |
vlog -f ../../libs/sim_verilog/axi4_models.f |
|
vlog -f ../../libs/axi4_lib_verilog/axi4_base.f |
|
# simulation $root |
vlog ../../src/tb_axi4_memory.sv |
|
# compile test last |
vlog ./the_test.sv |
|
|
/sim/tests/tb_axi4_to_axis_basic_dma/init_test.do
0,0 → 1,34
# ------------------------------------ |
# |
# ------------------------------------ |
|
global env |
|
# setup environment |
do ../../../../scripts/sim_env.do |
set env(SIM_TARGET) fpga |
set env(SIM_TB) tb_axi4_to_axis_basic_dma |
|
radix -hexadecimal |
|
make_lib work 1 |
|
sim_compile_all tb_packages |
sim_compile_all bfm_packages |
sim_compile_all axi4_lib |
sim_compile_all qaz_lib |
sim_compile_all sim |
|
# compile simulation files |
vlog -f ./$env(SIM_TB).f |
|
# simulation $root |
vlog ./$env(SIM_TB)_pkg.sv |
vlog ./$env(SIM_TB).sv |
|
# compile test last |
vlog ./the_test.sv |
|
# run the sim |
sim_run_test |
|
/sim/tests/tb_axi4_to_axis_basic_dma/sim.do
0,0 → 1,13
# |
# |
|
quit -sim |
|
vsim -novopt work.tb_top |
|
# log all signals |
log -r * |
|
# run -all |
|
|
/sim/tests/tb_axi4_to_axis_basic_dma/tb_axi4_to_axis_basic_dma.f
0,0 → 1,12
# |
|
${LIB_BASE_DIR}/axi4_stream_lib/sim/src/axis_bfm_pkg.sv |
${LIB_BASE_DIR}/axi4_lib/sim/src/axi4_models/axi4_memory_pkg.sv |
|
${PROJECT_DIR}/sim/src/tb_axi4_to_axis_agent_class_pkg.sv |
|
${PROJECT_DIR}/src/axi4_to_axis_basic_dma.sv |
|
./${SIM_TB}_pkg.sv |
./${SIM_TB}.sv |
|
/sim/tests/tb_axi4_to_axis_basic_dma/tb_axi4_to_axis_basic_dma.sv
0,0 → 1,115
// -------------------------------------------------------------------- |
// |
// -------------------------------------------------------------------- |
|
|
module tb_top(); |
|
// -------------------------------------------------------------------- |
// test bench clock & reset |
wire clk_200mhz; |
wire tb_clk = clk_200mhz; |
wire tb_rst; |
|
tb_base #(.PERIOD(5_000)) tb(clk_200mhz, tb_rst); |
|
|
// -------------------------------------------------------------------- |
// |
wire tb_rst_s; |
wire aclk = tb_clk; |
wire aresetn = ~tb_rst_s; |
|
sync_reset |
sync_reset_i(aclk, tb_rst, tb_rst_s); |
|
|
// -------------------------------------------------------------------- |
// |
import tb_axi4_to_axis_basic_dma_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
axi4_if #(.A(A), .N(N), .I(I)) axi4_m(.*); |
axis_if #(.N(N), .I(I), .D(D), .U(U)) axis_out(.*); |
|
|
// -------------------------------------------------------------------- |
// |
logic dma_enable = 0; |
|
axi4_to_axis_basic_dma |
#( |
.A(A), |
.N(N), |
.I(I), |
.BASE_ADDRESS(BASE_ADDRESS), |
.BUFFER_SIZE(BUFFER_SIZE), |
.BURST_LENGTH(BURST_LENGTH), |
.MAX_BURSTS(MAX_BURSTS), |
.BYTES_PER_TUSER(BYTES_PER_TUSER) |
) |
dut(.*); |
|
|
// -------------------------------------------------------------------- |
// sim models |
// | | | | | | | | | | | | | | | | | |
// \|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/ |
// ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' |
|
// -------------------------------------------------------------------- |
// |
axi4_checker #(.A(A), .N(N), .MAXWAITS(64)) |
axi4_checker_i(.axi4_in(axi4_m)); |
|
|
// -------------------------------------------------------------------- |
// |
axis_checker #(.N(N), .I(I), .D(D), .U(U)) |
axis_checker_i(.axis_in(axis_out)); |
|
|
// -------------------------------------------------------------------- |
// |
tb_axi4_to_axis_basic_dma_class a_h; |
|
initial |
a_h = new(axi4_m, axis_out); |
|
|
// -------------------------------------------------------------------- |
// |
|
// ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' |
// /|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\ |
// | | | | | | | | | | | | | | | | | |
// 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 |
/sim/tests/tb_axi4_to_axis_basic_dma/tb_axi4_to_axis_basic_dma_pkg.sv
0,0 → 1,58
// -------------------------------------------------------------------- |
// |
// -------------------------------------------------------------------- |
|
|
package tb_axi4_to_axis_basic_dma_pkg; |
|
// -------------------------------------------------------------------- |
// |
import tb_axi4_to_axis_agent_class_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
localparam BASE_ADDRESS = 32'h0000_0000; // must be on 4K boundry |
localparam BUFFER_SIZE = 'h800; |
localparam BURST_LENGTH = 8'h08; |
localparam MAX_BURSTS = 4; |
localparam BYTES_PER_TUSER = 2; // bytes per tuser bit. Set to 0 for transfer based. |
|
localparam N = 8; // data bus width in bytes |
localparam A = 32; // address bus width |
localparam I = 1; // ID width |
localparam D = 1; // TDEST width |
localparam U = N / BYTES_PER_TUSER; // TUSER width |
|
|
// -------------------------------------------------------------------- |
// |
class tb_axi4_to_axis_basic_dma_class |
extends tb_axi4_to_axis_agent_class #(N, A, I, D, U); |
|
|
//-------------------------------------------------------------------- |
// |
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 |
); |
|
super.new(.axi4_m(axi4_m), .axis_out(axis_out)); |
|
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: tb_axi4_to_axis_basic_dma_class |
|
// -------------------------------------------------------------------- |
// |
endpackage: tb_axi4_to_axis_basic_dma_pkg |
|
|
|
|
|
/sim/tests/tb_axi4_to_axis_basic_dma/the_test.sv
0,0 → 1,69
// -------------------------------------------------------------------- |
// |
// -------------------------------------------------------------------- |
|
`timescale 1ps/1ps |
|
|
module |
the_test( |
input tb_clk, |
input tb_rst |
); |
|
// -------------------------------------------------------------------- |
// |
import tb_axi4_to_axis_basic_dma_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
task run_the_test; |
|
// -------------------------------------------------------------------- |
// insert test below |
// -------------------------------------------------------------------- |
$display("^^^---------------------------------"); |
$display("^^^ %16.t | Testbench begun.", $time); |
$display("^^^---------------------------------"); |
|
// -------------------------------------------------------------------- |
tb_top.tb.timeout_stop(50us); |
// tb_top.a_h.m_h.counting_fill(0,'h800); |
|
// -------------------------------------------------------------------- |
wait(tb_top.aresetn); |
#200ns; |
|
// -------------------------------------------------------------------- |
tb_top.a_h.random_transaction(BASE_ADDRESS, BUFFER_SIZE); |
force tb_top.dma_enable = 1; |
repeat(2) tb_top.a_h.wait_for_sof(); |
tb_top.a_h.compare(); |
|
// -------------------------------------------------------------------- |
release tb_top.dma_enable; |
force tb_top.tb_rst = 1; |
#200ns; |
release tb_top.tb_rst; |
#200ns; |
|
// -------------------------------------------------------------------- |
tb_top.a_h.random_transaction(BASE_ADDRESS, BUFFER_SIZE); |
force tb_top.dma_enable = 1; |
repeat(2) tb_top.a_h.wait_for_sof(); |
tb_top.a_h.compare(); |
|
// -------------------------------------------------------------------- |
#200ns; |
|
|
// -------------------------------------------------------------------- |
// insert test above |
// -------------------------------------------------------------------- |
|
endtask |
|
|
endmodule |
|
/sim/tests/tb_axi4_to_axis_basic_dma/wip.do
0,0 → 1,11
# |
|
vlog -f ./tb_axi4_to_axis_basic_dma.f |
|
# simulation $root |
vlog ./tb_axi4_to_axis_basic_dma.sv |
|
# compile test last |
vlog ./the_test.sv |
|
|
/src/axi4_if.sv
38,51 → 38,273
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; |
wire [(A-1):0] araddr; |
wire [1:0] arburst; |
wire [3:0] arcache; |
wire [(I-1):0] arid; |
wire [7:0] arlen; |
wire arlock; |
wire [2:0] arprot; |
wire [3:0] arqos; |
wire arready; |
wire [3:0] arregion; |
wire [2:0] arsize; |
wire arvalid; |
wire [(A-1):0] awaddr; |
wire [1:0] awburst; |
wire [3:0] awcache; |
wire [(I-1):0] awid; |
wire [7:0] awlen; |
wire awlock; |
wire [2:0] awprot; |
wire [3:0] awqos; |
wire awready; |
wire [3:0] awregion; |
wire [2:0] awsize; |
wire awvalid; |
wire [(I-1):0] bid; |
wire bready; |
wire [1:0] bresp; |
wire bvalid; |
wire [(8*N)-1:0] rdata; |
wire [(I-1):0] rid; |
wire rlast; |
wire rready; |
wire [1:0] rresp; |
wire rvalid; |
wire [(8*N)-1:0] wdata; |
wire [(I-1):0] wid; |
wire wlast; |
wire wready; |
wire [N-1:0] wstrb; |
wire wvalid; |
|
|
// -------------------------------------------------------------------- |
// synthesis translate_off |
clocking cb_s @(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 |
|
|
// -------------------------------------------------------------------- |
// |
default clocking cb_m @(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 wid; |
output wlast; |
input wready; |
output wstrb; |
output wvalid; |
input aresetn; |
input aclk; |
endclocking |
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// |
`ifdef USE_MOD_PORTS |
// -------------------------------------------------------------------- |
// |
modport |
slave |
( |
// -------------------------------------------------------------------- |
// synthesis translate_off |
clocking cb_s, |
// synthesis translate_on |
// -------------------------------------------------------------------- |
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 |
); |
|
|
// -------------------------------------------------------------------- |
// |
modport |
master |
( |
// -------------------------------------------------------------------- |
// synthesis translate_off |
clocking cb_m, |
// synthesis translate_on |
// -------------------------------------------------------------------- |
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 |
); |
`endif |
|
|
// -------------------------------------------------------------------- |
// synthesis translate_off |
task |
zero_cycle_delay; |
|
##0; |
|
endtask: zero_cycle_delay |
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// |
|
endinterface |
|
|
/src/axi4_m_to_read_fifos.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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
module |
axi4_m_to_read_fifos |
#( |
A = 32, // address bus width |
N = 8, // data bus width in bytes |
I = 1, // ID width |
R_D = 32, |
AR_D = 2, |
WATERMARK = 0, |
USE_ADVANCED_PROTOCOL = 0 |
) |
( |
axi4_if axi4_m, |
axi4_if axi4_read_fifo, |
|
output ar_wr_full, |
input ar_wr_en, |
output r_rd_empty, |
input r_rd_en, |
output r_topped_off, |
output r_watermark, |
|
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// |
localparam UB = $clog2(R_D); |
|
|
// -------------------------------------------------------------------- |
// |
localparam R_W = |
8*N + // logic [(8*N)-1:0] rdata; |
I + // logic [(I-1):0] rid; |
1 + // logic rlast; |
2; // logic [1:0] rresp; |
|
localparam AX_BASIC_W = |
A + // logic [(A-1):0] axaddr; |
2 + // logic [1:0] axburst; |
I + // logic [(I-1):0] axid; |
8 + // logic [7:0] axlen; |
3; // logic [2:0] axsize; |
|
localparam AX_ADVANCED_W = |
4 + // logic [3:0] axcache; |
1 + // logic axlock; |
3 + // logic [2:0] axprot; |
4 + // logic [3:0] axqos; |
4; // logic [3:0] axregion; |
|
localparam AR_W = USE_ADVANCED_PROTOCOL ? AX_BASIC_W + AX_ADVANCED_W : AX_BASIC_W; |
|
|
// -------------------------------------------------------------------- |
// |
wire [AR_W-1:0] ar_rd_data; |
wire [AR_W-1:0] ar_wr_data; |
|
generate |
begin: ar_data_gen |
if(USE_ADVANCED_PROTOCOL) |
begin |
assign ar_wr_data = |
{ |
axi4_read_fifo.araddr, |
axi4_read_fifo.arburst, |
axi4_read_fifo.arid, |
axi4_read_fifo.arlen, |
axi4_read_fifo.arsize, |
axi4_read_fifo.arcache, |
axi4_read_fifo.arlock, |
axi4_read_fifo.arprot, |
axi4_read_fifo.arqos, |
axi4_read_fifo.arregion |
}; |
|
assign |
{ |
axi4_m.araddr, |
axi4_m.arburst, |
axi4_m.arid, |
axi4_m.arlen, |
axi4_m.arsize, |
axi4_m.arcache, |
axi4_m.arlock, |
axi4_m.arprot, |
axi4_m.arqos, |
axi4_m.arregion |
} = ar_rd_data; |
end |
else |
begin |
assign ar_wr_data = |
{ |
axi4_read_fifo.araddr, |
axi4_read_fifo.arburst, |
axi4_read_fifo.arid, |
axi4_read_fifo.arlen, |
axi4_read_fifo.arsize |
}; |
|
assign axi4_read_fifo.arcache = 0; |
assign axi4_read_fifo.arlock = 0; |
assign axi4_read_fifo.arprot = 0; |
assign axi4_read_fifo.arqos = 0; |
assign axi4_read_fifo.arregion = 0; |
|
assign |
{ |
axi4_m.araddr, |
axi4_m.arburst, |
axi4_m.arid, |
axi4_m.arlen, |
axi4_m.arsize |
} = ar_rd_data; |
|
assign axi4_m.arcache = 0; |
assign axi4_m.arlock = 0; |
assign axi4_m.arprot = 0; |
assign axi4_m.arqos = 0; |
assign axi4_m.arregion = 0; |
|
end |
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
wire ar_rd_empty; |
wire ar_rd_en = axi4_m.arready & axi4_m.arvalid; |
assign axi4_m.arvalid = ~ar_rd_empty; |
|
sync_fifo #(.W(AR_W), .D(AR_D)) |
ar_fifo |
( |
.wr_full(ar_wr_full), |
.wr_data(ar_wr_data), |
.wr_en(ar_wr_en), |
.rd_empty(ar_rd_empty), |
.rd_data(ar_rd_data), |
.rd_en(ar_rd_en), |
.count(), |
.clk(aclk), |
.reset(~aresetn) |
); |
|
|
// -------------------------------------------------------------------- |
// |
wire [R_W-1:0] r_rd_data; |
wire [R_W-1:0] r_wr_data; |
|
assign r_wr_data = |
{ |
axi4_m.rdata, |
axi4_m.rid, |
axi4_m.rlast, |
axi4_m.rresp |
}; |
|
assign |
{ |
axi4_read_fifo.rdata, |
axi4_read_fifo.rid, |
axi4_read_fifo.rlast, |
axi4_read_fifo.rresp |
} = r_rd_data; |
|
|
// -------------------------------------------------------------------- |
// |
wire [UB:0] r_count; |
|
generate |
begin: r_watermark_gen |
if(WATERMARK == 0) |
begin |
assign r_topped_off = 1; |
assign r_watermark = 0; |
end |
else |
begin |
reg r_topped_off_r; |
assign r_topped_off = r_topped_off_r; |
assign r_watermark = r_count > WATERMARK - 1; |
|
always_ff @(posedge aclk) |
if(~aresetn | r_rd_empty) |
r_topped_off_r <= 0; |
else if(r_watermark) |
r_topped_off_r <= 1; |
end |
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
wire r_wr_full; |
wire r_wr_en = axi4_m.rready & axi4_m.rvalid; |
assign axi4_m.rready = ~r_wr_full; |
|
sync_fifo #(.W(R_W), .D(R_D)) |
r_fifo |
( |
.wr_full(r_wr_full), |
.wr_data(r_wr_data), |
.wr_en(r_wr_en), |
.rd_empty(r_rd_empty), |
.rd_data(r_rd_data), |
.rd_en(r_rd_en), |
.count(r_count), |
.clk(aclk), |
.reset(~aresetn) |
); |
|
|
// -------------------------------------------------------------------- |
// |
|
endmodule |
|
/src/axi4_m_to_write_fifos.sv
0,0 → 1,282
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 |
axi4_m_to_write_fifos |
#( |
A = 32, // address bus width |
N = 8, // data bus width in bytes |
I = 1, // ID width |
W_D = 32, |
B_D = 2, |
AW_D = 2, |
WATERMARK = 0, |
USE_ADVANCED_PROTOCOL = 0 |
) |
( |
axi4_if axi4_m, |
axi4_if axi4_write_fifo, |
output aw_wr_full, |
input aw_wr_en, |
output w_wr_full, |
input w_wr_en, |
output w_topped_off, |
output w_watermark, |
output b_rd_empty, |
input b_rd_en, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// |
localparam UB = $clog2(W_D); |
|
|
// -------------------------------------------------------------------- |
// |
localparam W_W = |
8*N + // logic [(8*N)-1:0] wdata; |
I + // logic [(I-1):0] wid; |
1 + // logic wlast; |
N; // logic [N-1:0] wstrb; |
|
localparam B_W = |
I + // logic [(I-1):0] bid; |
2; // logic [1:0] bresp; |
|
localparam AX_BASIC_W = |
A + // logic [(A-1):0] axaddr; |
2 + // logic [1:0] axburst; |
I + // logic [(I-1):0] axid; |
8 + // logic [7:0] axlen; |
3; // logic [2:0] axsize; |
|
localparam AX_ADVANCED_W = |
4 + // logic [3:0] axcache; |
1 + // logic axlock; |
3 + // logic [2:0] axprot; |
4 + // logic [3:0] axqos; |
4; // logic [3:0] axregion; |
|
localparam AW_W = USE_ADVANCED_PROTOCOL ? AX_BASIC_W + AX_ADVANCED_W : AX_BASIC_W; |
|
|
// -------------------------------------------------------------------- |
// |
wire [AW_W-1:0] aw_rd_data; |
wire [AW_W-1:0] aw_wr_data; |
|
generate |
begin: aw_data_gen |
if(USE_ADVANCED_PROTOCOL) |
begin |
assign aw_wr_data = |
{ |
axi4_write_fifo.awaddr, |
axi4_write_fifo.awburst, |
axi4_write_fifo.awid, |
axi4_write_fifo.awlen, |
axi4_write_fifo.awsize, |
axi4_write_fifo.awcache, |
axi4_write_fifo.awlock, |
axi4_write_fifo.awprot, |
axi4_write_fifo.awqos, |
axi4_write_fifo.awregion |
}; |
|
assign |
{ |
axi4_m.awaddr, |
axi4_m.awburst, |
axi4_m.awid, |
axi4_m.awlen, |
axi4_m.awsize, |
axi4_m.awcache, |
axi4_m.awlock, |
axi4_m.awprot, |
axi4_m.awqos, |
axi4_m.awregion |
} = aw_rd_data; |
end |
else |
begin |
assign aw_wr_data = |
{ |
axi4_write_fifo.awaddr, |
axi4_write_fifo.awburst, |
axi4_write_fifo.awid, |
axi4_write_fifo.awlen, |
axi4_write_fifo.awsize |
}; |
|
assign |
{ |
axi4_m.awaddr, |
axi4_m.awburst, |
axi4_m.awid, |
axi4_m.awlen, |
axi4_m.awsize |
} = aw_rd_data; |
end |
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
wire aw_rd_empty; |
wire aw_rd_en = axi4_m.awready & axi4_m.awvalid; |
assign axi4_m.awvalid = ~aw_rd_empty; |
|
sync_fifo #(.W(AW_W), .D(AW_D)) |
aw_fifo |
( |
.wr_full(aw_wr_full), |
.wr_data(aw_wr_data), |
.wr_en(aw_wr_en), |
.rd_empty(aw_rd_empty), |
.rd_data(aw_rd_data), |
.rd_en(aw_rd_en), |
.count(), |
.clk(aclk), |
.reset(~aresetn) |
); |
|
|
// -------------------------------------------------------------------- |
// |
wire [W_W-1:0] w_rd_data; |
wire [W_W-1:0] w_wr_data; |
|
assign w_wr_data = |
{ |
axi4_write_fifo.wdata, |
axi4_write_fifo.wid, |
axi4_write_fifo.wlast, |
axi4_write_fifo.wstrb |
}; |
|
assign |
{ |
axi4_m.wdata, |
axi4_m.wid, |
axi4_m.wlast, |
axi4_m.wstrb |
} = w_rd_data; |
|
|
// -------------------------------------------------------------------- |
// |
wire [UB:0] w_count; |
wire w_rd_empty; |
wire w_rd_en = axi4_m.wready & axi4_m.wvalid; |
assign axi4_m.wvalid = ~w_rd_empty; |
|
sync_fifo #(.W(W_W), .D(W_D)) |
w_fifo |
( |
.wr_full(w_wr_full), |
.wr_data(w_wr_data), |
.wr_en(w_wr_en), |
.rd_empty(w_rd_empty), |
.rd_data(w_rd_data), |
.rd_en(w_rd_en), |
.count(w_count), |
.clk(aclk), |
.reset(~aresetn) |
); |
|
|
// -------------------------------------------------------------------- |
// |
generate |
begin: w_watermark_gen |
if(WATERMARK == 0) |
begin |
assign w_topped_off = 1; |
assign w_watermark = 0; |
end |
else |
begin |
reg w_topped_off_r; |
assign w_topped_off = w_topped_off_r; |
assign w_watermark = w_count > WATERMARK - 1; |
|
always_ff @(posedge aclk) |
if(~aresetn | w_rd_empty) |
w_topped_off_r <= 0; |
else if(w_watermark) |
w_topped_off_r <= 1; |
end |
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
wire [B_W-1:0] b_rd_data; |
wire [B_W-1:0] b_wr_data; |
|
assign b_wr_data = |
{ |
axi4_m.bid, |
axi4_m.bresp |
}; |
|
assign |
{ |
axi4_write_fifo.bid, |
axi4_write_fifo.bresp |
} = b_rd_data; |
|
|
// -------------------------------------------------------------------- |
// |
wire b_wr_full; |
wire b_wr_en = axi4_m.bready & axi4_m.bvalid; |
assign axi4_m.bready = ~b_wr_full; |
|
sync_fifo #(.W(B_W), .D(B_D)) |
b_fifo |
( |
.wr_full(b_wr_full), |
.wr_data(b_wr_data), |
.wr_en(b_wr_en), |
.rd_empty(b_rd_empty), |
.rd_data(b_rd_data), |
.rd_en(b_rd_en), |
.count(), |
.clk(aclk), |
.reset(~aresetn) |
); |
|
|
// -------------------------------------------------------------------- |
// |
endmodule |
|
/src/axi4_register_slice.sv
53,14 → 53,16
|
// -------------------------------------------------------------------- |
// |
axi4_to_read_fifos |
axi4_s_to_read_fifos |
#( |
.A(A), |
.N(N), |
.I(I), |
.R_D(2), |
.AR_D(2), |
.USE_ADVANCED_PROTOCOL(USE_ADVANCED_PROTOCOL) |
) |
axi4_to_read_fifos_i(.*); |
axi4_s_to_read_fifos_i(.*); |
|
|
// -------------------------------------------------------------------- |
118,14 → 120,17
|
// -------------------------------------------------------------------- |
// |
axi4_to_write_fifos |
axi4_s_to_write_fifos |
#( |
.A(A), |
.N(N), |
.I(I), |
.W_D(2), |
.B_D(2), |
.AW_D(2), |
.USE_ADVANCED_PROTOCOL(USE_ADVANCED_PROTOCOL) |
) |
axi4_to_write_fifos_i(.*); |
axi4_s_to_write_fifos_i(.*); |
|
|
// -------------------------------------------------------------------- |
/src/axi4_s_to_read_fifos.sv
0,0 → 1,205
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 |
axi4_s_to_read_fifos |
#( |
A = 32, // address bus width |
N = 8, // data bus width in bytes |
I = 1, // ID width |
R_D = 32, |
AR_D = 2, |
USE_ADVANCED_PROTOCOL = 0 |
) |
( |
axi4_if axi4_s, |
axi4_if axi4_read_fifo, |
|
output ar_rd_empty, |
input ar_rd_en, |
output r_wr_full, |
input r_wr_en, |
|
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// |
localparam R_W = |
8*N + // logic [(8*N)-1:0] rdata; |
I + // logic [(I-1):0] rid; |
1 + // logic rlast; |
2; // logic [1:0] rresp; |
|
localparam AX_BASIC_W = |
A + // logic [(A-1):0] axaddr; |
2 + // logic [1:0] axburst; |
I + // logic [(I-1):0] axid; |
8 + // logic [7:0] axlen; |
3; // logic [2:0] axsize; |
|
localparam AX_ADVANCED_W = |
4 + // logic [3:0] axcache; |
1 + // logic axlock; |
3 + // logic [2:0] axprot; |
4 + // logic [3:0] axqos; |
4; // logic [3:0] axregion; |
|
localparam AR_W = USE_ADVANCED_PROTOCOL ? AX_BASIC_W + AX_ADVANCED_W : AX_BASIC_W; |
|
|
// -------------------------------------------------------------------- |
// |
wire [AR_W-1:0] ar_rd_data; |
wire [AR_W-1:0] ar_wr_data; |
|
generate |
begin: ar_data_gen |
if(USE_ADVANCED_PROTOCOL) |
begin |
assign ar_wr_data = |
{ |
axi4_s.araddr, |
axi4_s.arburst, |
axi4_s.arid, |
axi4_s.arlen, |
axi4_s.arsize, |
axi4_s.arcache, |
axi4_s.arlock, |
axi4_s.arprot, |
axi4_s.arqos, |
axi4_s.arregion |
}; |
|
assign |
{ |
axi4_read_fifo.araddr, |
axi4_read_fifo.arburst, |
axi4_read_fifo.arid, |
axi4_read_fifo.arlen, |
axi4_read_fifo.arsize, |
axi4_read_fifo.arcache, |
axi4_read_fifo.arlock, |
axi4_read_fifo.arprot, |
axi4_read_fifo.arqos, |
axi4_read_fifo.arregion |
} = ar_rd_data; |
end |
else |
begin |
assign ar_wr_data = |
{ |
axi4_s.araddr, |
axi4_s.arburst, |
axi4_s.arid, |
axi4_s.arlen, |
axi4_s.arsize |
}; |
|
assign |
{ |
axi4_read_fifo.araddr, |
axi4_read_fifo.arburst, |
axi4_read_fifo.arid, |
axi4_read_fifo.arlen, |
axi4_read_fifo.arsize |
} = ar_rd_data; |
end |
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
wire ar_wr_full; |
wire ar_wr_en = axi4_s.arready & axi4_s.arvalid; |
assign axi4_s.arready = ~ar_wr_full; |
|
sync_fifo #(.W(AR_W), .D(AR_D)) |
ar_fifo |
( |
.wr_full(ar_wr_full), |
.wr_data(ar_wr_data), |
.wr_en(ar_wr_en), |
.rd_empty(ar_rd_empty), |
.rd_data(ar_rd_data), |
.rd_en(ar_rd_en), |
.count(), |
.clk(aclk), |
.reset(~aresetn) |
); |
|
|
// -------------------------------------------------------------------- |
// |
wire [R_W-1:0] r_rd_data; |
wire [R_W-1:0] r_wr_data; |
|
assign r_wr_data = |
{ |
axi4_read_fifo.rdata, |
axi4_read_fifo.rid, |
axi4_read_fifo.rlast, |
axi4_read_fifo.rresp |
}; |
|
assign |
{ |
axi4_s.rdata, |
axi4_s.rid, |
axi4_s.rlast, |
axi4_s.rresp |
} = r_rd_data; |
|
|
// -------------------------------------------------------------------- |
// |
wire r_rd_empty; |
wire r_rd_en = axi4_s.rready & axi4_s.rvalid; |
assign axi4_s.rvalid = ~r_rd_empty; |
|
sync_fifo #(.W(R_W), .D(R_D)) |
r_fifo |
( |
.wr_full(r_wr_full), |
.wr_data(r_wr_data), |
.wr_en(r_wr_en), |
.rd_empty(r_rd_empty), |
.rd_data(r_rd_data), |
.rd_en(r_rd_en), |
.count(), |
.clk(aclk), |
.reset(~aresetn) |
); |
|
|
// -------------------------------------------------------------------- |
// |
|
endmodule |
|
/src/axi4_s_to_write_fifos.sv
0,0 → 1,252
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 |
axi4_s_to_write_fifos |
#( |
A = 32, // address bus width |
N = 8, // data bus width in bytes |
I = 1, // ID width |
W_D = 32, |
B_D = 2, |
AW_D = 2, |
|
USE_ADVANCED_PROTOCOL = 0 |
) |
( |
axi4_if axi4_s, |
axi4_if axi4_write_fifo, |
|
output aw_rd_empty, |
input aw_rd_en, |
output w_rd_empty, |
input w_rd_en, |
output b_wr_full, |
input b_wr_en, |
|
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// |
localparam W_W = |
8*N + // logic [(8*N)-1:0] wdata; |
I + // logic [(I-1):0] wid; |
1 + // logic wlast; |
N; // logic [N-1:0] wstrb; |
|
localparam B_W = |
I + // logic [(I-1):0] bid; |
2; // logic [1:0] bresp; |
|
localparam AX_BASIC_W = |
A + // logic [(A-1):0] axaddr; |
2 + // logic [1:0] axburst; |
I + // logic [(I-1):0] axid; |
8 + // logic [7:0] axlen; |
3; // logic [2:0] axsize; |
|
localparam AX_ADVANCED_W = |
4 + // logic [3:0] axcache; |
1 + // logic axlock; |
3 + // logic [2:0] axprot; |
4 + // logic [3:0] axqos; |
4; // logic [3:0] axregion; |
|
localparam AW_W = USE_ADVANCED_PROTOCOL ? AX_BASIC_W + AX_ADVANCED_W : AX_BASIC_W; |
|
|
// -------------------------------------------------------------------- |
// |
wire [AW_W-1:0] aw_rd_data; |
wire [AW_W-1:0] aw_wr_data; |
|
generate |
begin: aw_data_gen |
if(USE_ADVANCED_PROTOCOL) |
begin |
assign aw_wr_data = |
{ |
axi4_s.awaddr, |
axi4_s.awburst, |
axi4_s.awid, |
axi4_s.awlen, |
axi4_s.awsize, |
axi4_s.awcache, |
axi4_s.awlock, |
axi4_s.awprot, |
axi4_s.awqos, |
axi4_s.awregion |
}; |
|
assign |
{ |
axi4_write_fifo.awaddr, |
axi4_write_fifo.awburst, |
axi4_write_fifo.awid, |
axi4_write_fifo.awlen, |
axi4_write_fifo.awsize, |
axi4_write_fifo.awcache, |
axi4_write_fifo.awlock, |
axi4_write_fifo.awprot, |
axi4_write_fifo.awqos, |
axi4_write_fifo.awregion |
} = aw_rd_data; |
end |
else |
begin |
assign aw_wr_data = |
{ |
axi4_s.awaddr, |
axi4_s.awburst, |
axi4_s.awid, |
axi4_s.awlen, |
axi4_s.awsize |
}; |
|
assign |
{ |
axi4_write_fifo.awaddr, |
axi4_write_fifo.awburst, |
axi4_write_fifo.awid, |
axi4_write_fifo.awlen, |
axi4_write_fifo.awsize |
} = aw_rd_data; |
end |
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
wire aw_wr_full; |
wire aw_wr_en = axi4_s.awready & axi4_s.awvalid; |
assign axi4_s.awready = ~aw_wr_full; |
|
sync_fifo #(.W(AW_W), .D(AW_D)) |
aw_fifo |
( |
.wr_full(aw_wr_full), |
.wr_data(aw_wr_data), |
.wr_en(aw_wr_en), |
.rd_empty(aw_rd_empty), |
.rd_data(aw_rd_data), |
.rd_en(aw_rd_en), |
.count(), |
.clk(aclk), |
.reset(~aresetn) |
); |
|
|
// -------------------------------------------------------------------- |
// |
wire [W_W-1:0] w_rd_data; |
wire [W_W-1:0] w_wr_data; |
|
assign w_wr_data = |
{ |
axi4_s.wdata, |
axi4_s.wid, |
axi4_s.wlast, |
axi4_s.wstrb |
}; |
|
assign |
{ |
axi4_write_fifo.wdata, |
axi4_write_fifo.wid, |
axi4_write_fifo.wlast, |
axi4_write_fifo.wstrb |
} = w_rd_data; |
|
|
// -------------------------------------------------------------------- |
// |
wire w_wr_full; |
wire w_wr_en = axi4_s.wready & axi4_s.wvalid; |
assign axi4_s.wready = ~w_wr_full; |
|
sync_fifo #(.W(W_W), .D(W_D)) |
w_fifo |
( |
.wr_full(w_wr_full), |
.wr_data(w_wr_data), |
.wr_en(w_wr_en), |
.rd_empty(w_rd_empty), |
.rd_data(w_rd_data), |
.rd_en(w_rd_en), |
.count(), |
.clk(aclk), |
.reset(~aresetn) |
); |
|
|
// -------------------------------------------------------------------- |
// |
wire [B_W-1:0] b_rd_data; |
wire [B_W-1:0] b_wr_data; |
|
assign b_wr_data = |
{ |
axi4_write_fifo.bid, |
axi4_write_fifo.bresp |
}; |
|
assign |
{ |
axi4_s.bid, |
axi4_s.bresp |
} = b_rd_data; |
|
|
// -------------------------------------------------------------------- |
// |
wire b_rd_empty; |
wire b_rd_en = axi4_s.bready & axi4_s.bvalid; |
assign axi4_s.bvalid = ~b_rd_empty; |
|
sync_fifo #(.W(B_W), .D(B_D)) |
b_fifo |
( |
.wr_full(b_wr_full), |
.wr_data(b_wr_data), |
.wr_en(b_wr_en), |
.rd_empty(b_rd_empty), |
.rd_data(b_rd_data), |
.rd_en(b_rd_en), |
.count(), |
.clk(aclk), |
.reset(~aresetn) |
); |
|
|
// -------------------------------------------------------------------- |
// |
|
endmodule |
|
/src/axi4_to_axis_basic_dma.sv
0,0 → 1,170
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 |
axi4_to_axis_basic_dma |
#( |
A, // address bus width |
N, // data bus width in bytes |
I, // ID width |
BASE_ADDRESS, // must be on 4K boundry |
BUFFER_SIZE, |
BURST_LENGTH, |
MAX_BURSTS, // max number of burst the FIFO can hold |
BYTES_PER_TUSER = 0 // bytes per tuser bit . Set to 0 for transfer based. |
) |
( |
axi4_if axi4_m, |
axis_if axis_out, |
input dma_enable, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// |
localparam R_D = BURST_LENGTH * MAX_BURSTS; |
localparam AR_D = 2; |
localparam WATERMARK = BURST_LENGTH * (MAX_BURSTS - AR_D); |
localparam STRIDE = N * BURST_LENGTH; |
localparam ADDRESS_END = BASE_ADDRESS + BUFFER_SIZE; |
localparam AR_STOP = (BUFFER_SIZE % STRIDE) ? ADDRESS_END - STRIDE : ADDRESS_END; |
localparam R_STOP = (BUFFER_SIZE % N) ? ADDRESS_END - N : ADDRESS_END; |
localparam U = N / BYTES_PER_TUSER; |
|
|
// -------------------------------------------------------------------- |
// synthesis translate_off |
localparam N_4K = 'h1000 / 'h8; // number of bytes in 4K |
initial |
begin |
a_4k_mod_base_address: assert(BASE_ADDRESS % 'h1000 == 0) else $fatal; |
a_4k_gt_eq_stride: assert(N_4K >= STRIDE) else $fatal; |
a_4k_mod_stride: assert('h1000 % STRIDE == 0) else $fatal; |
a_n: assert((N % BYTES_PER_TUSER == 0)) else $fatal; |
a_buffer_size: assert(BUFFER_SIZE % N == 0) else $fatal; |
a_bytes_per_tuser: assert(BYTES_PER_TUSER != 0) else $fatal; // need to fix |
end |
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// |
axi4_if #(.A(A), .N(N), .I(I)) axi4_read_fifo(.*); |
axis_if #(.N(N), .U(U)) axis_in(.*); |
|
|
// -------------------------------------------------------------------- |
// |
reg [(A-1):0] araddr_r; |
wire araddr_en = (araddr_r < AR_STOP); |
wire r_watermark; |
wire ar_wr_full; |
wire ar_wr_en = ~ar_wr_full & ~r_watermark & araddr_en & dma_enable; |
|
always_ff @(posedge aclk) |
if(~aresetn | ~araddr_en) |
araddr_r <= BASE_ADDRESS; |
else if(ar_wr_en) |
araddr_r <= araddr_r + STRIDE; |
|
|
// -------------------------------------------------------------------- |
// |
reg [(A-1):0] r_rd_addr; |
wire r_rd_addr_en = (r_rd_addr < R_STOP); |
wire r_rd_addr_start = (r_rd_addr == BASE_ADDRESS); |
wire r_rd_addr_end = (r_rd_addr == R_STOP); |
wire r_rd_empty; |
wire r_topped_off; |
wire r_rd_en = ~r_rd_empty & r_rd_addr_en & axis_in.tready; |
|
always_ff @(posedge aclk) |
if(~aresetn | ~r_rd_addr_en) |
r_rd_addr <= BASE_ADDRESS; |
else if(r_rd_en) |
r_rd_addr <= r_rd_addr + N; |
|
|
// -------------------------------------------------------------------- |
// |
axi4_m_to_read_fifos #(.A(A), .N(N), .I(I), .R_D(R_D), .AR_D(AR_D), .WATERMARK(WATERMARK)) |
axi4_m_to_read_fifos_i(.*); |
|
|
// -------------------------------------------------------------------- |
// |
assign axi4_read_fifo.araddr = araddr_r; |
assign axi4_read_fifo.arid = 0; |
assign axi4_read_fifo.arburst = 2'b01; |
assign axi4_read_fifo.arsize = $clog2(N); |
assign axi4_read_fifo.arlen = BURST_LENGTH - 1; |
assign axi4_read_fifo.rready = 1; |
|
|
// -------------------------------------------------------------------- |
// |
assign axi4_m.awaddr = 0; |
assign axi4_m.awburst = 0; |
assign axi4_m.awcache = 0; |
assign axi4_m.awid = 0; |
assign axi4_m.awlen = 0; |
assign axi4_m.awlock = 0; |
assign axi4_m.awprot = 0; |
assign axi4_m.awqos = 0; |
assign axi4_m.awregion = 0; |
assign axi4_m.awsize = 0; |
assign axi4_m.awvalid = 0; |
assign axi4_m.bready = 0; |
assign axi4_m.wdata = 0; |
assign axi4_m.wid = 0; |
assign axi4_m.wlast = 0; |
assign axi4_m.wstrb = 0; |
assign axi4_m.wvalid = 0; |
|
|
// -------------------------------------------------------------------- |
// |
assign axis_in.tvalid = ~r_rd_empty; |
assign axis_in.tdata = axi4_read_fifo.rdata; |
assign axis_in.tlast = axi4_read_fifo.rlast; |
assign axis_in.tuser[0] = r_rd_addr_start; |
assign axis_in.tuser[U-1:1] = 0; // need to fix |
|
|
// -------------------------------------------------------------------- |
// |
axis_register_slice #(.N(N), .U(U)) |
axis_register_slice_i(.*); |
|
|
// -------------------------------------------------------------------- |
// |
endmodule |
|