URL
https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk
Subversion Repositories qaz_libs
[/] [qaz_libs/] [trunk/] [axi4_lib/] [sim/] [src/] [legacy/] [axi4_models/] [axi4_arbiter_pkg.sv] - Rev 45
Compare with Previous | Blame | View Log
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2015 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
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