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/avalon_lib
- from Rev 29 to Rev 31
- ↔ Reverse comparison
Rev 29 → Rev 31
/sim/src/amm_bfm/amm_master_bfm_if.sv
0,0 → 1,140
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2015 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
|
interface |
amm_master_bfm_if |
#( |
A = 32, // address bus width |
N = 8 // data bus width in bytes |
) |
( |
amm_if amm_s, |
input reset, |
input clk |
); |
|
logic [(A-1):0] address; |
logic read; |
logic [(8*N)-1:0] readdata; |
logic write; |
logic [(8*N)-1:0] writedata; |
logic [N-1:0] byteenable; |
logic waitrequest; |
logic arbiterlock; |
logic readdatavalid; |
logic [6:0] burstcount; |
logic resetrequest; |
|
|
// -------------------------------------------------------------------- |
// |
default clocking cb @(posedge clk); |
output address; |
output read; |
input readdata; |
output write; |
output writedata; |
output byteenable; |
input waitrequest; |
output arbiterlock; |
input readdatavalid; |
output burstcount; |
output resetrequest; |
input reset; |
input clk; |
endclocking |
|
|
// -------------------------------------------------------------------- |
// |
assign amm_s.address = address; |
assign amm_s.read = read; |
assign readdata = amm_s.readdata; |
assign amm_s.write = write; |
assign amm_s.writedata = writedata; |
assign amm_s.byteenable = byteenable; |
assign waitrequest = amm_s.waitrequest; |
assign amm_s.arbiterlock = arbiterlock; |
assign readdatavalid = amm_s.readdatavalid; |
assign amm_s.burstcount = burstcount; |
assign amm_s.resetrequest = resetrequest; |
|
|
// -------------------------------------------------------------------- |
// |
function void |
amm_default; |
|
address = 'bx; |
arbiterlock = 0; |
burstcount = 'bx; |
byteenable = 'bx; |
read = 0; |
resetrequest = 0; |
write = 0; |
writedata = 'bx; |
|
endfunction: amm_default |
|
|
// -------------------------------------------------------------------- |
// |
function void |
init; |
|
amm_default(); |
|
endfunction: init |
|
|
// -------------------------------------------------------------------- |
// |
task |
zero_cycle_delay; |
|
##0; |
|
endtask: zero_cycle_delay |
|
|
// -------------------------------------------------------------------- |
// |
initial |
begin |
|
init(); |
|
end |
|
|
// -------------------------------------------------------------------- |
// |
|
endinterface |
|
|
/sim/src/amm_bfm/amm_slave_bfm_if.sv
0,0 → 1,292
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2015 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
|
interface |
amm_slave_bfm_if |
#( |
A = 32, // address bus width |
N = 8 // data bus width in bytes |
) |
( |
amm_if amm_m, |
output reset, |
output clk |
); |
|
logic [(A-1):0] address; |
logic read; |
logic [(8*N)-1:0] readdata; |
logic write; |
logic [(8*N)-1:0] writedata; |
logic [N-1:0] byteenable; |
logic begintransfer; |
logic waitrequest; |
logic arbiterlock; |
logic readdatavalid; |
logic [6:0] burstcount; |
logic beginbursttransfer; |
logic readyfordata; |
logic dataavailable; |
logic resetrequest; |
|
|
// -------------------------------------------------------------------- |
// |
default clocking cb @(posedge clk); |
input address; |
input read; |
output readdata; |
input write; |
input writedata; |
input byteenable; |
input begintransfer; |
output waitrequest; |
input arbiterlock; |
output readdatavalid; |
input burstcount; |
input beginbursttransfer; |
output readyfordata; |
output dataavailable; |
output resetrequest; |
input reset; |
input clk; |
endclocking |
|
|
// -------------------------------------------------------------------- |
// |
assign address = amm_m.address; |
assign read = amm_m.read; |
assign amm_m.readdata = readdata; |
assign write = amm_m.write; |
assign writedata = amm_m.writedata; |
assign byteenable = amm_m.byteenable; |
assign begintransfer = amm_m.begintransfer; |
assign amm_m.waitrequest = waitrequest; |
assign arbiterlock = amm_m.arbiterlock; |
assign amm_m.readdatavalid = readdatavalid; |
assign burstcount = amm_m.burstcount; |
assign beginbursttransfer = amm_m.beginbursttransfer; |
assign amm_m.readyfordata = readyfordata; |
assign amm_m.dataavailable = dataavailable; |
assign amm_m.resetrequest = resetrequest; |
|
|
// -------------------------------------------------------------------- |
// |
function void |
set_address_default; |
|
waitrequest = 1; |
|
endfunction: set_address_default |
|
|
// -------------------------------------------------------------------- |
// |
function void |
set_data_default; |
|
readdata = 'bx; |
readdatavalid = 0; |
|
endfunction: set_data_default |
|
|
// -------------------------------------------------------------------- |
// |
function void |
init; |
|
readyfordata = 'bz; |
dataavailable = 'bz; |
resetrequest = 'bz; |
|
set_address_default(); |
set_data_default(); |
|
endfunction: init |
|
|
// -------------------------------------------------------------------- |
// |
task |
zero_cycle_delay; |
|
##0; |
|
endtask: zero_cycle_delay |
|
|
// -------------------------------------------------------------------- |
// |
import q_pkg::*; |
import axi4_transaction_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
class slave_write_transaction_class #(A = 32, N = 8, I = 1) |
extends blocking_transmission_q_class #(axi4_transaction_class); |
|
// -------------------------------------------------------------------- |
// |
task automatic |
transmit |
( |
ref T tr_h |
); |
|
->this.start; |
|
foreach(tr_h.payload_h.w[i]) |
begin |
##(tr_h.delay_h.next()); |
|
cb.waitrequest <= 0; |
##1; |
wait(cb.write); |
$display("^^^ %16.t | %m | AMM slave write | %0d | 0x%016x |", $time, i, tr_h.payload_h.w[i]); |
cb.waitrequest <= 1; |
end |
|
set_address_default(); |
set_data_default(); |
|
->this.done; |
|
endtask: transmit |
|
|
// -------------------------------------------------------------------- |
// |
endclass: slave_write_transaction_class |
|
|
// -------------------------------------------------------------------- |
// |
class slave_read_data_transaction_class #(A = 32, N = 8, I = 1) |
extends blocking_transmission_q_class #(axi4_transaction_class); |
|
// -------------------------------------------------------------------- |
// |
task automatic |
transmit |
( |
ref T tr_h |
); |
|
->this.start; |
|
foreach(tr_h.payload_h.w[i]) |
begin |
if(tr_h.payload_h.w.size > 1) |
##1; // slave burst response must be at lease one cycle after read address phase |
|
##(tr_h.delay_h.next()); |
|
cb.readdata <= tr_h.payload_h.w[i]; |
cb.readdatavalid <= 1; |
##1; |
$display("^^^ %16.t | %m | AMM slave read data | %0d of %0d | 0x%016x |", $time, i + 1, tr_h.payload_h.w.size, tr_h.payload_h.w[i]); |
cb.readdatavalid <= 0; |
cb.readdata <= 'bx; |
end |
|
set_data_default(); |
|
->this.done; |
|
endtask: transmit |
|
// -------------------------------------------------------------------- |
// |
endclass: slave_read_data_transaction_class |
|
|
// -------------------------------------------------------------------- |
// |
slave_read_data_transaction_class #(.A(A), .N(N), .I(1)) r_h; |
|
class slave_read_address_transaction_class #(A = 32, N = 8, I = 1) |
extends blocking_transmission_q_class #(axi4_transaction_class); |
|
// -------------------------------------------------------------------- |
// |
task automatic |
transmit |
( |
ref T tr_h |
); |
|
->this.start; |
|
##(tr_h.delay_h.next()); |
cb.waitrequest <= 0; |
##1; |
|
wait(cb.read) |
##0; |
$display("^^^ %16.t | %m | AMM slave read address | 0x%08x | %0d |", $time, tr_h.addr, tr_h.len + 1); |
|
r_h.put(tr_h); |
|
set_address_default(); |
->this.done; |
|
endtask: transmit |
|
|
// -------------------------------------------------------------------- |
// |
endclass: slave_read_address_transaction_class |
|
|
// -------------------------------------------------------------------- |
// |
slave_write_transaction_class #(.A(A), .N(N), .I(1)) w_h; |
slave_read_address_transaction_class #(.A(A), .N(N), .I(1)) ar_h; |
|
initial |
begin |
init(); |
w_h = new; |
w_h.init(); |
ar_h = new; |
ar_h.init(); |
r_h = new; |
r_h.init(); |
end |
|
|
// -------------------------------------------------------------------- |
// |
|
endinterface |
|
|
/sim/src/amm_bfm/amm_transaction_pkg.sv
0,0 → 1,224
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 amm_transaction_pkg; |
|
// -------------------------------------------------------------------- |
// |
class amm_delay_class; |
|
rand int unsigned delay; |
|
|
// -------------------------------------------------------------------- |
// |
function int unsigned |
next; |
|
assert(this.randomize() with{delay dist {0 := 40, [1:3] := 40, [4:7] := 20};}); |
return(delay); |
|
endfunction: next |
|
|
// -------------------------------------------------------------------- |
// |
endclass: amm_delay_class |
|
|
// -------------------------------------------------------------------- |
// |
class amm_payload_class #(N = 8, B = 1); |
|
rand logic [(8*N)-1:0] w[]; |
|
|
// -------------------------------------------------------------------- |
// |
function |
new |
( |
logic [B-1:0] burstcount = 0 |
); |
|
this.w = new[burstcount + 1]; |
|
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
function void |
random |
( |
logic [B-1:0] burstcount = 0 |
); |
|
this.w = new[burstcount + 1]; |
assert(this.randomize()); |
|
endfunction: random |
|
|
// -------------------------------------------------------------------- |
// |
endclass: amm_payload_class |
|
|
// -------------------------------------------------------------------- |
// |
class amm_transaction_class #(A = 32, N = 8, B = 1); |
|
amm_delay_class delay_h; |
amm_payload_class #(.N(N), .B(B)) payload_h; |
amm_payload_class #(.N(N), .B(B)) data_h; |
rand logic [(A-1):0] address = 'bz; |
rand logic [N-1:0] byteenable = {N{1'b1}}; |
rand logic [B-1:0] burstcount = 1; |
|
constraint default_burstcount |
{ |
burstcount dist {0 := 40, [1:15] := 40, [16:255] := 20}; |
} |
|
|
// -------------------------------------------------------------------- |
// |
function |
new |
( |
logic [B-1:0] burstcount = 0 |
); |
|
this.payload_h = new(burstcount + 1); |
this.delay_h = new; |
|
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
function void |
basic_random; |
|
assert(this.randomize() with |
{ |
this.burstcount == 1; |
}); |
|
this.payload_h.random(this.burstcount); |
|
endfunction: basic_random |
|
|
// // -------------------------------------------------------------------- |
// // |
// function void |
// basic_random_burst; |
|
// assert(this.randomize() with |
// { |
// this.addr[$clog2(N*8)-1:0] == 0; |
// this.id == 0; |
// this.resp == 0; |
// this.burst == 2'b01; |
// this.size == $clog2(N); |
// this.len dist {0 := 40, [1:3] := 40, [4:15] := 20}; |
// }); |
|
// this.payload_h.random(this.len); |
|
// endfunction: basic_random_burst |
|
|
// -------------------------------------------------------------------- |
// |
function void |
basic_read |
( |
logic [(A-1):0] address, |
logic [B-1:0] burstcount = 1 |
); |
|
this.address = address; |
this.burstcount = burstcount; |
this.payload_h.random(burstcount); |
|
endfunction: basic_read |
|
|
// -------------------------------------------------------------------- |
// |
function void |
basic_write |
( |
logic [(A-1):0] address, |
logic [B-1:0] burstcount = 1 |
); |
|
this.address = address; |
this.burstcount = burstcount; |
this.payload_h.random(burstcount); |
|
endfunction: basic_write |
|
|
// -------------------------------------------------------------------- |
// |
function void copy |
( |
amm_transaction_class #(.A(A), .N(N), .B(B)) from |
); |
|
this.address = from.address; |
this.byteenable = from.byteenable; |
this.burstcount = from.burstcount; |
|
endfunction: copy |
|
|
// -------------------------------------------------------------------- |
// |
virtual function amm_transaction_class #(.A(A), .N(N), .B(B)) clone; |
|
clone = new(); |
clone.copy(this); |
return(clone); |
|
endfunction: clone |
|
|
// -------------------------------------------------------------------- |
// |
endclass: amm_transaction_class |
|
|
// -------------------------------------------------------------------- |
// |
endpackage: amm_transaction_pkg |
|
/sim/src/amm_monitor/altera_avalon_mm_monitor.sv
0,0 → 1,866
// (C) 2001-2016 Intel Corporation. All rights reserved. |
// Your use of Intel Corporation's design tools, logic functions and other |
// software and tools, and its AMPP partner logic functions, and any output |
// files any of the foregoing (including device programming or simulation |
// files), and any associated documentation or information are expressly subject |
// to the terms and conditions of the Intel Program License Subscription |
// Agreement, Intel MegaCore Function License Agreement, or other applicable |
// license agreement, including, without limitation, that your use is for the |
// sole purpose of programming logic devices manufactured by Intel and sold by |
// Intel or its authorized distributors. Please refer to the applicable |
// agreement for further details. |
|
|
// $Id: //acds/rel/16.1/ip/sopc/components/verification/altera_avalon_mm_monitor_bfm/altera_avalon_mm_monitor.sv#1 $ |
// $Revision: #1 $ |
// $Date: 2016/08/07 $ |
//----------------------------------------------------------------------------- |
// =head1 NAME |
// altera_avalon_mm_monitor |
// =head1 SYNOPSIS |
// Bridge with Avalon Bus Protocol Assertion Checker |
// The macro DISABLE_ALTERA_AVALON_SIM_SVA is defined to disable SVA processing |
// The macro ALTERA_AVALON_SIM_MTI must be defined to enable transaction tracing |
// The macro ENABLE_ALTERA_AVALON_TRANSACTION_RECORDING must be defined to |
// enable transaction monitoring |
//----------------------------------------------------------------------------- |
|
`timescale 1ps / 1ps |
|
module altera_avalon_mm_monitor( |
clk, |
reset, |
|
avm_clken, |
avs_clken, |
|
avs_waitrequest, |
avs_write, |
avs_read, |
avs_address, |
avs_byteenable, |
avs_burstcount, |
avs_beginbursttransfer, |
avs_begintransfer, |
avs_writedata, |
avs_readdata, |
avs_readdatavalid, |
avs_arbiterlock, |
avs_lock, |
avs_debugaccess, |
avs_transactionid, |
avs_readid, |
avs_writeid, |
avs_response, |
avs_writeresponserequest, |
avs_writeresponsevalid, |
|
// deprecated signals |
avs_readresponse, |
avs_writeresponse, |
avm_readresponse, |
avm_writeresponse, |
|
avm_waitrequest, |
avm_write, |
avm_read, |
avm_address, |
avm_byteenable, |
avm_burstcount, |
avm_beginbursttransfer, |
avm_begintransfer, |
avm_writedata, |
avm_readdata, |
avm_readdatavalid, |
avm_arbiterlock, |
avm_lock, |
avm_debugaccess, |
avm_transactionid, |
avm_readid, |
avm_writeid, |
avm_response, |
avm_writeresponserequest, |
avm_writeresponsevalid |
); |
|
// =head1 PARAMETERS |
parameter AV_ADDRESS_W = 32; // address width |
parameter AV_SYMBOL_W = 8; // default symbol is byte |
parameter AV_NUMSYMBOLS = 4; // number of symbols per word |
parameter AV_BURSTCOUNT_W = 3; // burst port width |
|
// deprecated parameter |
parameter AV_WRITERESPONSE_W = 8; |
parameter AV_READRESPONSE_W = 8; |
|
parameter AV_CONSTANT_BURST_BEHAVIOR = 1; // Address, burstcount, transactionid and |
// avm_writeresponserequest need to be held constant |
// in burst transaction |
parameter AV_BURST_LINEWRAP = 0; // line wrapping addr is set to 1 |
parameter AV_BURST_BNDR_ONLY = 0; // addr is multiple of burst size |
parameter REGISTER_WAITREQUEST = 0; // Waitrequest is registered at the slave |
parameter AV_MAX_PENDING_READS = 1; // maximum pending read transfer count |
parameter AV_MAX_PENDING_WRITES = 0; // maximum pending write transfer count |
parameter AV_FIX_READ_LATENCY = 0; // fixed read latency in cycles |
|
parameter USE_READ = 1; // use read port |
parameter USE_WRITE = 1; // use write port |
parameter USE_ADDRESS = 1; // use address port |
parameter USE_BYTE_ENABLE = 1; // use byteenable port |
parameter USE_BURSTCOUNT = 0; // use burstcount port |
parameter USE_READ_DATA = 1; // use readdata port |
parameter USE_READ_DATA_VALID = 1; // use readdatavalid port |
parameter USE_WRITE_DATA = 1; // use writedata port |
parameter USE_BEGIN_TRANSFER = 0; // use begintransfer port |
parameter USE_BEGIN_BURST_TRANSFER = 0; // use begintbursttransfer port |
parameter USE_WAIT_REQUEST = 1; // use waitrequest port |
parameter USE_ARBITERLOCK = 0; // Use arbiterlock pin on interface |
parameter USE_LOCK = 0; // Use lock pin on interface |
parameter USE_DEBUGACCESS = 0; // Use debugaccess pin on interface |
parameter USE_TRANSACTIONID = 0; // Use transactionid interface pin |
parameter USE_WRITERESPONSE = 0; // Use write response interface pins |
parameter USE_READRESPONSE = 0; // Use read response interface pins |
parameter USE_CLKEN = 0; // Use NTCM interface pins |
|
parameter AV_READ_TIMEOUT = 100; // timeout period for read transfer |
parameter AV_WRITE_TIMEOUT = 100; // timeout period for write burst transfer |
parameter AV_WAITREQUEST_TIMEOUT = 1024; // timeout period for continuous waitrequest |
parameter AV_MAX_READ_LATENCY = 100; // maximum read latency cycle for coverage |
parameter AV_MAX_WAITREQUESTED_READ = 100; // maximum waitrequested read cycle for coverage |
parameter AV_MAX_WAITREQUESTED_WRITE = 100; // maximum waitrequested write cycle for coverage |
parameter AV_MAX_CONTINUOUS_READ = 5; // maximum continuous read cycle for coverage |
parameter AV_MAX_CONTINUOUS_WRITE = 5; // maximum continuous write cycle for coverage |
parameter AV_MAX_CONTINUOUS_WAITREQUEST = 5; // maximum continuous waitrequest cycle for coverage |
parameter AV_MAX_CONTINUOUS_READDATAVALID = 5; // maximum continuous readdatavalid cycle for coverage |
parameter string SLAVE_ADDRESS_TYPE = "SYMBOLS"; // Set slave interface address type, {SYMBOLS, WORDS} |
parameter string MASTER_ADDRESS_TYPE = "SYMBOLS"; // Set master interface address type, {SYMBOLS, WORDS} |
|
parameter AV_READ_WAIT_TIME = 0; // Fixed wait time cycles when |
parameter AV_WRITE_WAIT_TIME = 0; // USE_WAIT_REQUEST is 0 |
|
parameter AV_REGISTERINCOMINGSIGNALS = 0; // Indicate that waitrequest is come from register |
parameter VHDL_ID = 0; // VHDL BFM ID number |
parameter PRINT_HELLO = 1; // To enable the printing of __hello message |
parameter STORE_COMMAND = 1; // Store commands inside command queue |
parameter STORE_RESPONSE = 1; // Store responses inside response queue |
|
localparam AV_DATA_W = AV_SYMBOL_W * AV_NUMSYMBOLS; |
localparam AV_MAX_BURST = USE_BURSTCOUNT ? 2**(lindex(AV_BURSTCOUNT_W)) : 1; |
localparam INT_WIDTH = 32; |
localparam AV_TRANSACTIONID_W = 8; |
|
localparam AV_SLAVE_ADDRESS_W = (SLAVE_ADDRESS_TYPE != MASTER_ADDRESS_TYPE)? (AV_ADDRESS_W - log2(AV_NUMSYMBOLS)):AV_ADDRESS_W; |
|
localparam TAP_W = 1 + // clken |
1 + // arbiterlock |
1 + // lock |
1 + // debugaccess |
((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) + // transactionid |
((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) + // readid |
((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) + // writeid |
2 + // response |
1 + // writeresponserequest |
1 + // writeresponsevalid |
1 + // waitrequest |
1 + // readdatavalid |
((AV_DATA_W == 0)? 1:AV_DATA_W) + // readdata |
1 + // write |
1 + // read |
((AV_ADDRESS_W == 0)? 1:AV_ADDRESS_W) + // address |
((AV_NUMSYMBOLS == 0)? 1:AV_NUMSYMBOLS) + // byteenable |
((AV_BURSTCOUNT_W == 0)? 1:AV_BURSTCOUNT_W) + // burstcount |
1 + // beginbursttransfer |
1 + // begintransfer |
((AV_DATA_W == 0)? 1:AV_DATA_W); // writedata |
|
function int lindex; |
// returns the left index for a vector having a declared width |
// when width is 0, then the left index is set to 0 rather than -1 |
input [31:0] width; |
lindex = (width > 0) ? (width-1) : 0; |
endfunction |
|
// =head1 PINS |
// =head2 Clock Interface |
input clk; |
input reset; |
|
// =head2 Tightly Coupled Memory Interface |
output avm_clken; |
input avs_clken; |
|
// =head2 Avalon Master Interface |
input avm_waitrequest; |
input avm_readdatavalid; |
input [lindex(AV_SYMBOL_W * AV_NUMSYMBOLS):0] avm_readdata; |
output avm_write; |
output avm_read; |
output [lindex(AV_ADDRESS_W):0] avm_address; |
output [lindex(AV_NUMSYMBOLS):0] avm_byteenable; |
output [lindex(AV_BURSTCOUNT_W):0] avm_burstcount; |
output avm_beginbursttransfer; |
output avm_begintransfer; |
output [lindex(AV_SYMBOL_W * AV_NUMSYMBOLS):0] avm_writedata; |
output avm_arbiterlock; |
output avm_lock; |
output avm_debugaccess; |
|
output [lindex(AV_TRANSACTIONID_W):0] avm_transactionid; |
input [lindex(AV_TRANSACTIONID_W):0] avm_readid; |
input [lindex(AV_TRANSACTIONID_W):0] avm_writeid; |
input [1:0] avm_response; |
output avm_writeresponserequest; |
input avm_writeresponsevalid; |
|
// deprecated |
input [lindex(AV_READRESPONSE_W):0] avm_readresponse; |
input [lindex(AV_WRITERESPONSE_W):0] avm_writeresponse; |
|
// =head2 Avalon Slave Interface |
output avs_waitrequest; |
output avs_readdatavalid; |
output [lindex(AV_SYMBOL_W * AV_NUMSYMBOLS):0] avs_readdata; |
input avs_write; |
input avs_read; |
input [lindex(AV_SLAVE_ADDRESS_W):0] avs_address; |
input [lindex(AV_NUMSYMBOLS):0] avs_byteenable; |
input [lindex(AV_BURSTCOUNT_W):0] avs_burstcount; |
input avs_beginbursttransfer; |
input avs_begintransfer; |
input [lindex(AV_SYMBOL_W * AV_NUMSYMBOLS):0] avs_writedata; |
input avs_arbiterlock; |
input avs_lock; |
input avs_debugaccess; |
|
input [lindex(AV_TRANSACTIONID_W):0] avs_transactionid; |
output [lindex(AV_TRANSACTIONID_W):0] avs_readid; |
output [lindex(AV_TRANSACTIONID_W):0] avs_writeid; |
output [1:0] avs_response; |
input avs_writeresponserequest; |
output avs_writeresponsevalid; |
|
// deprecated |
output [lindex(AV_READRESPONSE_W):0] avs_readresponse; |
output [lindex(AV_WRITERESPONSE_W):0] avs_writeresponse; |
|
logic avm_clken; |
logic avs_clken; |
|
logic avm_waitrequest; |
logic avm_readdatavalid; |
logic [lindex(AV_SYMBOL_W * AV_NUMSYMBOLS):0] avm_readdata; |
logic avm_write; |
logic avm_read; |
logic [lindex(AV_ADDRESS_W):0] avm_address; |
logic [lindex(AV_NUMSYMBOLS):0] avm_byteenable; |
logic [lindex(AV_BURSTCOUNT_W):0] avm_burstcount; |
logic avm_beginbursttransfer; |
logic avm_begintransfer; |
logic [lindex(AV_SYMBOL_W * AV_NUMSYMBOLS):0] avm_writedata; |
logic avm_arbiterlock; |
logic avm_lock; |
logic avm_debugaccess; |
|
logic [lindex(AV_TRANSACTIONID_W):0] avm_transactionid; |
logic [lindex(AV_TRANSACTIONID_W):0] avm_readid; |
logic [lindex(AV_TRANSACTIONID_W):0] avm_writeid; |
logic [1:0] avm_response; |
logic avm_writeresponserequest; |
logic avm_writeresponsevalid; |
|
// deprecated |
logic [lindex(AV_READRESPONSE_W):0] avm_readresponse; |
logic [lindex(AV_WRITERESPONSE_W):0] avm_writeresponse; |
|
|
logic avs_waitrequest; |
logic avs_readdatavalid; |
logic [lindex(AV_SYMBOL_W * AV_NUMSYMBOLS):0] avs_readdata; |
logic avs_write; |
logic avs_read; |
logic [lindex(AV_SLAVE_ADDRESS_W):0] avs_address; |
logic [lindex(AV_NUMSYMBOLS):0] avs_byteenable; |
logic [lindex(AV_BURSTCOUNT_W):0] avs_burstcount; |
logic avs_beginbursttransfer; |
logic avs_begintransfer; |
logic [lindex(AV_SYMBOL_W * AV_NUMSYMBOLS):0] avs_writedata; |
logic avs_arbiterlock; |
logic avs_lock; |
logic avs_debugaccess; |
|
logic [lindex(AV_TRANSACTIONID_W):0] avs_transactionid; |
logic [lindex(AV_TRANSACTIONID_W):0] avs_readid; |
logic [lindex(AV_TRANSACTIONID_W):0] avs_writeid; |
logic [1:0] avs_response; |
logic avs_writeresponserequest; |
logic avs_writeresponsevalid; |
|
// deprecated |
logic [lindex(AV_READRESPONSE_W):0] avs_readresponse; |
logic [lindex(AV_WRITERESPONSE_W):0] avs_writeresponse; |
|
logic [lindex(TAP_W):0] tap; |
|
logic [31:0] read_wait_time = 0; |
logic [31:0] write_wait_time = 0; |
logic local_avs_waitrequest; |
|
bit master_slave_address_type_mismatch; |
|
// Use SLAVE_ADDRESS_TYPE/MASTER_ADDRESS_TYPE inside always_comb block will causing an warning |
initial begin |
master_slave_address_type_mismatch = (SLAVE_ADDRESS_TYPE != MASTER_ADDRESS_TYPE); |
end |
|
//-------------------------------------------------------------------------- |
// =head1 DESCRIPTION |
// The component acts as a simple repeater or bridge with Avalon bus |
// signals passed through from the slave to master interface. |
// The instantiated altera_avalon_mm_monitor snoops all passing Avalon |
// bus signals and performs assertion checking and measures coverage on |
// Avalon Memory Mapped protocol properties. |
// =cut |
//-------------------------------------------------------------------------- |
|
always_comb begin |
// repeater |
avm_clken <= avs_clken; |
|
if (USE_WAIT_REQUEST == 0) begin |
avs_waitrequest <= local_avs_waitrequest; |
end else begin |
avs_waitrequest <= avm_waitrequest; |
end |
|
avs_readdatavalid <= avm_readdatavalid; |
avs_readdata <= avm_readdata; |
|
avm_write <= avs_write; |
avm_read <= avs_read; |
if (master_slave_address_type_mismatch) |
avm_address <= address_shift(avs_address); |
else |
avm_address <= avs_address; |
avm_byteenable <= avs_byteenable; |
avm_burstcount <= avs_burstcount; |
avm_beginbursttransfer <= avs_beginbursttransfer; |
avm_begintransfer <= avs_begintransfer; |
avm_writedata <= avs_writedata; |
|
avm_arbiterlock <= avs_arbiterlock; |
avm_lock <= avs_lock; |
avm_debugaccess <= avs_debugaccess; |
avm_transactionid <= avs_transactionid; |
avs_readid <= avm_readid; |
avs_writeid <= avm_writeid; |
avm_writeresponserequest <= avs_writeresponserequest; |
avs_writeresponsevalid <= avm_writeresponsevalid; |
avs_response <= avm_response; |
|
// snoop bus for assertion and coverage checking |
if (master_slave_address_type_mismatch) begin |
tap <= { |
avs_clken, |
avs_arbiterlock, |
avs_lock, |
avs_debugaccess, |
avs_transactionid, |
avm_readid, |
avm_writeid, |
avm_response, |
avs_writeresponserequest, |
avm_writeresponsevalid, |
|
(USE_WAIT_REQUEST == 0)? local_avs_waitrequest:avm_waitrequest, |
avm_readdatavalid, |
avm_readdata, |
|
avs_write, |
avs_read, |
address_shift(avs_address), |
avs_byteenable, |
avs_burstcount, |
avs_beginbursttransfer, |
avs_begintransfer, |
avs_writedata |
}; |
end else begin |
tap <= { |
avs_clken, |
avs_arbiterlock, |
avs_lock, |
avs_debugaccess, |
avs_transactionid, |
avm_readid, |
avm_writeid, |
avm_response, |
avs_writeresponserequest, |
avm_writeresponsevalid, |
|
(USE_WAIT_REQUEST == 0)? local_avs_waitrequest:avm_waitrequest, |
avm_readdatavalid, |
avm_readdata, |
|
avs_write, |
avs_read, |
avs_address, |
avs_byteenable, |
avs_burstcount, |
avs_beginbursttransfer, |
avs_begintransfer, |
avs_writedata |
}; |
end |
end |
|
//-------------------------------------------------------------------------- |
// =head1 ALTERA_AVALON_MM_MONITOR_ASSERTION |
// This module implements Avalon MM protocol assertion checking for |
// simulation. |
// Component name = monitor_assertion. |
// =cut |
//-------------------------------------------------------------------------- |
altera_avalon_mm_monitor_assertion |
#( |
.AV_ADDRESS_W (AV_ADDRESS_W), |
.AV_SYMBOL_W (AV_SYMBOL_W), |
.AV_NUMSYMBOLS (AV_NUMSYMBOLS), |
.AV_BURSTCOUNT_W (AV_BURSTCOUNT_W), |
.AV_CONSTANT_BURST_BEHAVIOR (AV_CONSTANT_BURST_BEHAVIOR), |
.AV_BURST_LINEWRAP (AV_BURST_LINEWRAP), |
.AV_BURST_BNDR_ONLY (AV_BURST_BNDR_ONLY), |
.AV_MAX_PENDING_READS (AV_MAX_PENDING_READS), |
.AV_MAX_PENDING_WRITES (AV_MAX_PENDING_WRITES), |
.AV_FIX_READ_LATENCY (AV_FIX_READ_LATENCY), |
|
.REGISTER_WAITREQUEST (REGISTER_WAITREQUEST), |
|
.USE_READ (USE_READ), |
.USE_WRITE (USE_WRITE), |
.USE_ADDRESS (USE_ADDRESS), |
.USE_BYTE_ENABLE (USE_BYTE_ENABLE), |
.USE_BURSTCOUNT (USE_BURSTCOUNT), |
.USE_READ_DATA (USE_READ_DATA), |
.USE_READ_DATA_VALID (USE_READ_DATA_VALID), |
.USE_WRITE_DATA (USE_WRITE_DATA), |
.USE_BEGIN_TRANSFER (USE_BEGIN_TRANSFER), |
.USE_BEGIN_BURST_TRANSFER (USE_BEGIN_BURST_TRANSFER), |
.USE_WAIT_REQUEST (USE_WAIT_REQUEST), |
|
.USE_ARBITERLOCK (USE_ARBITERLOCK), |
.USE_LOCK (USE_LOCK), |
.USE_DEBUGACCESS (USE_DEBUGACCESS), |
.USE_TRANSACTIONID (USE_TRANSACTIONID), |
.USE_WRITERESPONSE (USE_WRITERESPONSE), |
.USE_READRESPONSE (USE_READRESPONSE), |
.USE_CLKEN (USE_CLKEN), |
|
.AV_READ_TIMEOUT (AV_READ_TIMEOUT), |
.AV_WRITE_TIMEOUT (AV_WRITE_TIMEOUT), |
.AV_WAITREQUEST_TIMEOUT (AV_WAITREQUEST_TIMEOUT), |
.AV_READ_WAIT_TIME (AV_READ_WAIT_TIME), |
.AV_WRITE_WAIT_TIME (AV_WRITE_WAIT_TIME), |
.AV_REGISTERINCOMINGSIGNALS (AV_REGISTERINCOMINGSIGNALS), |
.SLAVE_ADDRESS_TYPE (SLAVE_ADDRESS_TYPE), |
.MASTER_ADDRESS_TYPE (MASTER_ADDRESS_TYPE) |
) |
master_assertion ( |
.clk (clk), |
.reset (reset), |
.tap (tap) |
); |
|
//-------------------------------------------------------------------------- |
// =head1 ALTERA_AVALON_MM_MONITOR_COVERAGE |
// This module implements Avalon MM protocol coverage for simulation. |
// Component name = monitor_coverage. |
// =cut |
//-------------------------------------------------------------------------- |
altera_avalon_mm_monitor_coverage |
#( |
.AV_ADDRESS_W (AV_ADDRESS_W), |
.AV_SYMBOL_W (AV_SYMBOL_W), |
.AV_NUMSYMBOLS (AV_NUMSYMBOLS), |
.AV_BURSTCOUNT_W (AV_BURSTCOUNT_W), |
.AV_BURST_LINEWRAP (AV_BURST_LINEWRAP), |
.AV_BURST_BNDR_ONLY (AV_BURST_BNDR_ONLY), |
.AV_MAX_PENDING_READS (AV_MAX_PENDING_READS), |
.AV_MAX_PENDING_WRITES (AV_MAX_PENDING_WRITES), |
.AV_FIX_READ_LATENCY (AV_FIX_READ_LATENCY), |
|
.REGISTER_WAITREQUEST (REGISTER_WAITREQUEST), |
|
.USE_READ (USE_READ), |
.USE_WRITE (USE_WRITE), |
.USE_ADDRESS (USE_ADDRESS), |
.USE_BYTE_ENABLE (USE_BYTE_ENABLE), |
.USE_BURSTCOUNT (USE_BURSTCOUNT), |
.USE_READ_DATA (USE_READ_DATA), |
.USE_READ_DATA_VALID (USE_READ_DATA_VALID), |
.USE_WRITE_DATA (USE_WRITE_DATA), |
.USE_BEGIN_TRANSFER (USE_BEGIN_TRANSFER), |
.USE_BEGIN_BURST_TRANSFER (USE_BEGIN_BURST_TRANSFER), |
.USE_WAIT_REQUEST (USE_WAIT_REQUEST), |
.USE_CLKEN (USE_CLKEN), |
|
.USE_ARBITERLOCK (USE_ARBITERLOCK), |
.USE_LOCK (USE_LOCK), |
.USE_DEBUGACCESS (USE_DEBUGACCESS), |
.USE_TRANSACTIONID (USE_TRANSACTIONID), |
.USE_WRITERESPONSE (USE_WRITERESPONSE), |
.USE_READRESPONSE (USE_READRESPONSE), |
|
.AV_MAX_READ_LATENCY (AV_MAX_READ_LATENCY), |
.AV_MAX_WAITREQUESTED_READ (AV_MAX_WAITREQUESTED_READ), |
.AV_MAX_WAITREQUESTED_WRITE (AV_MAX_WAITREQUESTED_WRITE), |
.AV_MAX_CONTINUOUS_READ (AV_MAX_CONTINUOUS_READ), |
.AV_MAX_CONTINUOUS_WRITE (AV_MAX_CONTINUOUS_WRITE), |
.AV_MAX_CONTINUOUS_WAITREQUEST (AV_MAX_CONTINUOUS_WAITREQUEST), |
.AV_MAX_CONTINUOUS_READDATAVALID (AV_MAX_CONTINUOUS_READDATAVALID), |
.AV_READ_WAIT_TIME (AV_READ_WAIT_TIME), |
.AV_WRITE_WAIT_TIME (AV_WRITE_WAIT_TIME) |
) |
master_coverage( |
.clk (clk), |
.reset (reset), |
.tap (tap) |
); |
|
//-------------------------------------------------------------------------- |
// =head1 ALTERA_AVALON_MM_MONITOR_TRANSACTIONS |
// This module implements Avalon-MM the transaction recorder. |
// =cut |
//-------------------------------------------------------------------------- |
`ifdef ENABLE_ALTERA_AVALON_TRANSACTION_RECORDING |
altera_avalon_mm_monitor_transactions |
#( |
.AV_ADDRESS_W (AV_ADDRESS_W), |
.AV_SYMBOL_W (AV_SYMBOL_W), |
.AV_NUMSYMBOLS (AV_NUMSYMBOLS), |
.AV_BURSTCOUNT_W (AV_BURSTCOUNT_W), |
.AV_BURST_LINEWRAP (AV_BURST_LINEWRAP), |
.AV_BURST_BNDR_ONLY (AV_BURST_BNDR_ONLY), |
.AV_MAX_PENDING_READS (AV_MAX_PENDING_READS), |
.AV_MAX_PENDING_WRITES (AV_MAX_PENDING_WRITES), |
.AV_FIX_READ_LATENCY (AV_FIX_READ_LATENCY), |
|
// deprecated |
// deprecated parameter |
.AV_WRITERESPONSE_W (AV_WRITERESPONSE_W), |
.AV_READRESPONSE_W (AV_READRESPONSE_W), |
|
.REGISTER_WAITREQUEST (REGISTER_WAITREQUEST), |
|
.USE_READ (USE_READ), |
.USE_WRITE (USE_WRITE), |
.USE_ADDRESS (USE_ADDRESS), |
.USE_BYTE_ENABLE (USE_BYTE_ENABLE), |
.USE_BURSTCOUNT (USE_BURSTCOUNT), |
.USE_READ_DATA (USE_READ_DATA), |
.USE_READ_DATA_VALID (USE_READ_DATA_VALID), |
.USE_WRITE_DATA (USE_WRITE_DATA), |
.USE_BEGIN_TRANSFER (USE_BEGIN_TRANSFER), |
.USE_BEGIN_BURST_TRANSFER (USE_BEGIN_BURST_TRANSFER), |
.USE_WAIT_REQUEST (USE_WAIT_REQUEST), |
.USE_CLKEN (USE_CLKEN), |
|
.USE_ARBITERLOCK (USE_ARBITERLOCK), |
.USE_LOCK (USE_LOCK), |
.USE_DEBUGACCESS (USE_DEBUGACCESS), |
.USE_TRANSACTIONID (USE_TRANSACTIONID), |
.USE_WRITERESPONSE (USE_WRITERESPONSE), |
.USE_READRESPONSE (USE_READRESPONSE), |
|
.AV_READ_WAIT_TIME (AV_READ_WAIT_TIME), |
.AV_WRITE_WAIT_TIME (AV_WRITE_WAIT_TIME), |
.STORE_RESPONSE (STORE_RESPONSE), |
.STORE_COMMAND (STORE_COMMAND) |
) |
monitor_trans( |
.clk (clk), |
.reset (reset), |
.tap (tap) |
); |
`endif |
|
// synthesis translate_off |
import verbosity_pkg::*; |
import avalon_mm_pkg::*; |
|
typedef bit [lindex(AV_ADDRESS_W):0] AvalonAddress_t; |
typedef bit [lindex(AV_BURSTCOUNT_W):0] AvalonBurstCount_t; |
typedef bit [AV_MAX_BURST-1:0][AV_DATA_W-1:0] AvalonData_t; |
typedef bit [AV_MAX_BURST-1:0][AV_NUMSYMBOLS-1:0] AvalonByteEnable_t; |
typedef bit [AV_MAX_BURST-1:0][INT_WIDTH-1:0] AvalonLatency_t; |
|
typedef struct packed { |
Request_t request; |
AvalonAddress_t address; // start address |
AvalonBurstCount_t burst_count; // burst length |
AvalonData_t data; // write data |
AvalonByteEnable_t byte_enable; // hot encoded |
int burst_cycle; |
} SlaveCommand_t; |
|
typedef struct packed { |
Request_t request; |
AvalonAddress_t address; // start addr |
AvalonBurstCount_t burst_count; // burst length |
AvalonData_t data; // read data |
AvalonLatency_t read_latency; |
AvalonLatency_t wait_latency; |
} MasterResponse_t; |
|
|
//-------------------------------------------------------------------------- |
// =head1 Public Methods API |
// This section describes the public methods in the application programming |
// interface (API). In this case the application program is the test bench |
// which instantiates and controls and queries state of this component. |
// Test programs must only use these public access methods and events to |
// communicate with this BFM component. The API and the module pins |
// are the only interfaces in this component that are guaranteed to be |
// stable. The API will be maintained for the life of the product. |
// While we cannot prevent a test program from directly accessing internal |
// tasks, functions, or data private to the BFM, there is no guarantee that |
// these will be present in the future. In fact, it is best for the user |
// to assume that the underlying implementation of this component can |
// and will change. |
//-------------------------------------------------------------------------- |
|
function automatic string get_version(); // public |
// Return component version as a string of three integers separated by periods. |
// For example, version 9.1 sp1 is encoded as "9.1.1". |
string ret_version = "16.1"; |
return ret_version; |
endfunction |
|
// =cut |
//-------------------------------------------------------------------------- |
// Public API Method(s) - end |
//-------------------------------------------------------------------------- |
|
function automatic void hello(); |
// introduction message to the console |
string message; |
$sformat(message, "%m: - Hello from altera_avalon_mm_monitor"); |
print(VERBOSITY_INFO, message); |
`ifdef DISABLE_ALTERA_AVALON_SIM_SVA |
$sformat(message, "%m: - Assertions disabled (DISABLE_ALTERA_AVALON_SIM_SVA defined)"); |
`else |
$sformat(message, "%m: - Assertions enabled (DISABLE_ALTERA_AVALON_SIM_SVA undefined)"); |
`endif |
print(VERBOSITY_INFO, message); |
`ifdef ALTERA_AVALON_SIM_MTI |
$sformat(message, "%m: - Transaction tracing enabled (ALTERA_AVALON_SIM_MTI defined)"); |
`else |
$sformat(message, "%m: - Transaction tracing disabled (ALTERA_AVALON_SIM_MTI undefined)"); |
`endif |
print(VERBOSITY_INFO, message); |
$sformat(message, "%m: - $Revision: #1 $"); |
print(VERBOSITY_INFO, message); |
$sformat(message, "%m: - $Date: 2016/08/07 $"); |
print(VERBOSITY_INFO, message); |
print_divider(VERBOSITY_INFO); |
endfunction |
|
//-------------------------------------------------------------------------- |
// The Mentor QuestaSim simulation transaction tracing feature is supported |
// by enabling the macro: +define+ALTERA_AVALON_SIM_MTI in CLI |
SlaveCommand_t current_command; |
MasterResponse_t completed_response; |
|
int command_trans; |
int command_trans_stream; |
|
int addr_offset = 0; |
bit burst_mode = 0; |
int command_counter = 0; |
int response_counter = 0; |
int clock_counter = 0; |
string message = "*unitialized*"; |
|
event signal_fatal_error; |
event command; |
event response; |
|
function automatic void init_transaction_recording(); |
`ifdef ALTERA_AVALON_SIM_MTI |
command_trans_stream = |
$create_transaction_stream("avalon_mm_monitor_bfm_cmd"); |
`endif |
endfunction |
|
function automatic void begin_record_command_trans(); |
`ifdef ALTERA_AVALON_SIM_MTI |
command_trans = $begin_transaction(command_trans_stream, "Command"); |
`endif |
endfunction |
|
function automatic void end_record_command_trans(); |
`ifdef ALTERA_AVALON_SIM_MTI |
string field; |
if (!reset) begin |
$add_attribute(command_trans, current_command.request, "request"); |
$add_attribute(command_trans, current_command.address, "address"); |
$add_attribute(command_trans, current_command.burst_count, "burst_count"); |
if (current_command.request == REQ_WRITE) begin |
for (int i=0; i<current_command.burst_count; i++) begin |
$sformat(field, "data_cycle_%0d", i); |
$add_attribute(command_trans, current_command.data[i], field); |
$sformat(field, "byte_enable_cycle_%0d", i); |
$add_attribute(command_trans, current_command.byte_enable[i], field); |
end |
end |
$end_transaction(command_trans); |
$free_transaction(command_trans); |
end |
`endif |
endfunction |
|
//-------------------------------------------------------------------------- |
|
initial begin |
// $vcdpluson; // for debugging with DVE |
if (PRINT_HELLO) |
hello(); |
init_transaction_recording(); |
end |
|
//-------------------------------------------------------------------------- |
always @(posedge clk) clock_counter++; |
always @(command) command_counter++; |
always @(response) response_counter++; |
|
always @(signal_fatal_error) begin |
$sformat(message, "%m: Terminate simulation."); |
print(VERBOSITY_FAILURE, message); |
abort_simulation(); |
end |
|
always @(posedge clk) begin |
fork: monitor |
begin |
#1 monitor_command(); |
begin_record_command_trans(); |
end |
begin |
@(posedge clk); |
end_record_command_trans(); |
end |
join_any; |
end |
|
task monitor_command(); |
current_command.address = avm_address; |
current_command.burst_count = avm_burstcount; |
if (avm_read && avm_write) begin |
current_command.address = avm_address; |
$sformat(message, "%m: Error - both write and read active, address: %0d", |
current_command.address); |
print(VERBOSITY_FAILURE, message); |
end else if (avm_write) begin |
if (avm_beginbursttransfer) begin |
current_command = '0; |
addr_offset = 0; |
burst_mode = 1; |
end else if (burst_mode) begin |
if (addr_offset == avm_burstcount-1) begin |
burst_mode = 0; |
addr_offset = 0; |
end else begin |
addr_offset++; |
end |
end else begin |
current_command = '0; |
burst_mode = 0; |
addr_offset = 0; |
end |
current_command.request = REQ_WRITE; |
current_command.data[addr_offset] = avm_writedata; |
current_command.byte_enable[addr_offset] = avm_byteenable; |
current_command.burst_cycle = addr_offset; |
->command; |
end else if (avm_read) begin |
current_command = '0; |
burst_mode = 0; |
addr_offset = 0; |
current_command.request = REQ_READ; |
// according to the Avalon spec, we expect that the master does |
// not drive writedata and byteenable during read request, but |
// this behavior may be violated in custom components |
current_command.data = avm_writedata; |
current_command.byte_enable = avm_byteenable; |
end |
endtask |
|
always @(posedge clk) begin |
if (USE_WAIT_REQUEST == 0) begin |
if (reset) begin |
local_avs_waitrequest = 0; |
read_wait_time = 0; |
write_wait_time = 0; |
end else begin |
local_avs_waitrequest = 0; |
if (AV_READ_WAIT_TIME > 0) begin |
#1; |
if (avs_read) begin |
if (read_wait_time < AV_READ_WAIT_TIME) begin |
local_avs_waitrequest = 1; |
read_wait_time++; |
end else begin |
local_avs_waitrequest = 0; |
read_wait_time = 0; |
end |
end |
end |
|
if (AV_WRITE_WAIT_TIME > 0) begin |
#1; |
if (avs_write) begin |
if (write_wait_time < AV_WRITE_WAIT_TIME) begin |
local_avs_waitrequest = 1; |
write_wait_time++; |
end else begin |
local_avs_waitrequest = 0; |
write_wait_time = 0; |
end |
end |
end |
end |
end else begin |
local_avs_waitrequest = avm_waitrequest; |
end |
end |
|
// synthesis translate_on |
|
function integer log2( |
input int value |
); |
//----------------------------------------------------------------------------- |
// Mathematic logarithm function with base as 2. |
//----------------------------------------------------------------------------- |
value = value-1; |
for (log2=0; value>0; log2=log2+1) |
begin |
value = value>>1; |
end |
|
endfunction: log2 |
|
function logic [lindex(AV_ADDRESS_W):0] address_shift( |
input logic [lindex(AV_ADDRESS_W):0] value |
); |
//----------------------------------------------------------------------------- |
// Shift the slave interface address back as master interface address. |
//----------------------------------------------------------------------------- |
if (value >= 0) |
address_shift = value << log2(AV_NUMSYMBOLS); |
else |
address_shift = 'x; |
|
endfunction: address_shift |
|
endmodule |
|
/sim/src/amm_monitor/altera_avalon_mm_monitor_assertion.sv
0,0 → 1,1858
// (C) 2001-2016 Intel Corporation. All rights reserved. |
// Your use of Intel Corporation's design tools, logic functions and other |
// software and tools, and its AMPP partner logic functions, and any output |
// files any of the foregoing (including device programming or simulation |
// files), and any associated documentation or information are expressly subject |
// to the terms and conditions of the Intel Program License Subscription |
// Agreement, Intel MegaCore Function License Agreement, or other applicable |
// license agreement, including, without limitation, that your use is for the |
// sole purpose of programming logic devices manufactured by Intel and sold by |
// Intel or its authorized distributors. Please refer to the applicable |
// agreement for further details. |
|
|
// $File: //acds/rel/16.1/ip/sopc/components/verification/altera_avalon_mm_monitor_bfm/altera_avalon_mm_monitor_assertion.sv $ |
// $Revision: #1 $ |
// $Date: 2016/08/07 $ |
//----------------------------------------------------------------------------- |
// =head1 NAME |
// altera_avalon_mm_monitor_assertion |
// =head1 SYNOPSIS |
// Memory Mapped Avalon Bus Protocol Checker |
//----------------------------------------------------------------------------- |
// =head1 DESCRIPTION |
// This module implements Avalon MM protocol assertion checking for simulation. |
//----------------------------------------------------------------------------- |
|
`timescale 1ps / 1ps |
|
module altera_avalon_mm_monitor_assertion( |
clk, |
reset, |
tap |
); |
|
// =head1 PARAMETERS |
parameter AV_ADDRESS_W = 32; // address width |
parameter AV_SYMBOL_W = 8; // default symbol is byte |
parameter AV_NUMSYMBOLS = 4; // number of symbols per word |
parameter AV_BURSTCOUNT_W = 3; // burst port width |
|
parameter AV_CONSTANT_BURST_BEHAVIOR = 1; // Address, burstcount and |
// avm_writeresponserequest need to be held constant |
// in burst transaction |
parameter AV_BURST_LINEWRAP = 0; // line wrapping addr is set to 1 |
parameter AV_BURST_BNDR_ONLY = 0; // addr is multiple of burst size |
parameter REGISTER_WAITREQUEST = 0; // Waitrequest is registered at the slave |
parameter AV_MAX_PENDING_READS = 1; // maximum pending read transfer count |
parameter AV_MAX_PENDING_WRITES = 0; // maximum pending write transfer count |
parameter AV_FIX_READ_LATENCY = 0; // fixed read latency in cycles |
|
parameter USE_READ = 1; // use read port |
parameter USE_WRITE = 1; // use write port |
parameter USE_ADDRESS = 1; // use address port |
parameter USE_BYTE_ENABLE = 1; // use byteenable port |
parameter USE_BURSTCOUNT = 0; // use burstcount port |
parameter USE_READ_DATA = 1; // use readdata port |
parameter USE_READ_DATA_VALID = 1; // use readdatavalid port |
parameter USE_WRITE_DATA = 1; // use writedata port |
parameter USE_BEGIN_TRANSFER = 0; // use begintransfer port |
parameter USE_BEGIN_BURST_TRANSFER = 0; // use begintbursttransfer port |
parameter USE_WAIT_REQUEST = 1; // use waitrequest port |
parameter USE_ARBITERLOCK = 0; // Use arbiterlock pin on interface |
parameter USE_LOCK = 0; // Use lock pin on interface |
parameter USE_DEBUGACCESS = 0; // Use debugaccess pin on interface |
parameter USE_TRANSACTIONID = 0; // Use transactionid interface pin |
parameter USE_WRITERESPONSE = 0; // Use write response interface pins |
parameter USE_READRESPONSE = 0; // Use read response interface pins |
parameter USE_CLKEN = 0; // Use clken interface pins |
|
parameter AV_READ_TIMEOUT = 100; // timeout period for read transfer |
parameter AV_WRITE_TIMEOUT = 100; // timeout period for write burst transfer |
parameter AV_WAITREQUEST_TIMEOUT = 1024; // timeout period for continuous waitrequest |
parameter AV_MAX_READ_LATENCY = 100; // maximum read latency cycle for coverage |
parameter AV_MAX_WAITREQUESTED_READ = 100; // maximum waitrequested read cycle for coverage |
parameter AV_MAX_WAITREQUESTED_WRITE = 100; // maximum waitrequested write cycle for coverage |
parameter string SLAVE_ADDRESS_TYPE = "SYMBOLS"; // Set slave interface address type, {SYMBOLS, WORDS} |
parameter string MASTER_ADDRESS_TYPE = "SYMBOLS"; // Set master interface address type, {SYMBOLS, WORDS} |
|
parameter AV_READ_WAIT_TIME = 0; // Fixed wait time cycles when |
parameter AV_WRITE_WAIT_TIME = 0; // USE_WAIT_REQUEST is 0 |
|
parameter AV_REGISTERINCOMINGSIGNALS = 0; // Indicate that waitrequest is come from register |
|
localparam AV_DATA_W = AV_SYMBOL_W * AV_NUMSYMBOLS; |
localparam AV_MAX_BURST = USE_BURSTCOUNT ? 2**(lindex(AV_BURSTCOUNT_W)) : 1; |
localparam INT_WIDTH = 32; |
localparam MAX_ID = (AV_MAX_PENDING_READS*AV_MAX_BURST > 100? AV_MAX_PENDING_READS*AV_MAX_BURST:100); |
localparam AV_TRANSACTIONID_W = 8; |
|
localparam TAP_W = 1 + // clken |
1 + // arbiterlock |
1 + // lock |
1 + // debugaccess |
((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) + // transactionid |
((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) + // readid |
((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) + // avm_writeid |
2 + // response |
1 + // writeresponserequest |
1 + // writeresponsevalid |
1 + // waitrequest |
1 + // readdatavalid |
((AV_DATA_W == 0)? 1:AV_DATA_W) + // readdata |
1 + // write |
1 + // read |
((AV_ADDRESS_W == 0)? 1:AV_ADDRESS_W) + // address |
((AV_NUMSYMBOLS == 0)? 1:AV_NUMSYMBOLS) + // byteenable |
((AV_BURSTCOUNT_W == 0)? 1:AV_BURSTCOUNT_W) + // burstcount |
1 + // beginbursttransfer |
1 + // begintransfer |
((AV_DATA_W == 0)? 1:AV_DATA_W); // writedata |
|
// =head1 PINS |
// =head2 Clock Interface |
input clk; |
input reset; |
|
// =head2 Avalon Monitor Interface |
// Interface consists of Avalon Memory-Mapped Interface. |
// =cut |
|
// =pod |
input [TAP_W-1:0] tap; |
// =cut |
|
function int lindex; |
// returns the left index for a vector having a declared width |
// when width is 0, then the left index is set to 0 rather than -1 |
input [31:0] width; |
lindex = (width > 0) ? (width-1) : 0; |
endfunction |
|
//-------------------------------------------------------------------------- |
// synthesis translate_off |
|
import verbosity_pkg::*; |
import avalon_mm_pkg::*; |
|
typedef bit [lindex(AV_ADDRESS_W):0] AvalonAddress_t; |
typedef bit [lindex(AV_BURSTCOUNT_W):0] AvalonBurstCount_t; |
typedef bit [AV_MAX_BURST-1:0][AV_DATA_W-1:0] AvalonData_t; |
typedef bit [AV_MAX_BURST-1:0][AV_NUMSYMBOLS-1:0] AvalonByteEnable_t; |
typedef bit [AV_MAX_BURST-1:0][INT_WIDTH-1:0] AvalonLatency_t; |
typedef bit [AV_MAX_BURST-1:0][1:0] AvalonReadResponseStatus_t; |
|
typedef struct packed { |
Request_t request; |
AvalonAddress_t address; // start address |
AvalonBurstCount_t burst_count; // burst length |
AvalonData_t data; // write data |
AvalonByteEnable_t byte_enable; // hot encoded |
int burst_cycle; |
logic write_response_request; |
} SlaveCommand_t; |
|
typedef struct packed { |
Request_t request; |
AvalonAddress_t address; // start addr |
AvalonBurstCount_t burst_count; // burst length |
AvalonData_t data; // read data |
AvalonLatency_t read_latency; |
AvalonLatency_t wait_latency; |
AvalonReadResponseStatus_t read_response; |
AvalonResponseStatus_t write_response; |
} MasterResponse_t; |
|
event event_a_half_cycle_reset_legal; |
event event_a_no_read_during_reset; |
event event_a_no_write_during_reset; |
event event_a_exclusive_read_write; |
event event_a_begintransfer_single_cycle; |
event event_a_begintransfer_legal; |
event event_a_begintransfer_exist; |
event event_a_beginbursttransfer_single_cycle; |
event event_a_beginbursttransfer_legal; |
event event_a_beginbursttransfer_exist; |
event event_a_less_than_burstcount_max_size; |
event event_a_byteenable_legal; |
event event_a_constant_during_waitrequest; |
event event_a_constant_during_burst; |
event event_a_burst_legal; |
event event_a_waitrequest_during_reset; |
event event_a_no_readdatavalid_during_reset; |
event event_a_less_than_maximumpendingreadtransactions; |
event event_a_waitrequest_timeout; |
event event_a_write_burst_timeout; |
event event_a_read_response_timeout; |
event event_a_read_response_sequence; |
event event_a_readid_sequence; |
event event_a_writeid_sequence; |
event event_a_constant_during_clk_disabled; |
event event_a_register_incoming_signals; |
event event_a_address_align_with_data_width; |
event event_a_write_response_timeout; |
event event_a_unrequested_write_response; |
|
|
bit [1:0] reset_flag = 2'b11; |
bit read_transaction_flag = 0; |
bit read_without_waitrequest_flag = 0; |
bit byteenable_legal_flag = 0; |
bit byteenable_single_bit_flag = 0; |
bit byteenable_continual_bit_flag = 0; |
bit reset_half_cycle_flag = 0; |
logic [MAX_ID:0] read_response_timeout_start_flag = 0; |
|
bit enable_a_half_cycle_reset_legal = 1; |
bit enable_a_no_read_during_reset = 1; |
bit enable_a_no_write_during_reset = 1; |
bit enable_a_exclusive_read_write = 1; |
bit enable_a_begintransfer_single_cycle = 1; |
bit enable_a_begintransfer_legal = 1; |
bit enable_a_begintransfer_exist = 1; |
bit enable_a_beginbursttransfer_single_cycle = 1; |
bit enable_a_beginbursttransfer_legal = 1; |
bit enable_a_beginbursttransfer_exist = 1; |
bit enable_a_less_than_burstcount_max_size = 1; |
bit enable_a_byteenable_legal = 1; |
bit enable_a_constant_during_waitrequest = 1; |
bit enable_a_constant_during_burst = 1; |
bit enable_a_burst_legal = 1; |
bit enable_a_waitrequest_during_reset = 1; |
bit enable_a_no_readdatavalid_during_reset = 1; |
bit enable_a_less_than_maximumpendingreadtransactions = 1; |
bit enable_a_waitrequest_timeout = 1; |
bit enable_a_write_burst_timeout = 1; |
bit enable_a_read_response_timeout = 1; |
bit enable_a_read_response_sequence = 1; |
bit enable_a_readid_sequence = 0; |
bit enable_a_writeid_sequence = 0; |
bit enable_a_constant_during_clk_disabled = 1; |
bit enable_a_register_incoming_signals = 1; |
bit enable_a_address_align_with_data_width = 1; |
bit enable_a_write_response_timeout = 1; |
bit enable_a_unrequested_write_response = 1; |
|
int write_burst_counter = 0; |
int pending_read_counter = 0; |
int write_burst_timeout_counter = 0; |
int waitrequest_timeout_counter = 0; |
logic [MAX_ID:0][31:0] temp_read_response_timeout_counter = 0; |
int read_response_timeout_counter = 0; |
int read_id = 0; |
int readdatavalid_id = 0; |
int byteenable_bit_counter = 0; |
int reset_counter = 1; |
bit write_burst_completed = 0; |
logic [MAX_ID:0][lindex(AV_BURSTCOUNT_W):0] read_burst_counter = 0; |
logic [AV_TRANSACTIONID_W-1:0] write_transactionid_queued[$]; |
logic [AV_TRANSACTIONID_W-1:0] read_transactionid_queued[$]; |
int write_response_burstcount = 0; |
int write_burstcount_queued[$]; |
int read_response_burstcount = 0; |
int read_burstcount_queued[$]; |
int temp_write_transactionid_queued = 0; |
int temp_read_transactionid_queued = 0; |
int fix_latency_queued[$]; |
int fix_latency_queued_counter = 0; |
int pending_write_response = 0; |
int write_response_timeout = 100; |
logic [lindex(AV_MAX_PENDING_WRITES):0][31:0] write_response_timeout_counter; |
logic past_readdatavalid = 0; |
logic past_writeresponsevalid = 0; |
logic [lindex(AV_TRANSACTIONID_W):0] past_writeid; |
logic [lindex(AV_TRANSACTIONID_W):0] past_readid; |
logic round_over = 0; |
logic command_while_clken = 0; |
logic waitrequested_command_while_clken = 0; |
|
//-------------------------------------------------------------------------- |
// unpack Avalon bus interface tap into individual port signals |
|
logic waitrequest; |
logic readdatavalid; |
logic [lindex(AV_DATA_W):0] readdata; |
logic write; |
logic read; |
logic [lindex(AV_ADDRESS_W):0] address; |
logic [lindex(AV_NUMSYMBOLS):0] byteenable; |
logic [lindex(AV_BURSTCOUNT_W):0] burstcount; |
logic beginbursttransfer; |
logic begintransfer; |
logic [lindex(AV_DATA_W):0] writedata; |
logic arbiterlock; |
logic lock; |
logic debugaccess; |
|
logic [lindex(AV_TRANSACTIONID_W):0] transactionid; |
logic [lindex(AV_TRANSACTIONID_W):0] readid; |
logic [lindex(AV_TRANSACTIONID_W):0] writeid; |
logic [1:0] response; |
logic writeresponserequest; |
logic writeresponsevalid; |
logic clken; |
|
always_comb begin |
|
clken <= (USE_CLKEN == 1)? |
tap[3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+21: |
3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+21] : 1; |
|
arbiterlock <= (USE_ARBITERLOCK == 1)? |
tap[3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+20: |
3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+20] : 0; |
|
lock <= (USE_LOCK == 1)? |
tap[3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+19: |
3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+19] : 0; |
|
debugaccess <= (USE_DEBUGACCESS == 1)? |
tap[3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+18: |
3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+18] : 0; |
|
transactionid <= (USE_TRANSACTIONID == 1)? |
tap[3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+17: |
2*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+17] : 0; |
|
readid <= (USE_READRESPONSE == 1)? |
tap[2*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+16: |
lindex(AV_TRANSACTIONID_W)+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+16] : 0; |
|
writeid <= (USE_WRITERESPONSE == 1)? |
tap[lindex(AV_TRANSACTIONID_W)+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+15: |
2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+15] : 0; |
|
response <= (USE_WRITERESPONSE == 1 || USE_READRESPONSE == 1)? |
tap[2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+14: |
2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+13] : 0; |
|
writeresponserequest <= (USE_WRITERESPONSE == 1)? |
tap[2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+12: |
2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+12] : 0; |
|
writeresponsevalid <= (USE_WRITERESPONSE == 1)? |
tap[2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+11: |
2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+11] : 0; |
|
waitrequest <= tap[2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+10: |
2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+10]; |
|
readdatavalid <= (USE_READ_DATA_VALID == 1)? |
tap[2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+9: |
2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+9] : 0; |
|
readdata <= (USE_READ_DATA == 1)? |
tap[2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+8: |
lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+8] : 0; |
|
write <= (USE_WRITE == 1)? |
tap[lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+7: |
lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+7] : 0; |
|
read <= (USE_READ == 1)? |
tap[lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+6: |
lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+6] : 0; |
|
address <= (USE_ADDRESS == 1)? |
tap[lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+5: |
lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+5] : 0; |
|
byteenable <= (USE_BYTE_ENABLE == 1)? |
tap[lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+4: |
lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+4] : 0; |
|
burstcount <= (USE_BURSTCOUNT == 1)? |
tap[lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+3: lindex(AV_DATA_W)+3] : 1; |
|
beginbursttransfer <= (USE_BEGIN_BURST_TRANSFER == 1)? |
tap[lindex(AV_DATA_W)+2:lindex(AV_DATA_W)+2] : 0; |
|
begintransfer <= (USE_BEGIN_TRANSFER == 1)? tap[lindex(AV_DATA_W)+1:lindex(AV_DATA_W)+1] : 0; |
|
writedata <= (USE_WRITE_DATA == 1)? tap[lindex(AV_DATA_W):0] : 0; |
end |
|
//-------------------------------------------------------------------------- |
// =head1 Public Methods API |
// This section describes the public methods in the application programming |
// interface (API). In this case the application program is the test bench |
// which instantiates and controls and queries state of this component. |
// Test programs must only use these public access methods and events to |
// communicate with this BFM component. The API and the module pins |
// are the only interfaces in this component that are guaranteed to be |
// stable. The API will be maintained for the life of the product. |
// While we cannot prevent a test program from directly accessing internal |
// tasks, functions, or data private to the BFM, there is no guarantee that |
// these will be present in the future. In fact, it is best for the user |
// to assume that the underlying implementation of this component can |
// and will change. |
// =cut |
//-------------------------------------------------------------------------- |
|
// Master Assertions API |
function automatic void set_enable_a_half_cycle_reset_legal( // public |
bit assert_enable |
); |
// enable or disable a_half_cycle_reset_legal assertion |
|
enable_a_half_cycle_reset_legal = assert_enable; |
endfunction |
|
function automatic void set_enable_a_no_read_during_reset( // public |
bit assert_enable |
); |
// enable or disable a_no_read_during_reset assertion |
|
enable_a_no_read_during_reset = assert_enable; |
endfunction |
|
function automatic void set_enable_a_no_write_during_reset( // public |
bit assert_enable |
); |
// enable or disable a_no_write_during_reset assertion |
|
enable_a_no_write_during_reset = assert_enable; |
endfunction |
|
function automatic void set_enable_a_exclusive_read_write( // public |
bit assert_enable |
); |
// enable or disable a_exclusive_read_write assertion |
|
enable_a_exclusive_read_write = assert_enable; |
endfunction |
|
function automatic void set_enable_a_begintransfer_single_cycle( // public |
bit assert_enable |
); |
// enable or disable a_begintransfer_single_cycle assertion |
|
enable_a_begintransfer_single_cycle = assert_enable; |
endfunction |
|
function automatic void set_enable_a_begintransfer_legal( // public |
bit assert_enable |
); |
// enable or disable a_begintransfer_legal assertion |
|
enable_a_begintransfer_legal = assert_enable; |
endfunction |
|
function automatic void set_enable_a_begintransfer_exist( // public |
bit assert_enable |
); |
// enable or disable a_begintransfer_exist assertion |
|
enable_a_begintransfer_exist = assert_enable; |
endfunction |
|
function automatic void set_enable_a_beginbursttransfer_single_cycle( // public |
bit assert_enable |
); |
// enable or disable a_beginbursttransfer_single_cycle assertion |
|
enable_a_beginbursttransfer_single_cycle = assert_enable; |
endfunction |
|
function automatic void set_enable_a_beginbursttransfer_legal( // public |
bit assert_enable |
); |
// enable or disable a_beginbursttransfer_legal assertion |
|
enable_a_beginbursttransfer_legal = assert_enable; |
endfunction |
|
function automatic void set_enable_a_beginbursttransfer_exist( // public |
bit assert_enable |
); |
// enable or disable a_beginbursttransfer_exist assertion |
|
enable_a_beginbursttransfer_exist = assert_enable; |
endfunction |
|
function automatic void set_enable_a_less_than_burstcount_max_size( // public |
bit assert_enable |
); |
// enable or disable a_less_than_burstcount_max_size assertion |
|
enable_a_less_than_burstcount_max_size = assert_enable; |
endfunction |
|
function automatic void set_enable_a_byteenable_legal( // public |
bit assert_enable |
); |
// enable or disable a_byteenable_legal assertion |
|
enable_a_byteenable_legal = assert_enable; |
endfunction |
|
function automatic void set_enable_a_constant_during_waitrequest( // public |
bit assert_enable |
); |
// enable or disable a_constant_during_waitrequest assertion |
|
enable_a_constant_during_waitrequest = assert_enable; |
endfunction |
|
function automatic void set_enable_a_constant_during_burst( // public |
bit assert_enable |
); |
// enable or disable a_constant_during_burst assertion |
|
enable_a_constant_during_burst = assert_enable; |
endfunction |
|
function automatic void set_enable_a_burst_legal( // public |
bit assert_enable |
); |
// enable or disable a_burst_legal assertion |
|
enable_a_burst_legal = assert_enable; |
endfunction |
|
// Slave Assertions API |
function automatic void set_enable_a_waitrequest_during_reset( // public |
bit assert_enable |
); |
// enable or disable a_waitrequest_during_reset assertion |
|
enable_a_waitrequest_during_reset = assert_enable; |
endfunction |
|
function automatic void set_enable_a_no_readdatavalid_during_reset( // public |
bit assert_enable |
); |
// enable or disable a_no_readdatavalid_during_reset assertion |
|
enable_a_no_readdatavalid_during_reset = assert_enable; |
endfunction |
|
function automatic void set_enable_a_less_than_maximumpendingreadtransactions( // public |
bit assert_enable |
); |
// enable or disable a_less_than_maximumpendingreadtransactions assertion |
|
enable_a_less_than_maximumpendingreadtransactions = assert_enable; |
endfunction |
|
function automatic void set_enable_a_read_response_sequence( // public |
bit assert_enable |
); |
// enable or disable a_read_response_sequence assertion |
|
enable_a_read_response_sequence = assert_enable; |
endfunction |
|
function automatic void set_enable_a_readid_sequence( // public |
bit assert_enable |
); |
// enable or disable a_readid_sequence assertion |
|
enable_a_readid_sequence = assert_enable; |
endfunction |
|
function automatic void set_enable_a_writeid_sequence( // public |
bit assert_enable |
); |
// enable or disable a_writeid_sequence assertion |
|
enable_a_writeid_sequence = assert_enable; |
endfunction |
// Timeout Assertions API |
function automatic void set_enable_a_waitrequest_timeout( // public |
bit assert_enable |
); |
// enable or disable a_waitrequest_timeout assertion |
|
enable_a_waitrequest_timeout = assert_enable; |
endfunction |
|
function automatic void set_enable_a_write_burst_timeout( // public |
bit assert_enable |
); |
// enable or disable a_write_burst_timeout assertion |
|
enable_a_write_burst_timeout = assert_enable; |
endfunction |
|
function automatic void set_enable_a_read_response_timeout( // public |
bit assert_enable |
); |
// enable or disable a_read_response_timeout assertion |
|
enable_a_read_response_timeout = assert_enable; |
endfunction |
|
function automatic void set_enable_a_constant_during_clk_disabled( // public |
bit assert_enable |
); |
// enable or disable a_constant_during_clk_disabled assertion |
|
enable_a_constant_during_clk_disabled = assert_enable; |
endfunction |
|
function automatic void set_enable_a_register_incoming_signals( // public |
bit assert_enable |
); |
// enable or disable a_register_incoming_signals assertion |
|
enable_a_register_incoming_signals = assert_enable; |
endfunction |
|
function automatic void set_enable_a_address_align_with_data_width( // public |
bit assert_enable |
); |
// enable or disable a_address_align_with_data_width assertion |
|
enable_a_address_align_with_data_width = assert_enable; |
endfunction |
|
function automatic void set_enable_a_write_response_timeout( // public |
bit assert_enable |
); |
// enable or disable a_write_response_timeout assertion |
|
enable_a_write_response_timeout = assert_enable; |
endfunction |
|
function automatic void set_enable_a_unrequested_write_response( // public |
bit assert_enable |
); |
// enable or disable a_unrequested_write_response assertion |
|
enable_a_unrequested_write_response = assert_enable; |
endfunction |
|
function automatic void set_write_response_timeout( // public |
int cycles = 100 |
); |
// set timeout for write response |
|
write_response_timeout = cycles; |
endfunction |
|
//-------------------------------------------------------------------------- |
// =head1 Assertion Checkers and Coverage Monitors |
// The assertion checkers in this module are only executable on simulators |
// supporting the SystemVerilog Assertion (SVA) language. |
// Mentor Modelsim AE and SE do not support this. |
// Simulators that are supported include: Synopsys VCS and Mentor questasim. |
// The assertion checking logic in this module must be explicitly enabled |
// so that designs using this module can still be compiled on Modelsim without |
// changes. To disable assertions define the following macro in the testbench |
// or on the command line with: +define+DISABLE_ALTERA_AVALON_SIM_SVA. |
// =cut |
//-------------------------------------------------------------------------- |
|
string str_assertion; |
|
function automatic void print_assertion( |
string message_in |
); |
string message_out; |
$sformat(message_out, "ASSERTION: %m: %s", message_in); |
print(VERBOSITY_FAILURE, message_out); |
endfunction |
|
// previous cycle value of signals |
always @(posedge clk) begin |
past_readdatavalid = readdatavalid; |
past_writeresponsevalid = writeresponsevalid; |
past_readid = readid; |
past_writeid = writeid; |
end |
|
// Counter for general assertion counters |
always @(posedge clk) begin |
|
if (!USE_CLKEN || clken) begin |
// ignore the waitrequest effect while reset |
if ((read || write) && |
reset_flag[1] == 0) |
reset_flag[0] = 0; |
if (($fell(read) || $fell(write) || readdatavalid || |
$fell(begintransfer) || $fell(beginbursttransfer) || |
((read || write) && $fell(waitrequest))) && |
reset_flag[0] == 0) begin |
reset_flag[1] = 1; |
reset_flag[0] = 1; |
end |
|
// counter for readdatavalid_id and read response timeout check |
if ((!read || (read && waitrequest)) && !readdatavalid) begin |
read_response_timeout_counter = 0; |
end |
if (read && !waitrequest && !readdatavalid) begin |
if (((!$fell(waitrequest) && !waitrequested_command_while_clken) || |
$rose(read)) || command_while_clken || reset_flag[1] == 0) begin |
read_response_timeout_start_flag[read_id] = 1; |
temp_read_response_timeout_counter[read_id] = 0; |
end else begin |
if (read_id != 0) begin |
read_response_timeout_start_flag[read_id-1] = 1; |
temp_read_response_timeout_counter[read_id-1] = 0; |
end else begin |
read_response_timeout_start_flag[MAX_ID] = 1; |
temp_read_response_timeout_counter[MAX_ID] = 0; |
end |
end |
end |
|
if (!read && readdatavalid) begin |
read_response_timeout_counter = |
temp_read_response_timeout_counter[readdatavalid_id]-1; |
if (read_burst_counter[readdatavalid_id] == 1 || |
read_burst_counter[readdatavalid_id] == 0) begin |
temp_read_response_timeout_counter[readdatavalid_id] = 0; |
read_response_timeout_start_flag[readdatavalid_id] = 0; |
if (readdatavalid_id < (MAX_ID)) |
readdatavalid_id++; |
else |
readdatavalid_id = 0; |
end |
end |
if (read && readdatavalid) begin |
read_response_timeout_counter = |
temp_read_response_timeout_counter[readdatavalid_id]-1; |
if (!waitrequest) begin |
if (((!$fell(waitrequest) && !waitrequested_command_while_clken) || |
$rose(read)) || command_while_clken || reset_flag[1] == 0) begin |
read_response_timeout_start_flag[read_id] = 1; |
temp_read_response_timeout_counter[read_id] = 0; |
end else begin |
if (read_id != 0) begin |
read_response_timeout_start_flag[read_id-1] = 1; |
temp_read_response_timeout_counter[read_id-1] = 0; |
end else begin |
read_response_timeout_start_flag[MAX_ID] = 1; |
temp_read_response_timeout_counter[MAX_ID] = 0; |
end |
end |
end |
if (read_burst_counter[readdatavalid_id] == 1 || |
read_burst_counter[readdatavalid_id] == 0) begin |
temp_read_response_timeout_counter[readdatavalid_id] = 0; |
read_response_timeout_start_flag[readdatavalid_id] = 0; |
if (readdatavalid_id < (MAX_ID)) |
readdatavalid_id++; |
else |
readdatavalid_id = 0; |
end |
end |
|
// new burst write transaction started |
if (($rose(write) || (write && ((!waitrequest && ((!$fell(waitrequest) && |
!waitrequested_command_while_clken) || reset_flag[1] == 0)) || |
command_while_clken || ($rose(waitrequest))))) && |
write_burst_counter == 0 && burstcount > 0) begin |
write_burst_counter = burstcount; |
write_transactionid_queued.push_front(transactionid); |
temp_write_transactionid_queued = write_transactionid_queued[$]; |
write_burstcount_queued.push_front(burstcount); |
end |
|
if (write && !waitrequest && write_burst_counter > 0) |
write_burst_counter--; |
|
// new read transaction asserted |
if (($rose(read) || (read && ((!waitrequest && |
((!$fell(waitrequest) && !waitrequested_command_while_clken) || |
reset_flag[1] == 0)) || command_while_clken || |
($rose(waitrequest))))) || (read_transaction_flag && waitrequest && |
read_without_waitrequest_flag && read)) begin |
read_transaction_flag = 1; |
read_transactionid_queued.push_front(transactionid); |
temp_read_transactionid_queued = read_transactionid_queued[$]; |
read_burstcount_queued.push_front(burstcount); |
end else |
read_transaction_flag = 0; |
|
// new read transaction without previous read response(readdatavalid) returned at same cycle |
if ((($rose(read) || (read && ((!waitrequest && |
((!$fell(waitrequest) && !waitrequested_command_while_clken) || |
reset_flag[1] == 0)) || command_while_clken || |
($rose(waitrequest))))) || (read_transaction_flag && waitrequest && |
read_without_waitrequest_flag && read)) && |
!readdatavalid) begin |
if (burstcount > 0) |
read_burst_counter[read_id] = burstcount; |
if (!waitrequest) |
read_without_waitrequest_flag = 1; |
else |
read_without_waitrequest_flag = 0; |
pending_read_counter++; |
if (read_id < (MAX_ID)) |
read_id++; |
else |
read_id = 0; |
end |
|
// previous read response(readdatavalid) returned while no new read transaction asserted |
if ((readdatavalid || |
(fix_latency_queued_counter != 0 && |
fix_latency_queued_counter == AV_FIX_READ_LATENCY && |
!USE_READ_DATA_VALID)) && |
(!read_transaction_flag || !read) && pending_read_counter > 0) begin |
if ((readdatavalid_id == 0) && (read_burst_counter[MAX_ID] == 0)) begin |
round_over = 0; |
if (read_burst_counter[readdatavalid_id] > 0) begin |
if (read_burst_counter[readdatavalid_id] == 1) begin |
pending_read_counter--; |
end |
read_burst_counter[readdatavalid_id]--; |
end |
end else if (read_id >= ((readdatavalid_id == 0)?MAX_ID-1:readdatavalid_id-1)) begin |
round_over = 0; |
for (int i=0; i<=MAX_ID; i++) begin |
if (read_burst_counter[i] > 0) begin |
if (read_burst_counter[i] == 1) begin |
pending_read_counter--; |
end |
read_burst_counter[i]--; |
i=MAX_ID+1; |
end |
end |
end else begin |
for (int i=((readdatavalid_id == 0)?MAX_ID-1:readdatavalid_id-1); i<=MAX_ID; i++) begin |
round_over = 1; |
if (read_burst_counter[i] > 0) begin |
if (read_burst_counter[i] == 1) begin |
pending_read_counter--; |
end |
read_burst_counter[i]--; |
i=MAX_ID+1; |
end |
end |
end |
end |
|
// new read transaction with previous read response(readdatavalid) returned at same cycle |
if ((($rose(read) || (read && ((!waitrequest && |
((!$fell(waitrequest) && !waitrequested_command_while_clken) || |
reset_flag[1] == 0)) || command_while_clken || |
($rose(waitrequest))))) || (read_transaction_flag && waitrequest && |
read_without_waitrequest_flag && read)) && |
(readdatavalid || (fix_latency_queued_counter != 0 && |
fix_latency_queued_counter == AV_FIX_READ_LATENCY && |
!USE_READ_DATA_VALID))) begin |
if ((readdatavalid_id == 0) && (read_burst_counter[MAX_ID] == 0)) begin |
round_over = 0; |
if (read_burst_counter[readdatavalid_id] > 0) begin |
if (read_burst_counter[readdatavalid_id] == 1) begin |
pending_read_counter--; |
end |
read_burst_counter[readdatavalid_id]--; |
end |
end else if (read_id >= ((readdatavalid_id == 0)?MAX_ID-1:readdatavalid_id-1)) begin |
round_over = 0; |
for (int i=0; i<=MAX_ID; i++) begin |
if (read_burst_counter[i] > 0) begin |
if (read_burst_counter[i] == 1) begin |
pending_read_counter--; |
end |
read_burst_counter[i]--; |
i=MAX_ID+1; |
end |
end |
end else begin |
for (int i=((readdatavalid_id == 0)?MAX_ID-1:readdatavalid_id-1); i<=MAX_ID; i++) begin |
round_over = 1; |
if (read_burst_counter[i] > 0) begin |
if (read_burst_counter[i] == 1) begin |
pending_read_counter--; |
end |
read_burst_counter[i]--; |
i=MAX_ID+1; |
end |
end |
end |
|
if (burstcount > 0) |
read_burst_counter[read_id] = burstcount; |
if (!waitrequest) |
read_without_waitrequest_flag = 1; |
else |
read_without_waitrequest_flag = 0; |
pending_read_counter++; |
if (read_id < (MAX_ID)) |
read_id++; |
else |
read_id = 0; |
end |
|
// Counter for timeout |
if (pending_read_counter > 0) begin |
if (!USE_READ_DATA_VALID) begin |
end else begin |
for (int i=0; i<=MAX_ID; i++) begin |
if (i != read_id) begin |
if (read_response_timeout_start_flag[i]) |
temp_read_response_timeout_counter[i]++; |
end |
end |
end |
end |
|
if (read || write_burst_counter == 0) |
write_burst_timeout_counter = 0; |
if (write_burst_counter != 0 || (write && beginbursttransfer)) |
write_burst_timeout_counter++; |
if (waitrequest && (read || write)) |
waitrequest_timeout_counter++; |
else |
waitrequest_timeout_counter = 0; |
|
// Counter for write response timeout checking |
if (pending_write_response > 0) begin |
for (int i = 0; i < pending_write_response; i++) begin |
write_response_timeout_counter[i]++; |
end |
end |
|
if (write == 1 && write_burst_counter == 0) begin |
write_response_timeout_counter[pending_write_response] = 0; |
pending_write_response++; |
end |
|
if (writeresponsevalid) begin |
if (pending_write_response > 0) begin |
pending_write_response--; |
end |
write_response_timeout_counter[0] = 0; |
for (int i = 0; i < pending_write_response; i++) begin |
write_response_timeout_counter[i] = write_response_timeout_counter[i+1]; |
end |
end |
|
// Counter for writeresponse sequence checking |
if (writeresponsevalid) begin |
void'(write_transactionid_queued.pop_back()); |
temp_write_transactionid_queued = write_transactionid_queued[$]; |
end |
|
// Counter for readresponse sequence checking |
if (readdatavalid || ((fix_latency_queued_counter == AV_FIX_READ_LATENCY) && |
(!USE_READ_DATA_VALID))) begin |
if (read_response_burstcount == 0) begin |
if (read_burstcount_queued.size() > 0) |
read_response_burstcount = read_burstcount_queued.pop_back(); |
end |
if (read_response_burstcount > 0) |
read_response_burstcount--; |
if (read_response_burstcount == 0) begin |
if (read_transactionid_queued.size() > 0) |
void'(read_transactionid_queued.pop_back()); |
temp_read_transactionid_queued = read_transactionid_queued[$]; |
end |
end |
|
// fix latency counter |
if (read && !waitrequest) begin |
fix_latency_queued.push_front(0); |
end |
|
if (fix_latency_queued.size() > 0) begin |
foreach(fix_latency_queued[size]) begin |
fix_latency_queued[size]++; |
if (fix_latency_queued[size] > AV_FIX_READ_LATENCY) begin |
void'(fix_latency_queued.pop_back()); |
end |
end |
fix_latency_queued_counter = fix_latency_queued[$]; |
end |
command_while_clken = 0; |
waitrequested_command_while_clken = 0; |
end else begin |
if (($rose(waitrequest) && (read || write)) || |
($rose(read) || $rose(write))) begin |
command_while_clken = 1; |
end |
|
if ($fell(waitrequest) && (read || write)) begin |
waitrequested_command_while_clken = 1; |
end |
end |
end |
|
// Counter for byteenable legality checking |
always @(posedge clk && byteenable >= 0) begin |
byteenable_bit_counter = 0; |
byteenable_legal_flag = 0; |
byteenable_single_bit_flag = 0; |
byteenable_continual_bit_flag = 0; |
for (int i=0; i<AV_NUMSYMBOLS; i++) begin |
if (byteenable[i]) begin |
if (!byteenable_single_bit_flag && |
byteenable_bit_counter == 0) begin |
byteenable_single_bit_flag = 1; |
byteenable_continual_bit_flag = 0; |
byteenable_legal_flag = 0; |
end else if (byteenable_single_bit_flag && |
byteenable_bit_counter > 0) begin |
byteenable_single_bit_flag = 0; |
byteenable_continual_bit_flag = 1; |
byteenable_legal_flag = 0; |
end else if (!byteenable_single_bit_flag && |
!byteenable_continual_bit_flag && |
byteenable_bit_counter > 0) begin |
byteenable_legal_flag = 1; |
break; |
end |
byteenable_bit_counter++; |
end else begin |
if (byteenable_bit_counter > 0) begin |
if (byteenable_single_bit_flag && |
byteenable_bit_counter == 1) begin |
byteenable_single_bit_flag = 0; |
byteenable_continual_bit_flag = 0; |
byteenable_legal_flag = 0; |
end else if (byteenable_continual_bit_flag && |
byteenable_bit_counter > 1) begin |
if ((i != byteenable_bit_counter && |
i%byteenable_bit_counter == 0) || |
(i == byteenable_bit_counter && |
AV_NUMSYMBOLS%i == 0)) begin |
byteenable_single_bit_flag = 0; |
byteenable_continual_bit_flag = 0; |
byteenable_legal_flag = 0; |
end else begin |
byteenable_legal_flag = 1; |
break; |
end |
end |
end else |
byteenable_legal_flag = 0; |
end |
end |
if (byteenable_bit_counter != 1 && |
byteenable_bit_counter != 2 && |
byteenable_bit_counter%4 != 0 && |
byteenable_legal_flag == 0) begin |
byteenable_legal_flag = 1; |
end |
end |
|
// Counter for reset |
always @(clk) begin |
if (reset) begin |
write_transactionid_queued = {}; |
read_transactionid_queued = {}; |
write_burstcount_queued = {}; |
read_burstcount_queued = {}; |
fix_latency_queued = {}; |
write_response_burstcount = 0; |
read_response_burstcount = 0; |
temp_write_transactionid_queued = 0; |
temp_read_transactionid_queued = 0; |
fix_latency_queued_counter = 0; |
read_response_timeout_start_flag = 0; |
temp_read_response_timeout_counter = 0; |
read_burst_counter = 0; |
|
read_transaction_flag = 0; |
read_without_waitrequest_flag = 0; |
byteenable_legal_flag = 0; |
byteenable_single_bit_flag = 0; |
byteenable_continual_bit_flag = 0; |
write_burst_counter = 0; |
pending_read_counter = 0; |
write_burst_timeout_counter = 0; |
waitrequest_timeout_counter = 0; |
read_response_timeout_counter = 0; |
read_id = 0; |
readdatavalid_id = 0; |
byteenable_bit_counter = 0; |
reset_counter++; |
reset_flag[1] = 0; |
reset_flag[0] = 1; |
write_burst_completed = 0; |
round_over = 0; |
command_while_clken = 0; |
waitrequested_command_while_clken = 0; |
if ((reset_counter%2) == 1) |
reset_half_cycle_flag = 1; |
else |
reset_half_cycle_flag = 0; |
end |
if (reset == 0) begin |
reset_half_cycle_flag = 0; |
reset_counter = 0; |
end |
end |
|
// SVA assertion code lives within the following section block |
// which is disabled when the macro DISABLE_ALTERA_AVALON_SIM_SVA |
// is defined |
|
`ifdef DISABLE_ALTERA_AVALON_SIM_SVA |
// SVA assertion code has been disabled |
|
`else |
//-------------------------------------------------------------------------- |
// ASSERTION CODE BEGIN |
//-------------------------------------------------------------------------- |
//------------------------------------------------------------------------------- |
// =head2 Master Assertions |
// The following are the assertions code focus on Master component checking |
//------------------------------------------------------------------------------- |
|
//------------------------------------------------------------------------------- |
// =head3 a_half_cycle_reset_legal |
// This property checks if reset is asserted correctly |
//------------------------------------------------------------------------------- |
|
sequence s_reset_half_cycle; |
reset_half_cycle_flag ##0 |
$rose(clk); |
endsequence |
|
sequence s_reset_non_half_cycle; |
reset_half_cycle_flag && reset ##1 |
reset_counter > 1; |
endsequence |
|
property p_half_cycle_reset_legal; |
@(clk && enable_a_half_cycle_reset_legal) |
reset_half_cycle_flag |-> s_reset_half_cycle or |
s_reset_non_half_cycle; |
endproperty |
|
if (USE_BURSTCOUNT >= 0) begin: master_assertion_01 |
a_half_cycle_reset_legal: assert property(p_half_cycle_reset_legal) |
else begin |
-> event_a_half_cycle_reset_legal; |
print_assertion("reset must be held accross postive clock edge"); |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 a_no_read_during_reset |
// This property checks if read is deasserted while reset is asserted |
//------------------------------------------------------------------------------- |
|
property p_no_read_during_reset; |
@(clk && enable_a_no_read_during_reset) |
(reset_counter > 0 || reset_half_cycle_flag) && |
$rose(clk) |-> !read; |
endproperty |
|
if (USE_READ) begin: master_assertion_02 |
a_no_read_during_reset: assert property(p_no_read_during_reset) |
else begin |
-> event_a_no_read_during_reset; |
print_assertion("read must be deasserted while reset is asserted"); |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 a_no_write_during_reset |
// This property checks if write is deasserted while reset is asserted |
//------------------------------------------------------------------------------- |
|
property p_no_write_during_reset; |
@(clk && enable_a_no_write_during_reset) |
(reset_counter > 0 || reset_half_cycle_flag) && |
$rose(clk) |-> !write; |
endproperty |
|
if (USE_WRITE) begin: master_assertion_03 |
a_no_write_during_reset: assert property(p_no_write_during_reset) |
else begin |
-> event_a_no_write_during_reset; |
print_assertion("write must be deasserted while reset is asserted"); |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 a_exclusive_read_write |
// This property checks that read and write are not asserted simultaneously |
//------------------------------------------------------------------------------- |
|
property p_exclusive_read_write; |
@(posedge clk && enable_a_exclusive_read_write) |
disable iff (reset || (!clken && (USE_CLKEN))) |
read || write |-> $onehot({read, write}); |
endproperty |
|
if (USE_READ && USE_WRITE) begin: master_assertion_04 |
a_exclusive_read_write: assert property(p_exclusive_read_write) |
else begin |
-> event_a_exclusive_read_write; |
print_assertion("write and read were asserted simultaneously"); |
end |
end |
//------------------------------------------------------------------------------- |
// =head3 a_begintransfer_single_cycle |
// This property checks if begintransfer is asserted for only 1 cycle |
//------------------------------------------------------------------------------- |
|
sequence s_begintransfer_without_waitrequest; |
begintransfer && !waitrequest ##1 |
!begintransfer || (begintransfer && (read || write)); |
endsequence |
|
sequence s_begintransfer_with_waitrequest; |
begintransfer && waitrequest ##1 |
!begintransfer; |
endsequence |
|
property p_begintransfer_single_cycle; |
@(posedge clk && enable_a_begintransfer_single_cycle) |
disable iff (reset || (!clken && (USE_CLKEN))) |
begintransfer |-> s_begintransfer_without_waitrequest or |
s_begintransfer_with_waitrequest; |
endproperty |
|
if (USE_BEGIN_TRANSFER) begin: master_assertion_05 |
a_begintransfer_single_cycle: assert property(p_begintransfer_single_cycle) |
else begin |
-> event_a_begintransfer_single_cycle; |
print_assertion("begintransfer must be asserted for only 1 cycle"); |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 a_begintransfer_legal |
// This property checks if either read or write is asserted while |
// begintransfer is asserted |
//------------------------------------------------------------------------------- |
|
property p_begintransfer_legal; |
@(posedge clk && enable_a_begintransfer_legal) |
disable iff (reset || (!clken && (USE_CLKEN))) |
begintransfer |-> read || write; |
endproperty |
|
if (USE_BEGIN_TRANSFER) begin: master_assertion_06 |
a_begintransfer_legal: assert property(p_begintransfer_legal) |
else begin |
-> event_a_begintransfer_legal; |
print_assertion("neither read nor write was asserted with begintransfer"); |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 a_begintransfer_exist |
// This property checks if begintransfer is asserted during a transfer |
//------------------------------------------------------------------------------- |
|
property p_begintransfer_exist; |
@(posedge clk && enable_a_begintransfer_exist) |
disable iff (reset || (!clken && (USE_CLKEN))) |
($rose(read) || $rose(write)) || |
((write || read) && |
(!$fell(waitrequest) && !waitrequested_command_while_clken) && |
($rose(waitrequest) || !waitrequest)) |-> begintransfer; |
endproperty |
|
if (USE_BEGIN_TRANSFER) begin: master_assertion_07 |
a_begintransfer_exist: assert property(p_begintransfer_exist) |
else begin |
-> event_a_begintransfer_exist; |
print_assertion("begintransfer was deasserted during a transfer"); |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 a_beginbursttransfer_single_cycle |
// This property checks if beginbursttransfer is asserted for only 1 cycle |
//------------------------------------------------------------------------------- |
|
sequence s_beginbursttransfer_without_waitrequest; |
beginbursttransfer && !waitrequest && write_burst_counter == 0 ##1 |
!beginbursttransfer || (beginbursttransfer && (read || write)); |
endsequence |
|
sequence s_beginbursttransfer_with_waitrequest; |
beginbursttransfer && waitrequest && write_burst_counter == 0 ##1 |
!beginbursttransfer; |
endsequence |
|
property p_beginbursttransfer_single_cycle; |
@(posedge clk && enable_a_beginbursttransfer_single_cycle) |
disable iff (reset || (!clken && (USE_CLKEN))) |
beginbursttransfer |-> s_beginbursttransfer_without_waitrequest or |
s_beginbursttransfer_with_waitrequest; |
endproperty |
|
if (USE_BEGIN_BURST_TRANSFER) begin: master_assertion_08 |
a_beginbursttransfer_single_cycle: assert property(p_beginbursttransfer_single_cycle) |
else begin |
-> event_a_beginbursttransfer_single_cycle; |
print_assertion("beginbursttransfer must be asserted for only 1 cycle"); |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 a_beginbursttransfer_legal |
// This property checks if either read or write is asserted while |
// beginbursttransfer is asserted |
//------------------------------------------------------------------------------- |
|
property p_beginbursttransfer_legal; |
@(posedge clk && enable_a_beginbursttransfer_legal) |
disable iff (reset || (!clken && (USE_CLKEN))) |
beginbursttransfer |-> read || write; |
endproperty |
|
if (USE_BEGIN_BURST_TRANSFER) begin: master_assertion_09 |
a_beginbursttransfer_legal: assert property(p_beginbursttransfer_legal) |
else begin |
-> event_a_beginbursttransfer_legal; |
print_assertion("neither read nor write was asserted with beginbursttransfer"); |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 a_beginbursttransfer_exist |
// This property checks if beginbursttransfer is asserted during a transfer |
//------------------------------------------------------------------------------- |
|
property p_beginbursttransfer_exist; |
@(posedge clk && enable_a_beginbursttransfer_exist) |
disable iff (reset || (!clken && (USE_CLKEN))) |
(($rose(read) || $rose(write)) || |
((write || read) && |
(!$fell(waitrequest) && !waitrequested_command_while_clken) && |
($rose(waitrequest) || !waitrequest))) && |
write_burst_counter == 0 |-> beginbursttransfer; |
endproperty |
|
if (USE_BEGIN_BURST_TRANSFER) begin: master_assertion_10 |
a_beginbursttransfer_exist: assert property(p_beginbursttransfer_exist) |
else begin |
-> event_a_beginbursttransfer_exist; |
print_assertion("beginbursttransfer was deasserted during a transfer"); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_less_than_burstcount_max_size |
// This property checks if burstcount is less than or euqals to maxBurstSize |
//------------------------------------------------------------------------------ |
|
property p_less_than_burstcount_max_size; |
@(posedge clk && enable_a_less_than_burstcount_max_size) |
disable iff (reset || (!clken && (USE_CLKEN))) |
burstcount > 0 |-> burstcount <= AV_MAX_BURST; |
endproperty |
|
if (USE_BURSTCOUNT) begin: master_assertion_11 |
a_less_than_burstcount_max_size: assert property(p_less_than_burstcount_max_size) |
else begin |
-> event_a_less_than_burstcount_max_size; |
print_assertion("burstcount must be less than or equals to maxBurstSize"); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_byteenable_legal |
// This property checks if byteenalbe is a legal value |
//------------------------------------------------------------------------------ |
|
property p_byteenable_legal; |
@(posedge clk && enable_a_byteenable_legal) |
disable iff (reset || (!clken && (USE_CLKEN))) |
byteenable >= 0 |-> byteenable_legal_flag == 0; |
endproperty |
|
if (USE_BYTE_ENABLE) begin: master_assertion_12 |
a_byteenable_legal: assert property(p_byteenable_legal) |
else begin |
-> event_a_byteenable_legal; |
print_assertion("byteenable has an illegal value"); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_constant_during_waitrequest |
// This property checks if read, write, writedata, address, burstcount and |
// byteenable are constant while waitrequest is asserted |
//------------------------------------------------------------------------------ |
|
sequence s_waitrequest_with_read_constant_in_burst; |
(AV_CONSTANT_BURST_BEHAVIOR) && waitrequest && |
!$fell(waitrequest) && |
read ##1 read == $past(read) && |
address == $past(address) && |
burstcount == $past(burstcount) && |
byteenable == $past(byteenable); |
endsequence |
|
sequence s_waitrequest_with_read_inconstant_in_burst; |
!(AV_CONSTANT_BURST_BEHAVIOR) && waitrequest && |
!$fell(waitrequest) && |
read ##1 read == $past(read) && |
$isunknown(address)? $isunknown($past(address)): address == $past(address) && |
$isunknown(burstcount)? $isunknown($past(burstcount)): burstcount == $past(burstcount) && |
byteenable == $past(byteenable); |
endsequence |
|
sequence s_waitrequest_with_write_constant_in_burst; |
(AV_CONSTANT_BURST_BEHAVIOR) && waitrequest && |
!$fell(waitrequest) && |
write ##1 write == $past(write) && |
writedata == $past(writedata) && |
address == $past(address) && |
burstcount == $past(burstcount) && |
byteenable == $past(byteenable); |
endsequence |
|
sequence s_waitrequest_with_write_inconstant_in_burst; |
!(AV_CONSTANT_BURST_BEHAVIOR) && waitrequest && |
!$fell(waitrequest) && |
write ##1 write == $past(write) && |
writedata == $past(writedata) && |
$isunknown(address)? $isunknown($past(address)): address == $past(address) && |
$isunknown(burstcount)? $isunknown($past(burstcount)): burstcount == $past(burstcount) && |
byteenable == $past(byteenable); |
endsequence |
|
property p_constant_during_waitrequest; |
@(posedge clk && enable_a_constant_during_waitrequest) |
disable iff (reset || (!clken && (USE_CLKEN))) |
waitrequest && |
!$fell(waitrequest) && |
!reset && |
!$fell(reset) && |
(read || write) |-> s_waitrequest_with_read_constant_in_burst or s_waitrequest_with_write_constant_in_burst or |
s_waitrequest_with_read_inconstant_in_burst or s_waitrequest_with_write_inconstant_in_burst; |
endproperty |
|
if (USE_WAIT_REQUEST) begin: master_assertion_13 |
a_constant_during_waitrequest: |
assert property(p_constant_during_waitrequest) |
else begin |
-> event_a_constant_during_waitrequest; |
print_assertion("control signal(s) has changed while waitrequest is asserted"); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_constant_during_burst |
// This property checks if address, burstcount are constant |
// during write burst transfer |
//------------------------------------------------------------------------------ |
|
property p_constant_during_burst; |
@(posedge clk && enable_a_constant_during_burst) |
disable iff (reset || (!clken && (USE_CLKEN))) |
write_burst_counter > 0 |-> burstcount == $past(burstcount) && |
address == $past(address); |
endproperty |
|
if (USE_BURSTCOUNT && USE_WRITE && AV_CONSTANT_BURST_BEHAVIOR) begin: master_assertion_14 |
a_constant_during_burst: assert property(p_constant_during_burst) |
else begin |
-> event_a_constant_during_burst; |
print_assertion("control signal(s) has changed during write burst transfer"); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_burst_legal |
// This property checks if the total number of successive write is asserted and |
// equals to burstcount to complete a write burst transfer |
//------------------------------------------------------------------------------ |
|
property p_burst_legal; |
@(posedge clk && enable_a_burst_legal) |
disable iff (reset || (!clken && (USE_CLKEN))) |
(beginbursttransfer || $rose(read)) |-> write_burst_counter == 0; |
endproperty |
|
if (USE_BURSTCOUNT && USE_WRITE && |
(USE_READ || USE_BEGIN_BURST_TRANSFER)) begin: master_assertion_15 |
a_burst_legal: assert property(p_burst_legal) |
else begin |
-> event_a_burst_legal; |
print_assertion("insufficient write were asserted during burst transfer"); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_constant_during_clk_disabled |
// This property checks if all the signals are constant while clken is |
// deasserted. |
//------------------------------------------------------------------------------ |
|
sequence s_constant_during_clk_disabled_command; |
clken == 0 ##1 waitrequest === $past(waitrequest) && |
burstcount === $past(burstcount) && |
address === $past(address) && |
waitrequest === $past(waitrequest) && |
write === $past(write) && |
read === $past(read) && |
byteenable === $past(byteenable) && |
beginbursttransfer === $past(beginbursttransfer) && |
begintransfer === $past(begintransfer) && |
writedata === $past(writedata) && |
arbiterlock === $past(arbiterlock) && |
lock === $past(lock) && |
debugaccess === $past(debugaccess) |
; |
endsequence |
|
sequence s_constant_during_clk_disabled_response; |
clken == 0 ##0 readdatavalid === $past(readdatavalid) && |
readdata === $past(readdata) && |
response === $past(response) && |
writeresponsevalid === $past(writeresponsevalid) |
; |
endsequence |
|
property p_constant_during_clk_disabled; |
@(posedge clk && enable_a_constant_during_clk_disabled) |
disable iff (reset) |
clken == 0 |-> s_constant_during_clk_disabled_response and |
s_constant_during_clk_disabled_command |
; |
endproperty |
|
if (USE_CLKEN) begin: master_assertion_16 |
a_constant_during_clk_disabled: assert property(p_constant_during_clk_disabled) |
else begin |
-> event_a_constant_during_clk_disabled; |
print_assertion("signal(s) change while clken is deasserted."); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_address_align_with_data_width |
// This property checks if master is using byte address, the address must be |
// aligned with the data width. |
//------------------------------------------------------------------------------ |
|
property p_address_align_with_data_width; |
@(posedge clk && enable_a_address_align_with_data_width) |
disable iff (reset || (!clken && (USE_CLKEN))) |
((read || write) && !waitrequest) && |
(write_burst_counter == 0) |-> (address%AV_NUMSYMBOLS) == 0; |
endproperty |
|
if (USE_ADDRESS && (SLAVE_ADDRESS_TYPE == "SYMBOLS")) begin: master_assertion_17 |
a_address_align_with_data_width: assert property(p_address_align_with_data_width) |
else begin |
-> event_a_burst_legal; |
print_assertion("address is not align with data width"); |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head2 Slave Assertions |
// The following are the assertions code focus on Slave component checking |
//------------------------------------------------------------------------------- |
|
//------------------------------------------------------------------------------- |
// =head3 a_waitrequest_during_reset |
// This property checks if waitrequest is asserted while reset is asserted |
//------------------------------------------------------------------------------- |
|
property p_waitrequest_during_reset; |
@(clk && enable_a_waitrequest_during_reset) |
(reset_counter > 0 || reset_half_cycle_flag) && |
($rose(clk) || $fell(clk)) && !$fell(reset) |-> waitrequest; |
endproperty |
|
if (USE_WAIT_REQUEST) begin: slave_assertion_01 |
a_waitrequest_during_reset: assert property(p_waitrequest_during_reset) |
else begin |
-> event_a_waitrequest_during_reset; |
print_assertion("waitrequest must be asserted while reset is asserted"); |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 a_no_readdatavalid_during_reset |
// This property checks if readdatavalid is deasserted while reset is asserted |
//------------------------------------------------------------------------------- |
|
property p_no_readdatavalid_during_reset; |
@(clk && enable_a_no_readdatavalid_during_reset) |
(reset_counter > 0 || reset_half_cycle_flag) && |
$rose(clk) |-> !readdatavalid; |
endproperty |
|
if (USE_READ_DATA_VALID) begin: slave_assertion_02 |
a_no_readdatavalid_during_reset: assert property(p_no_readdatavalid_during_reset) |
else begin |
-> event_a_no_readdatavalid_during_reset; |
print_assertion("readdatavalid must be deasserted while reset is asserted"); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_less_than_maximumpendingreadtransactions |
// This property checks if pipelined pending read count is less than |
// maximumPendingReadTransaction |
//------------------------------------------------------------------------------ |
|
property p_less_than_maximumpendingreadtransactions; |
@(posedge clk && enable_a_less_than_maximumpendingreadtransactions) |
disable iff (reset || (!clken && (USE_CLKEN))) |
pending_read_counter > 0 |-> |
pending_read_counter <= (((read && (waitrequest == 1)) || (read && readdatavalid))? |
AV_MAX_PENDING_READS+1:AV_MAX_PENDING_READS); |
endproperty |
|
if (USE_READ && USE_READ_DATA_VALID && AV_MAX_PENDING_READS > 0) begin: slave_assertion_03 |
a_less_than_maximumpendingreadtransactions: |
assert property(p_less_than_maximumpendingreadtransactions) |
else begin |
-> event_a_less_than_maximumpendingreadtransactions; |
print_assertion("pending read must be within maximumPendingReadTransactions"); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_read_response_sequence |
// This property checks if readdatavalid is asserted while read is asserted for |
// the same read transfer |
//------------------------------------------------------------------------------ |
|
sequence s_read_response_sequence_0; |
!read && (readdatavalid_id < read_id) ##1 (round_over == 0); |
endsequence |
|
sequence s_read_response_sequence_1; |
read && ($past(waitrequest) == 1) && ($past(read) == 1) && |
(readdatavalid_id < read_id-1) ##1 (round_over == 0); |
endsequence |
|
sequence s_read_response_sequence_2; |
((read && ($past(waitrequest) == 0)) || ($rose(read))) && |
(readdatavalid_id < read_id) ##1 (round_over == 0); |
endsequence |
|
sequence s_read_response_sequence_3; |
!read && (readdatavalid_id > read_id) ##1 (round_over == 1); |
endsequence |
|
sequence s_read_response_sequence_4; |
read && ($past(waitrequest) == 1) && ($past(read) == 1) && |
(read_id == 0)?(readdatavalid_id < MAX_ID):(readdatavalid_id > read_id-1) ##1 (round_over == 1); |
endsequence |
|
sequence s_read_response_sequence_5; |
((read && ($past(waitrequest) == 0)) || ($rose(read))) && |
(readdatavalid_id > read_id) ##1 (round_over == 1); |
endsequence |
|
property p_read_response_sequence; |
@(posedge clk && enable_a_read_response_sequence) |
disable iff (reset || (!clken && (USE_CLKEN))) |
readdatavalid |-> s_read_response_sequence_0 or |
s_read_response_sequence_1 or |
s_read_response_sequence_2 or |
s_read_response_sequence_3 or |
s_read_response_sequence_4 or |
s_read_response_sequence_5; |
endproperty |
|
if (USE_READ_DATA_VALID && USE_READ) begin: slave_assertion_04 |
a_read_response_sequence: assert property(p_read_response_sequence) |
else begin |
-> event_a_read_response_sequence; |
print_assertion("readdatavalid must be asserted after read command"); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_readid_sequence |
// This property checks if readid return follow the sequence of transactionid |
// asserted. |
//------------------------------------------------------------------------------ |
|
property p_readid_sequence; |
@(posedge clk && enable_a_readid_sequence) |
disable iff (reset || (!clken && (USE_CLKEN))) |
(readdatavalid || ((!USE_READ_DATA_VALID) && |
(fix_latency_queued_counter == (AV_FIX_READ_LATENCY)))) |-> |
readid == temp_read_transactionid_queued; |
endproperty |
|
if (USE_TRANSACTIONID) begin: slave_assertion_05 |
a_readid_sequence: assert property(p_readid_sequence) |
else begin |
-> event_a_readid_sequence; |
print_assertion("readid did not match transactionid."); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_writeid_sequence |
// This property checks if writeid return follow the sequence of transactionid |
// asserted. |
//------------------------------------------------------------------------------ |
|
property p_writeid_sequence; |
@(posedge clk && enable_a_writeid_sequence) |
disable iff (reset || (!clken && (USE_CLKEN))) |
writeresponsevalid |-> writeid == temp_write_transactionid_queued; |
endproperty |
|
if (USE_TRANSACTIONID) begin: slave_assertion_06 |
a_writeid_sequence: assert property(p_writeid_sequence) |
else begin |
-> event_a_writeid_sequence; |
print_assertion("writeid did not match the transactionid."); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_register_incoming_signals |
// This property checks if waitrequest is asserted all the times except |
// deasserted at the single clock cycle after read/write transaction happen. |
//------------------------------------------------------------------------------ |
|
sequence s_register_incoming_signals_with_waitrequested_command; |
((read && waitrequest) || (write && waitrequest)) ##[1:$] !waitrequest ##1 waitrequest; |
endsequence |
|
sequence s_register_incoming_signals_without_command; |
(!write && !read) ##0 waitrequest; |
endsequence |
|
sequence s_register_incoming_signals_read; |
(read && !waitrequest) ##0 (read === $past(read) && $past(waitrequest) == 1) ##1 |
waitrequest; |
endsequence |
|
sequence s_register_incoming_signals_write; |
(write && !waitrequest) ##0 (write === $past(write) && $past(waitrequest) == 1) ##1 |
waitrequest; |
endsequence |
|
property p_register_incoming_signals; |
@(posedge clk && enable_a_register_incoming_signals) |
disable iff (!clken && (USE_CLKEN)) |
enable_a_register_incoming_signals |-> s_register_incoming_signals_read or |
s_register_incoming_signals_write or |
s_register_incoming_signals_without_command or |
s_register_incoming_signals_with_waitrequested_command; |
endproperty |
|
if (AV_REGISTERINCOMINGSIGNALS) begin: slave_assertion_07 |
a_register_incoming_signals: |
assert property(p_register_incoming_signals) |
else begin |
-> event_a_register_incoming_signals; |
print_assertion("waitrequest not asserted in first cycle of transaction."); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_unrequested_write_response |
// This property checks for write response to occur only when there is |
// request for write response |
//------------------------------------------------------------------------------ |
|
property p_unrequested_write_response; |
@(posedge clk && enable_a_unrequested_write_response) |
disable iff (reset || (!clken && (USE_CLKEN))) |
pending_write_response == 0 |-> !writeresponsevalid; |
endproperty |
|
if (USE_WRITE && USE_WRITERESPONSE) begin: slave_assertion_08 |
a_unrequested_write_response: assert property(p_unrequested_write_response) |
else begin |
-> event_a_unrequested_write_response; |
print_assertion("write response must only happen when write response is requested"); |
end |
end |
//------------------------------------------------------------------------------- |
// =head2 Timeout Assertions |
// The following are the assertions code focus on timeout checking |
//------------------------------------------------------------------------------- |
|
//------------------------------------------------------------------------------ |
// =head3 a_write_burst_timeout |
// This property checks if write burst transfer is completed within timeout |
// period |
//------------------------------------------------------------------------------ |
|
property p_write_burst_timeout; |
@(posedge clk && enable_a_write_burst_timeout) |
disable iff (reset || (!clken && (USE_CLKEN))) |
write_burst_counter > 0 |-> |
write_burst_timeout_counter <= AV_WRITE_TIMEOUT; |
endproperty |
|
if (USE_BURSTCOUNT && USE_WRITE && AV_WRITE_TIMEOUT > 0) begin: timeout_assertion_01 |
a_write_burst_timeout: assert property(p_write_burst_timeout) |
else begin |
-> event_a_write_burst_timeout; |
print_assertion("write burst transfer must be completed within timeout period"); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_waitrequest_timeout |
// This property checks if waitrequest is asserted continously for more than |
// maximum allowed timeout period |
//------------------------------------------------------------------------------ |
|
property p_waitrequest_timeout; |
@(posedge clk && enable_a_waitrequest_timeout) |
waitrequest_timeout_counter > 0 |-> |
waitrequest_timeout_counter <= AV_WAITREQUEST_TIMEOUT; |
endproperty |
|
if (USE_WAIT_REQUEST && AV_WAITREQUEST_TIMEOUT > 0) begin: timeout_assertion_02 |
a_waitrequest_timeout: assert property(p_waitrequest_timeout) |
else begin |
-> event_a_waitrequest_timeout; |
print_assertion("continuous waitrequest must be within timeout period"); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_read_response_timeout |
// This property checks if readdatavalid is asserted within timeout period |
// =cut |
//------------------------------------------------------------------------------ |
|
property p_read_response_timeout; |
@(posedge clk && enable_a_read_response_timeout) |
disable iff (reset || (!clken && (USE_CLKEN))) |
temp_read_response_timeout_counter[readdatavalid_id] > 0 |-> |
temp_read_response_timeout_counter[readdatavalid_id] <= AV_READ_TIMEOUT; |
endproperty |
|
if (USE_READ && USE_READ_DATA_VALID && AV_READ_TIMEOUT > 0) begin: timeout_assertion_03 |
a_read_response_timeout: assert property(p_read_response_timeout) |
else begin |
-> event_a_read_response_timeout; |
print_assertion("readdatavalid must be asserted within timeout period"); |
end |
end |
|
//------------------------------------------------------------------------------ |
// =head3 a_write_response_timeout |
// This property checks if write response happens within timeout |
// period after completed write command |
//------------------------------------------------------------------------------ |
|
property p_write_response_timeout; |
@(posedge clk && enable_a_write_response_timeout) |
disable iff (reset || (!clken && (USE_CLKEN))) |
write_response_timeout_counter[0] > 0 |-> |
write_response_timeout_counter[0] <= write_response_timeout; |
endproperty |
|
if (USE_WRITE && USE_WRITERESPONSE > 0) begin: timeout_assertion_04 |
a_write_response_timeout: assert property(p_write_response_timeout) |
else begin |
-> event_a_write_response_timeout; |
print_assertion("write response must happens within timeout period after completed write command"); |
end |
end |
|
//-------------------------------------------------------------------------- |
// ASSERTION CODE END |
//-------------------------------------------------------------------------- |
`endif |
|
// synthesis translate_on |
|
endmodule |
/sim/src/amm_monitor/altera_avalon_mm_monitor_coverage.sv
0,0 → 1,2633
// (C) 2001-2016 Intel Corporation. All rights reserved. |
// Your use of Intel Corporation's design tools, logic functions and other |
// software and tools, and its AMPP partner logic functions, and any output |
// files any of the foregoing (including device programming or simulation |
// files), and any associated documentation or information are expressly subject |
// to the terms and conditions of the Intel Program License Subscription |
// Agreement, Intel MegaCore Function License Agreement, or other applicable |
// license agreement, including, without limitation, that your use is for the |
// sole purpose of programming logic devices manufactured by Intel and sold by |
// Intel or its authorized distributors. Please refer to the applicable |
// agreement for further details. |
|
|
// $File: //acds/rel/16.1/ip/sopc/components/verification/altera_avalon_mm_monitor_bfm/altera_avalon_mm_monitor_coverage.sv $ |
// $Revision: #1 $ |
// $Date: 2016/08/07 $ |
//----------------------------------------------------------------------------- |
// =head1 NAME |
// altera_avalon_mm_monitor_coverage |
// =head1 SYNOPSIS |
// Memory Mapped Avalon Bus Protocol Checker |
//----------------------------------------------------------------------------- |
// =head1 DESCRIPTION |
// This module implements Avalon MM protocol coverage for simulation. |
//----------------------------------------------------------------------------- |
|
`timescale 1ps / 1ps |
|
module altera_avalon_mm_monitor_coverage( |
clk, |
reset, |
tap |
); |
|
// =head1 PARAMETERS |
parameter AV_ADDRESS_W = 32; // address width |
parameter AV_SYMBOL_W = 8; // default symbol is byte |
parameter AV_NUMSYMBOLS = 4; // number of symbols per word |
parameter AV_BURSTCOUNT_W = 3; // burst port width |
|
parameter AV_BURST_LINEWRAP = 0; // line wrapping addr is set to 1 |
parameter AV_BURST_BNDR_ONLY = 0; // addr is multiple of burst size |
parameter REGISTER_WAITREQUEST = 0; // Waitrequest is registered at the slave |
parameter AV_MAX_PENDING_READS = 1; // maximum pending read transfer count |
parameter AV_MAX_PENDING_WRITES = 0; // maximum pending write transfer count |
parameter AV_FIX_READ_LATENCY = 0; // fixed read latency in cycles |
|
parameter USE_READ = 1; // use read port |
parameter USE_WRITE = 1; // use write port |
parameter USE_ADDRESS = 1; // use address port |
parameter USE_BYTE_ENABLE = 1; // use byteenable port |
parameter USE_BURSTCOUNT = 0; // use burstcount port |
parameter USE_READ_DATA = 1; // use readdata port |
parameter USE_READ_DATA_VALID = 1; // use readdatavalid port |
parameter USE_WRITE_DATA = 1; // use writedata port |
parameter USE_BEGIN_TRANSFER = 0; // use begintransfer port |
parameter USE_BEGIN_BURST_TRANSFER = 0; // use begintbursttransfer port |
parameter USE_WAIT_REQUEST = 1; // use waitrequest port |
parameter USE_ARBITERLOCK = 0; // Use arbiterlock pin on interface |
parameter USE_LOCK = 0; // Use lock pin on interface |
parameter USE_DEBUGACCESS = 0; // Use debugaccess pin on interface |
parameter USE_TRANSACTIONID = 0; // Use transactionid interface pin |
parameter USE_WRITERESPONSE = 0; // Use write response interface pins |
parameter USE_READRESPONSE = 0; // Use read response interface pins |
parameter USE_CLKEN = 0; // Use clken interface pins |
|
parameter AV_MAX_READ_LATENCY = 100; // maximum read latency cycle for coverage |
parameter AV_MAX_WAITREQUESTED_READ = 100; // maximum waitrequested read cycle for coverage |
parameter AV_MAX_WAITREQUESTED_WRITE = 100; // maximum waitrequested write cycle for coverage |
parameter AV_MAX_CONTINUOUS_READ = 5; // maximum continuous read cycle for coverage |
parameter AV_MAX_CONTINUOUS_WRITE = 5; // maximum continuous write cycle for coverage |
parameter AV_MAX_CONTINUOUS_WAITREQUEST = 5; // maximum continuous waitrequest cycle for coverage |
parameter AV_MAX_CONTINUOUS_READDATAVALID = 5; // maximum continuous readdatavalid cycle for coverage |
|
parameter AV_READ_WAIT_TIME = 0; // Fixed wait time cycles when |
parameter AV_WRITE_WAIT_TIME = 0; // USE_WAIT_REQUEST is 0 |
|
localparam AV_DATA_W = AV_SYMBOL_W * AV_NUMSYMBOLS; |
localparam AV_MAX_BURST = USE_BURSTCOUNT ? 2**(lindex(AV_BURSTCOUNT_W)) : 1; |
localparam INT_WIDTH = 32; |
localparam MAX_ID = (AV_MAX_PENDING_READS*AV_MAX_BURST > 100? AV_MAX_PENDING_READS*AV_MAX_BURST:100); |
localparam AV_TRANSACTIONID_W = 8; |
|
localparam TAP_W = 1 + // clken |
1 + // arbiterlock |
1 + // lock |
1 + // debugaccess |
((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) + // transactionid |
((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) + // readid |
((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) + // writeid |
2 + // response |
1 + // writeresponserequest |
1 + // writeresponsevalid |
1 + // waitrequest |
1 + // readdatavalid |
((AV_DATA_W == 0)? 1:AV_DATA_W) + // readdata |
1 + // write |
1 + // read |
((AV_ADDRESS_W == 0)? 1:AV_ADDRESS_W) + // address |
((AV_NUMSYMBOLS == 0)? 1:AV_NUMSYMBOLS) + // byteenable |
((AV_BURSTCOUNT_W == 0)? 1:AV_BURSTCOUNT_W) + // burstcount |
1 + // beginbursttransfer |
1 + // begintransfer |
((AV_DATA_W == 0)? 1:AV_DATA_W); // writedata |
|
// =head1 PINS |
// =head2 Clock Interface |
input clk; |
input reset; |
|
// =head2 Avalon Monitor Interface |
// Interface consists of Avalon Memory-Mapped Interface. |
// =cut |
|
// =pod |
input [TAP_W-1:0] tap; |
// =cut |
|
function int lindex; |
// returns the left index for a vector having a declared width |
// when width is 0, then the left index is set to 0 rather than -1 |
input [31:0] width; |
lindex = (width > 0) ? (width-1) : 0; |
endfunction |
|
function automatic int __floor1( |
bit [31:0] arg |
); |
__floor1 = (arg <1) ? 1 : arg; |
endfunction |
|
//-------------------------------------------------------------------------- |
// synthesis translate_off |
|
import verbosity_pkg::*; |
import avalon_mm_pkg::*; |
|
typedef bit [lindex(AV_ADDRESS_W):0] AvalonAddress_t; |
typedef bit [lindex(AV_BURSTCOUNT_W):0] AvalonBurstCount_t; |
typedef bit [AV_MAX_BURST-1:0][AV_DATA_W-1:0] AvalonData_t; |
typedef bit [AV_MAX_BURST-1:0][AV_NUMSYMBOLS-1:0] AvalonByteEnable_t; |
typedef bit [AV_MAX_BURST-1:0][INT_WIDTH-1:0] AvalonLatency_t; |
typedef bit [AV_MAX_BURST-1:0][1:0] AvalonReadResponseStatus_t; |
|
typedef struct packed { |
Request_t request; |
AvalonAddress_t address; // start address |
AvalonBurstCount_t burst_count; // burst length |
AvalonData_t data; // write data |
AvalonByteEnable_t byte_enable; // hot encoded |
int burst_cycle; |
logic write_response_request; |
} SlaveCommand_t; |
|
typedef struct packed { |
Request_t request; |
AvalonAddress_t address; // start addr |
AvalonBurstCount_t burst_count; // burst length |
AvalonData_t data; // read data |
AvalonLatency_t read_latency; |
AvalonLatency_t wait_latency; |
AvalonReadResponseStatus_t read_response; |
AvalonResponseStatus_t write_response; |
} MasterResponse_t; |
|
|
string message = "*unitialized*"; |
|
bit covergroup_settings_changed_flag = 0; |
bit [1:0] reset_flag = 2'b11; |
bit read_transaction_flag = 0; |
bit read_without_waitrequest_flag = 0; |
bit idle_write_flag = 0; |
logic [MAX_ID:0] idle_read_flag = 0; |
bit idle_in_write_burst_flag = 0; |
logic [MAX_ID:0] read_latency_start_flag = 0; |
|
bit enable_c_read_byteenable = 1; |
bit enable_c_write_byteenable = 1; |
bit enable_c_read_burstcount = 1; |
bit enable_c_write_burstcount = 1; |
bit enable_c_pending_read = 1; |
bit enable_c_read = 1; |
bit enable_c_write = 1; |
bit enable_c_b2b_read_read = 1; |
bit enable_c_b2b_read_write = 1; |
bit enable_c_b2b_write_write = 1; |
bit enable_c_b2b_write_read = 1; |
bit enable_c_idle_in_write_burst = 1; |
bit enable_c_idle_in_read_response = 1; |
bit enable_c_read_latency = 1; |
bit enable_c_waitrequested_read = 1; |
bit enable_c_waitrequested_write = 1; |
bit enable_c_continuous_waitrequest_from_idle_to_write = 1; |
bit enable_c_continuous_waitrequest_from_idle_to_read = 1; |
bit enable_c_waitrequest_without_command = 1; |
bit enable_c_idle_before_transaction = 1; |
bit enable_c_continuous_read = 1; |
bit enable_c_continuous_write = 1; |
bit enable_c_continuous_readdatavalid = 1; |
bit enable_c_continuous_waitrequest = 1; |
bit enable_c_waitrequest_in_write_burst = 1; |
bit enable_c_readresponse = 0; |
bit enable_c_writeresponse = 0; |
bit enable_c_write_after_reset = 1; |
bit enable_c_read_after_reset = 1; |
bit enable_c_write_response = 1; |
bit enable_c_read_response = 1; |
bit enable_c_write_response_transition = 1; |
bit enable_c_read_response_transition = 1; |
|
int read_command_while_clken = 0; |
int write_command_while_clken = 0; |
int waitrequested_command_while_clken = 0; |
int write_burst_counter = 0; |
logic [MAX_ID:0][31:0] read_burst_counter = 0; |
int temp_read_burst_counter = 0; |
int pending_read_counter = 0; |
int fix_read_latency_counter = 0; |
int idle_in_read_response = 0; |
logic [MAX_ID:0][31:0] temp_idle_in_read_response = 0; |
int temp_waitrequested_read_counter = 0; |
int waitrequested_read_counter = 0; |
int temp_waitrequested_write_counter = 0; |
int waitrequested_write_counter = 0; |
int byteenable_counter = 0; |
logic [MAX_ID:0][31:0] temp_read_latency_counter = 0; |
int read_latency_counter = 0; |
int read_id = 0; |
int readdatavalid_id = 0; |
bit waitrequest_before_waitrequested_read = 0; |
bit waitrequest_before_waitrequested_write = 0; |
bit waitrequest_before_command = 0; |
bit waitrequest_without_command = 0; |
logic past_waitrequest = 0; |
logic idle_before_burst_transaction = 0; |
logic idle_before_burst_transaction_sampled = 0; |
logic continuous_read_sampled = 0; |
logic continuous_read_start_flag = 0; |
logic [31:0] continuous_read = 0; |
logic continuous_write_sampled = 0; |
logic continuous_write_start_flag = 0; |
logic [31:0] continuous_write = 0; |
logic continuous_readdatavalid_sampled = 0; |
logic continuous_readdatavalid_start_flag = 0; |
logic [31:0] continuous_readdatavalid = 0; |
logic continuous_waitrequest_sampled = 0; |
logic continuous_waitrequest_start_flag = 0; |
logic [31:0] continuous_waitrequest = 0; |
logic idle_in_write_burst_with_waitrequest = 0; |
logic idle_in_write_burst_with_waitrequest_sampled = 0; |
logic idle_in_write_burst_start_flag = 0; |
logic idle_before_burst_transaction_with_waitrequest = 0; |
logic idle_before_burst_transaction_with_waitrequest_sampled = 0; |
logic [31:0] waitrequested_before_transaction = 0; |
logic write_after_reset = 0; |
logic read_after_reset = 0; |
int fix_latency_queued[$]; |
int fix_latency_queued_counter = 0; |
logic read_reset_transaction = 0; |
logic write_reset_transaction = 0; |
logic burst_waitrequested_command = 0; |
logic [31:0] readresponse_bit_num = 0; |
logic [31:0] writeresponse_bit_num = 0; |
AvalonResponseStatus_t read_response; |
AvalonResponseStatus_t write_response; |
logic [3:0] write_response_transition = 4'bx; |
logic [3:0] read_response_transition = 4'bx; |
|
logic [3:0] b2b_transfer = 4'b1111; |
logic [AV_NUMSYMBOLS-1:0] check_byteenable = 0; |
logic [AV_NUMSYMBOLS-1:0] legal_byteenable[(AV_NUMSYMBOLS*2)-1:0]; |
|
logic byteenable_1_bit = 1'b1; |
logic [1:0] byteenable_2_bit = 2'b11; |
logic [3:0] byteenable_4_bit = 4'hf; |
logic [7:0] byteenable_8_bit = 8'hff; |
logic [15:0] byteenable_16_bit = 16'hffff; |
logic [31:0] byteenable_32_bit = 32'hffffffff; |
logic [63:0] byteenable_64_bit = 64'hffffffffffffffff; |
logic [127:0] byteenable_128_bit = 128'hffffffffffffffffffffffffffffffff; |
|
//-------------------------------------------------------------------------- |
// unpack Avalon bus interface tap into individual port signals |
|
logic waitrequest; |
logic readdatavalid; |
logic [lindex(AV_DATA_W):0] readdata; |
logic write; |
logic read; |
logic [lindex(AV_ADDRESS_W):0] address; |
logic [31:0] byteenable; |
logic [lindex(AV_BURSTCOUNT_W):0] burstcount; |
logic beginbursttransfer; |
logic begintransfer; |
logic [lindex(AV_DATA_W):0] writedata; |
|
logic arbiterlock; |
logic lock; |
logic debugaccess; |
|
logic [lindex(AV_TRANSACTIONID_W):0] transactionid; |
logic [lindex(AV_TRANSACTIONID_W):0] readid; |
logic [lindex(AV_TRANSACTIONID_W):0] writeid; |
logic [1:0] response; |
logic writeresponserequest; |
logic writeresponsevalid; |
logic clken; |
|
always_comb begin |
clken <= (USE_CLKEN == 1)? |
tap[3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+21: |
3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+21] : 1; |
|
arbiterlock <= (USE_ARBITERLOCK == 1)? |
tap[3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+20: |
3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+20] : 0; |
|
lock <= (USE_LOCK == 1)? |
tap[3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+19: |
3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+19] : 0; |
|
debugaccess <= (USE_DEBUGACCESS == 1)? |
tap[3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+18: |
3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+18] : 0; |
|
transactionid <= (USE_TRANSACTIONID == 1)? |
tap[3*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+17: |
2*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+17] : 0; |
|
readid <= (USE_READRESPONSE == 1)? |
tap[2*(lindex(AV_TRANSACTIONID_W))+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+16: |
lindex(AV_TRANSACTIONID_W)+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+16] : 0; |
|
writeid <= (USE_WRITERESPONSE == 1)? |
tap[lindex(AV_TRANSACTIONID_W)+2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+15: |
2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+15] : 0; |
|
response <= (USE_WRITERESPONSE == 1 || USE_READRESPONSE == 1)? |
tap[2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+14: |
2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+13] : 0; |
|
writeresponserequest <= (USE_WRITERESPONSE == 1)? |
tap[2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+12: |
2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+12] : 0; |
|
writeresponsevalid <= (USE_WRITERESPONSE == 1)? |
tap[2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+11: |
2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+11] : 0; |
|
waitrequest <= tap[2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+10: |
2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+10]; |
|
readdatavalid <= (USE_READ_DATA_VALID == 1)? |
tap[2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+9: |
2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+9] : 0; |
|
readdata <= (USE_READ_DATA == 1)? |
tap[2*(lindex(AV_DATA_W))+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+8: |
lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+8] : 0; |
|
write <= (USE_WRITE == 1)? |
tap[lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+7: |
lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+7] : 0; |
|
read <= (USE_READ == 1)? |
tap[lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+6: |
lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+6] : 0; |
|
address <= (USE_ADDRESS == 1)? |
tap[lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+lindex(AV_ADDRESS_W)+5: |
lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+5] : 0; |
|
byteenable <= (USE_BYTE_ENABLE == 1)? |
tap[lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+lindex(AV_NUMSYMBOLS)+4: |
lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+4] : 0; |
|
burstcount <= (USE_BURSTCOUNT == 1)? |
tap[lindex(AV_DATA_W)+lindex(AV_BURSTCOUNT_W)+3: lindex(AV_DATA_W)+3] : 1; |
|
beginbursttransfer <= (USE_BEGIN_BURST_TRANSFER == 1)? |
tap[lindex(AV_DATA_W)+2:lindex(AV_DATA_W)+2] : 0; |
|
begintransfer <= (USE_BEGIN_TRANSFER == 1)? tap[lindex(AV_DATA_W)+1:lindex(AV_DATA_W)+1] : 0; |
|
writedata <= (USE_WRITE_DATA == 1)? tap[lindex(AV_DATA_W):0] : 0; |
end |
|
//-------------------------------------------------------------------------- |
// =head1 Public Methods API |
// This section describes the public methods in the application programming |
// interface (API). In this case the application program is the test bench |
// which instantiates and controls and queries state of this component. |
// Test programs must only use these public access methods and events to |
// communicate with this BFM component. The API and the module pins |
// are the only interfaces in this component that are guaranteed to be |
// stable. The API will be maintained for the life of the product. |
// While we cannot prevent a test program from directly accessing internal |
// tasks, functions, or data private to the BFM, there is no guarantee that |
// these will be present in the future. In fact, it is best for the user |
// to assume that the underlying implementation of this component can |
// and will change. |
// =cut |
//-------------------------------------------------------------------------- |
|
// Master Coverages API |
function automatic void set_enable_c_read_byteenable( // public |
bit cover_enable |
); |
// enable or disable c_read_byteenable cover group |
|
enable_c_read_byteenable = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_read_byteenable"); |
endfunction |
|
function automatic void set_enable_c_write_byteenable( // public |
bit cover_enable |
); |
// enable or disable c_write_byteenable cover group |
|
enable_c_write_byteenable = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_write_byteenable"); |
endfunction |
|
function automatic void set_enable_c_read_burstcount( // public |
bit cover_enable |
); |
// enable or disable c_read_burstcount cover group |
|
enable_c_read_burstcount = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_read_burstcount"); |
endfunction |
|
function automatic void set_enable_c_write_burstcount( // public |
bit cover_enable |
); |
// enable or disable c_write_burstcount cover group |
|
enable_c_write_burstcount = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_write_burstcount"); |
endfunction |
|
function automatic void set_enable_c_pending_read( // public |
bit cover_enable |
); |
// enable or disable c_pending_read cover group |
|
enable_c_pending_read = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_pending_read"); |
endfunction |
|
function automatic void set_enable_c_read( // public |
bit cover_enable |
); |
// enable or disable c_read cover group |
|
enable_c_read = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_read"); |
endfunction |
|
function automatic void set_enable_c_write( // public |
bit cover_enable |
); |
// enable or disable c_write cover group |
|
enable_c_write = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_write"); |
endfunction |
|
function automatic void set_enable_c_b2b_read_read( // public |
bit cover_enable |
); |
// enable or disable c_b2b_read_read cover group |
|
enable_c_b2b_read_read = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_b2b_read_read"); |
endfunction |
|
function automatic void set_enable_c_b2b_read_write( // public |
bit cover_enable |
); |
// enable or disable c_b2b_read_write cover group |
|
enable_c_b2b_read_write = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_b2b_read_write"); |
endfunction |
|
function automatic void set_enable_c_b2b_write_write( // public |
bit cover_enable |
); |
// enable or disable c_b2b_write_write cover group |
|
enable_c_b2b_write_write = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_b2b_write_write"); |
endfunction |
|
function automatic void set_enable_c_b2b_write_read( // public |
bit cover_enable |
); |
// enable or disable c_b2b_write_read cover group |
|
enable_c_b2b_write_read = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_b2b_write_read"); |
endfunction |
|
function automatic void set_enable_c_idle_in_write_burst( // public |
bit cover_enable |
); |
// enable or disable c_idle_in_write_burst cover group |
|
enable_c_idle_in_write_burst = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_idle_in_write_burst"); |
endfunction |
|
// Slave Coverages API |
function automatic void set_enable_c_idle_in_read_response( // public |
bit cover_enable |
); |
// enable or disable c_idle_in_read_response cover group |
|
enable_c_idle_in_read_response = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_idle_in_read_response"); |
endfunction |
|
function automatic void set_enable_c_read_latency( // public |
bit cover_enable |
); |
// enable or disable c_read_latency cover group |
|
enable_c_read_latency = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_read_latency"); |
endfunction |
|
function automatic void set_enable_c_waitrequested_read( // public |
bit cover_enable |
); |
// enable or disable c_waitrequested_read cover group |
|
enable_c_waitrequested_read = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_waitrequested_read"); |
endfunction |
|
function automatic void set_enable_c_waitrequested_write( // public |
bit cover_enable |
); |
// enable or disable c_waitrequested_write cover group |
|
enable_c_waitrequested_write = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_waitrequested_write"); |
endfunction |
|
function automatic void set_enable_c_continuous_waitrequest_from_idle_to_write( // public |
bit cover_enable |
); |
// enable or disable c_continuous_waitrequest_from_idle_to_write cover group |
|
enable_c_continuous_waitrequest_from_idle_to_write = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_continuous_waitrequest_from_idle_to_write"); |
endfunction |
|
function automatic void set_enable_c_continuous_waitrequest_from_idle_to_read( // public |
bit cover_enable |
); |
// enable or disable c_continuous_waitrequest_from_idle_to_read cover group |
|
enable_c_continuous_waitrequest_from_idle_to_read = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_continuous_waitrequest_from_idle_to_read"); |
endfunction |
|
function automatic void set_enable_c_waitrequest_without_command( // public |
bit cover_enable |
); |
// enable or disable c_waitrequest_without_command cover group |
|
enable_c_waitrequest_without_command = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_waitrequest_without_command"); |
endfunction |
|
function automatic void set_enable_c_idle_before_transaction( // public |
bit cover_enable |
); |
// enable or disable c_idle_before_transaction cover group |
|
enable_c_idle_before_transaction = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_idle_before_transaction"); |
endfunction |
|
function automatic void set_enable_c_continuous_read( // public |
bit cover_enable |
); |
// enable or disable c_continuous_read cover group |
|
enable_c_continuous_read = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_continuous_read"); |
endfunction |
|
function automatic void set_enable_c_continuous_write( // public |
bit cover_enable |
); |
// enable or disable c_continuous_write cover group |
|
enable_c_continuous_write = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_continuous_write"); |
endfunction |
|
function automatic void set_enable_c_continuous_readdatavalid( // public |
bit cover_enable |
); |
// enable or disable c_continuous_readdatavalid cover group |
|
enable_c_continuous_readdatavalid = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_continuous_readdatavalid"); |
endfunction |
|
function automatic void set_enable_c_continuous_waitrequest( // public |
bit cover_enable |
); |
// enable or disable c_continuous_waitrequest cover group |
|
enable_c_continuous_waitrequest = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_continuous_waitrequest"); |
endfunction |
|
function automatic void set_enable_c_waitrequest_in_write_burst( // public |
bit cover_enable |
); |
// enable or disable c_waitrequest_in_write_burst cover group |
|
enable_c_waitrequest_in_write_burst = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_waitrequest_in_write_burst"); |
endfunction |
|
function automatic void set_enable_c_readresponse( // public |
bit cover_enable |
); |
// enable or disable c_readresponse cover group |
|
// enable_c_readresponse = cover_enable; |
// coverage_settings_check(covergroup_settings_changed_flag, "c_readresponse"); |
|
$sformat(message, "%m: This coverage is no longer supported. Please use c_read_response cover group"); |
print(VERBOSITY_WARNING, message); |
endfunction |
|
function automatic void set_enable_c_writeresponse( // public |
bit cover_enable |
); |
// enable or disable c_writeresponse cover group |
|
// enable_c_writeresponse = cover_enable; |
// coverage_settings_check(covergroup_settings_changed_flag, "c_writeresponse"); |
|
$sformat(message, "%m: This coverage is no longer supported. Please use c_write_response cover group"); |
print(VERBOSITY_WARNING, message); |
endfunction |
|
function automatic void set_enable_c_write_with_and_without_writeresponserequest( // public |
bit cover_enable |
); |
// This API is no longer supported. |
|
endfunction |
|
function automatic void set_enable_c_write_after_reset( // public |
bit cover_enable |
); |
// enable or disable c_write_after_reset cover group |
|
enable_c_write_after_reset = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_write_after_reset"); |
endfunction |
|
function automatic void set_enable_c_read_after_reset( // public |
bit cover_enable |
); |
// enable or disable c_read_after_reset cover group |
|
enable_c_read_after_reset = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_read_after_reset"); |
endfunction |
|
function automatic void coverage_settings_check( |
bit cover_flag, |
string cover_name |
); |
string message; |
if (cover_flag) begin |
$sformat(message, "%m: - Changing %s covergroup settings during run-time will not be reflected", |
cover_name); |
print(VERBOSITY_WARNING, message); |
end |
endfunction |
|
function automatic void set_enable_c_write_response( // public |
bit cover_enable |
); |
// enable or disable c_write_response cover group |
|
enable_c_write_response = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_write_response"); |
endfunction |
|
function automatic void set_enable_c_read_response( // public |
bit cover_enable |
); |
// enable or disable c_read_response cover group |
|
enable_c_read_response = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_read_response"); |
endfunction |
|
function automatic void set_enable_c_write_response_transition( // public |
bit cover_enable |
); |
// enable or disable c_write_response_transition cover group |
|
enable_c_write_response_transition = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_write_response_transition"); |
endfunction |
|
function automatic void set_enable_c_read_response_transition( // public |
bit cover_enable |
); |
// enable or disable c_read_response_transition cover group |
|
enable_c_read_response_transition = cover_enable; |
coverage_settings_check(covergroup_settings_changed_flag, "c_read_response_transition"); |
endfunction |
|
//-------------------------------------------------------------------------- |
// =head1 Assertion Checkers and Coverage Monitors |
// The assertion checkers in this module are only executable on simulators |
// supporting the SystemVerilog Assertion (SVA) language. |
// Mentor Modelsim AE and SE do not support this. |
// Simulators that are supported include: Synopsys VCS and Mentor questasim. |
// The assertion checking logic in this module must be explicitly enabled |
// so that designs using this module can still be compiled on Modelsim without |
// changes. To disable assertions define the following macro in the testbench |
// or on the command line with: +define+DISABLE_ALTERA_AVALON_SIM_SVA. |
// =cut |
//-------------------------------------------------------------------------- |
|
//counter to capture previous cycle waitrequest value |
always @(posedge clk) |
begin |
if (!reset) begin |
past_waitrequest = waitrequest; |
end |
end |
|
// Counter for general coverage counters |
always @(posedge clk) begin |
if (!USE_CLKEN || clken) begin |
if (idle_in_write_burst_start_flag) begin |
if (waitrequest) begin |
idle_in_write_burst_with_waitrequest = 1; |
end |
end |
|
// ignore the waitrequest effect while reset |
if ((read || write) && |
reset_flag[1] == 0) |
reset_flag[0] = 0; |
if (($fell(read) || $fell(write) || readdatavalid || |
$fell(begintransfer) || $fell(beginbursttransfer) || |
((read || write) && $fell(waitrequest))) && |
reset_flag[0] == 0) begin |
reset_flag[1] = 1; |
reset_flag[0] = 1; |
end |
|
// Counter for read latency and readdatavalid_id |
if (!readdatavalid) begin |
read_latency_counter = 0; |
end |
if (read && !waitrequest && !readdatavalid) begin |
if (((!$fell(waitrequest) && !waitrequested_command_while_clken) || $rose(read)) || |
read_command_while_clken || reset_flag[1] == 0) begin |
read_latency_start_flag[read_id] = 1; |
temp_read_latency_counter[read_id] = 0; |
end else begin |
if (read_id != 0) begin |
read_latency_start_flag[read_id-1] = 1; |
temp_read_latency_counter[read_id-1] = 0; |
end else begin |
read_latency_start_flag[MAX_ID] = 1; |
temp_read_latency_counter[MAX_ID] = 0; |
end |
end |
end |
if (!read && readdatavalid) begin |
read_latency_counter = |
temp_read_latency_counter[readdatavalid_id]; |
if (read_burst_counter[readdatavalid_id] == 1 || |
read_burst_counter[readdatavalid_id] == 0) begin |
temp_read_latency_counter[readdatavalid_id] = 0; |
read_latency_start_flag[readdatavalid_id] = 0; |
// increase the id, restart the id from zero to reduce memory usage |
if (readdatavalid_id < (MAX_ID)) |
readdatavalid_id++; |
else |
readdatavalid_id = 0; |
end |
end |
if (read && readdatavalid) begin |
read_latency_counter = |
temp_read_latency_counter[readdatavalid_id]; |
if (!waitrequest) begin |
if (((!$fell(waitrequest) && !waitrequested_command_while_clken) || $rose(read)) || |
read_command_while_clken || reset_flag[1] == 0) begin |
read_latency_start_flag[read_id] = 1; |
temp_read_latency_counter[read_id] = 0; |
end else begin |
if (read_id != 0) begin |
read_latency_start_flag[read_id-1] = 1; |
temp_read_latency_counter[read_id-1] = 0; |
end else begin |
read_latency_start_flag[MAX_ID] = 1; |
temp_read_latency_counter[MAX_ID] = 0; |
end |
end |
end |
if (read_burst_counter[readdatavalid_id] == 1 || |
read_burst_counter[readdatavalid_id] == 0) begin |
temp_read_latency_counter[readdatavalid_id] = 0; |
read_latency_start_flag[readdatavalid_id] = 0; |
if (readdatavalid_id < (MAX_ID)) |
readdatavalid_id++; |
else |
readdatavalid_id = 0; |
end |
end |
|
// new burst write transaction started |
if (((write && (!waitrequest || $rose(waitrequest)) && |
((!$fell(waitrequest) && !waitrequested_command_while_clken) || |
reset_flag[1] == 0)) || write_command_while_clken || ($rose(write))) && |
write_burst_counter == 0) begin |
if (burstcount > 0) |
write_burst_counter = burstcount; |
idle_write_flag = 1; |
idle_in_write_burst_start_flag = 1; |
idle_before_burst_transaction_sampled = 1; |
end |
|
if (write && (write_burst_counter == 1)) begin |
idle_in_write_burst_start_flag = 0; |
idle_in_write_burst_with_waitrequest_sampled = 1; |
end |
|
// decrease the write_burst_counter while write asserted |
if (write && !waitrequest && write_burst_counter > 0) begin |
write_burst_counter--; |
end |
|
// new read transaction asserted |
if (((read && (!waitrequest || $rose(waitrequest)) && |
((!$fell(waitrequest) && !waitrequested_command_while_clken) || |
reset_flag[1] == 0)) || read_command_while_clken || $rose(read) || |
(read_transaction_flag && waitrequest && |
read_without_waitrequest_flag && read))) begin |
read_transaction_flag = 1; |
idle_before_burst_transaction_sampled = 1; |
if (continuous_read >= 2) |
continuous_read++; |
if (continuous_read_start_flag) begin |
if (continuous_read == 0) |
continuous_read = 2; |
end |
continuous_read_start_flag = 1; |
continuous_read_sampled = 0; |
end else begin |
read_transaction_flag = 0; |
if (read) begin |
continuous_read_start_flag = 1; |
continuous_read_sampled = 0; |
end else begin |
continuous_read_start_flag = 0; |
continuous_read_sampled = 1; |
end |
end |
|
// new read transaction without previous read response(readdatavalid) returned at same cycle |
if (((read && (!waitrequest || $rose(waitrequest)) && |
((!$fell(waitrequest) && !waitrequested_command_while_clken) || |
reset_flag[1] == 0)) || read_command_while_clken || $rose(read) || |
(read_transaction_flag && waitrequest && |
read_without_waitrequest_flag && read)) && |
!readdatavalid) begin |
if (burstcount > 0) begin |
read_burst_counter[read_id] = burstcount; |
temp_read_burst_counter = burstcount; |
end |
|
if (!waitrequest) |
read_without_waitrequest_flag = 1; |
else |
read_without_waitrequest_flag = 0; |
idle_write_flag = 0; |
idle_read_flag[read_id] = 1; |
pending_read_counter++; |
if (read_id < (MAX_ID)) |
read_id++; |
else |
read_id = 0; |
end |
|
// previous read response(readdatavalid) returned while no new read transaction asserted |
if ((readdatavalid || |
(fix_latency_queued_counter != 0 && |
fix_latency_queued_counter == AV_FIX_READ_LATENCY && |
!USE_READ_DATA_VALID)) && |
(!read_transaction_flag || !read) && pending_read_counter > 0) begin |
if ((readdatavalid_id == 0) && (read_burst_counter[MAX_ID] == 0)) begin |
if (read_burst_counter[readdatavalid_id] > 0) begin |
if (read_burst_counter[readdatavalid_id] == 1) begin |
pending_read_counter--; |
end |
read_burst_counter[readdatavalid_id]--; |
end |
end else if (read_id >= ((readdatavalid_id == 0)?MAX_ID-1:readdatavalid_id-1)) begin |
for (int i=0; i<=MAX_ID; i++) begin |
if (read_burst_counter[i] > 0) begin |
if (read_burst_counter[i] == 1) begin |
pending_read_counter--; |
end |
read_burst_counter[i]--; |
i=MAX_ID+1; |
end |
end |
end else begin |
for (int i=((readdatavalid_id == 0)?MAX_ID-1:readdatavalid_id-1); i<=MAX_ID; i++) begin |
if (read_burst_counter[i] > 0) begin |
if (read_burst_counter[i] == 1) begin |
pending_read_counter--; |
end |
read_burst_counter[i]--; |
i=MAX_ID+1; |
end |
end |
end |
end |
|
// new read transaction with previous read response(readdatavalid) returned at same cycle |
if (((read && (!waitrequest || $rose(waitrequest)) && |
((!$fell(waitrequest) && !waitrequested_command_while_clken) || |
reset_flag[1] == 0)) || read_command_while_clken || $rose(read) || |
(read_transaction_flag && waitrequest && |
read_without_waitrequest_flag && read)) && |
(readdatavalid || |
(fix_latency_queued_counter != 0 && |
fix_latency_queued_counter == AV_FIX_READ_LATENCY && |
!USE_READ_DATA_VALID)) && |
pending_read_counter > 0) begin |
if ((readdatavalid_id == 0) && (read_burst_counter[MAX_ID] == 0)) begin |
if (read_burst_counter[readdatavalid_id] > 0) begin |
if (read_burst_counter[readdatavalid_id] == 1) begin |
pending_read_counter--; |
end |
read_burst_counter[readdatavalid_id]--; |
end |
end else if (read_id >= ((readdatavalid_id == 0)?MAX_ID-1:readdatavalid_id-1)) begin |
for (int i=0; i<=MAX_ID; i++) begin |
if (read_burst_counter[i] > 0) begin |
if (read_burst_counter[i] == 1) begin |
pending_read_counter--; |
end |
read_burst_counter[i]--; |
i=MAX_ID+1; |
end |
end |
end else begin |
for (int i=((readdatavalid_id == 0)?MAX_ID-1:readdatavalid_id-1); i<=MAX_ID; i++) begin |
if (read_burst_counter[i] > 0) begin |
if (read_burst_counter[i] == 1) begin |
pending_read_counter--; |
end |
read_burst_counter[i]--; |
i=MAX_ID+1; |
end |
end |
end |
if (burstcount > 0) begin |
read_burst_counter[read_id] = burstcount; |
temp_read_burst_counter = burstcount; |
end |
if (!waitrequest) |
read_without_waitrequest_flag = 1; |
else |
read_without_waitrequest_flag = 0; |
idle_write_flag = 0; |
idle_read_flag[read_id] = 1; |
pending_read_counter++; |
if (read_id < (MAX_ID)) |
read_id++; |
else |
read_id = 0; |
end |
|
// counter for read latency |
if (pending_read_counter > 0) begin |
if (!USE_READ_DATA_VALID) begin |
fix_read_latency_counter++; |
if (fix_read_latency_counter > |
AV_FIX_READ_LATENCY) |
fix_read_latency_counter = 0; |
end else begin |
for (int i=0; i<=MAX_ID; i++) begin |
if (i != read_id) begin |
if (read_latency_start_flag[i]) begin |
temp_read_latency_counter[i]++; |
end |
end |
end |
end |
end |
|
// counter for idle_in_write_burst |
if (idle_in_write_burst_flag) begin |
idle_write_flag = 0; |
idle_in_write_burst_flag = 0; |
end |
if (!write && idle_write_flag && |
write_burst_counter < burstcount && |
write_burst_counter != 0) |
idle_in_write_burst_flag = 1; |
|
// counter for idle_in_read_response |
if (idle_in_read_response == 1) |
idle_in_read_response = 0; |
if (!readdatavalid && !waitrequest && |
idle_read_flag[readdatavalid_id] && |
read_burst_counter[readdatavalid_id] <= |
temp_read_burst_counter) begin |
temp_idle_in_read_response[readdatavalid_id]++; |
idle_in_read_response = |
temp_idle_in_read_response[readdatavalid_id]; |
end |
|
// counter for waitrequested command |
if (read && waitrequest) |
temp_waitrequested_read_counter++; |
if (!read || !waitrequest) begin |
waitrequested_read_counter = |
temp_waitrequested_read_counter; |
temp_waitrequested_read_counter = 0; |
end |
if (write && waitrequest) begin |
temp_waitrequested_write_counter++; |
end |
if (!write || !waitrequest) begin |
waitrequested_write_counter = |
temp_waitrequested_write_counter; |
temp_waitrequested_write_counter = 0; |
end |
|
// fix latency counter |
if (read && !waitrequest) begin |
fix_latency_queued.push_front(0); |
end |
|
if (fix_latency_queued.size() > 0) begin |
foreach(fix_latency_queued[size]) begin |
fix_latency_queued[size]++; |
if (fix_latency_queued[size] > AV_FIX_READ_LATENCY) begin |
void'(fix_latency_queued.pop_back()); |
end |
end |
fix_latency_queued_counter <= fix_latency_queued[$]; |
end |
waitrequested_command_while_clken = 0; |
write_command_while_clken = 0; |
read_command_while_clken = 0; |
end else begin |
if (($rose(waitrequest) && read) || ($rose(read))) begin |
read_command_while_clken = 1; |
end |
if (($rose(waitrequest) && write) || $rose(write)) begin |
write_command_while_clken = 1; |
end |
|
if ($fell(waitrequest) && (read || write)) begin |
waitrequested_command_while_clken = 1; |
end |
end |
end |
|
// counter for waitrequest before command asserted |
always @(posedge clk) begin |
if (!reset) begin |
if (!USE_CLKEN || clken) begin |
if (waitrequest && !write && !read) begin |
waitrequest_before_command = 1; |
waitrequested_before_transaction = 1; |
end else begin |
if (read || write) begin |
waitrequested_before_transaction = 0; |
end |
end |
|
if (waitrequest && (read || write)) begin |
if (write_burst_counter == 0) |
burst_waitrequested_command = 1; |
end |
|
if (waitrequest_before_command) begin |
if (write && waitrequest) begin |
waitrequest_before_waitrequested_write = 1; |
end else if (read && waitrequest) begin |
waitrequest_before_waitrequested_read = 1; |
end |
|
if(!waitrequest) begin |
if (!waitrequest_before_waitrequested_write && !waitrequest_before_waitrequested_read) begin |
waitrequest_without_command = 1; |
end else begin |
waitrequest_without_command = 0; |
end |
waitrequest_before_command = 0; |
end |
end else begin |
waitrequest_before_waitrequested_write = 0; |
waitrequest_before_waitrequested_read = 0; |
end |
|
if (!waitrequest) begin |
waitrequest_before_command = 0; |
end |
|
if (!read && ! write && !waitrequest) begin |
if (write_burst_counter == 0) begin |
idle_before_burst_transaction = 1; |
idle_before_burst_transaction_sampled = 0; |
end |
end |
|
if (waitrequested_before_transaction) begin |
if (idle_before_burst_transaction) begin |
idle_before_burst_transaction_with_waitrequest = 1; |
idle_before_burst_transaction_with_waitrequest_sampled = 0; |
end |
end else begin |
if ((burst_waitrequested_command) && (idle_before_burst_transaction)) begin |
idle_before_burst_transaction_with_waitrequest = 1; |
end |
if (write_burst_counter == 0) begin |
idle_before_burst_transaction_with_waitrequest_sampled = 1; |
end else begin |
idle_before_burst_transaction_with_waitrequest_sampled = 0; |
end |
end |
end |
end |
end |
|
// Counter for continuous write, readdatavalid |
always@(posedge clk) begin |
if (!reset) begin |
if (!USE_CLKEN || clken) begin |
if ((write && (!waitrequest))) begin |
if (continuous_write >= 2) |
continuous_write++; |
if (continuous_write_start_flag) begin |
if (continuous_write == 0) |
continuous_write = 2; |
end else begin |
continuous_write_start_flag = 1; |
end |
|
continuous_write_start_flag = 1; |
continuous_write_sampled = 0; |
end else begin |
if (write) begin |
continuous_write_sampled = 0; |
end else begin |
continuous_write_sampled = 1; |
continuous_write_start_flag = 0; |
end |
end |
|
if (readdatavalid) begin |
if (continuous_readdatavalid >= 2) |
continuous_readdatavalid++; |
if(continuous_readdatavalid_start_flag == 1) begin |
if (continuous_readdatavalid == 0) |
continuous_readdatavalid = 2; |
end |
continuous_readdatavalid_sampled = 0; |
continuous_readdatavalid_start_flag = 1; |
end else begin |
continuous_readdatavalid_start_flag = 0; |
continuous_readdatavalid_sampled = 1; |
end |
|
if (waitrequest) begin |
if (continuous_waitrequest >= 1) |
continuous_waitrequest++; |
if(continuous_waitrequest_start_flag == 1) begin |
if (continuous_waitrequest == 0) begin |
continuous_waitrequest = 2; |
end |
end |
continuous_waitrequest_sampled = 0; |
continuous_waitrequest_start_flag = 1; |
end else begin |
continuous_waitrequest_start_flag = 0; |
continuous_waitrequest_sampled = 1; |
end |
end |
end |
end |
|
// Counter for generating legal byteenable |
initial begin |
legal_byteenable[(AV_NUMSYMBOLS*2)-1] = 0; |
check_byteenable = byteenable_1_bit; |
for (int i=0; i<AV_NUMSYMBOLS; i++) begin |
legal_byteenable[i] = check_byteenable; |
check_byteenable = check_byteenable << 1; |
byteenable_counter = i; |
end |
if (AV_NUMSYMBOLS > 1) begin |
check_byteenable = byteenable_2_bit; |
for (int i=0; i<AV_NUMSYMBOLS; i=i+2) begin |
byteenable_counter++; |
legal_byteenable[byteenable_counter] = check_byteenable; |
check_byteenable = check_byteenable << 2; |
end |
end |
if (AV_NUMSYMBOLS > 2) begin |
check_byteenable = byteenable_4_bit; |
for (int i=0; i<AV_NUMSYMBOLS; i=i+4) begin |
byteenable_counter++; |
legal_byteenable[byteenable_counter] = check_byteenable; |
check_byteenable = check_byteenable << 4; |
end |
end |
if (AV_NUMSYMBOLS > 4) begin |
check_byteenable = byteenable_8_bit; |
for (int i=0; i<AV_NUMSYMBOLS; i=i+8) begin |
byteenable_counter++; |
legal_byteenable[byteenable_counter] = check_byteenable; |
check_byteenable = check_byteenable << 8; |
end |
end |
if (AV_NUMSYMBOLS > 8) begin |
check_byteenable = byteenable_16_bit; |
for (int i=0; i<AV_NUMSYMBOLS; i=i+16) begin |
byteenable_counter++; |
legal_byteenable[byteenable_counter] = check_byteenable; |
check_byteenable = check_byteenable << 16; |
end |
end |
if (AV_NUMSYMBOLS > 16) begin |
check_byteenable = byteenable_32_bit; |
for (int i=0; i<AV_NUMSYMBOLS; i=i+32) begin |
byteenable_counter++; |
legal_byteenable[byteenable_counter] = check_byteenable; |
check_byteenable = check_byteenable << 32; |
end |
end |
if (AV_NUMSYMBOLS > 32) begin |
check_byteenable = byteenable_64_bit; |
for (int i=0; i<AV_NUMSYMBOLS; i=i+64) begin |
byteenable_counter++; |
legal_byteenable[byteenable_counter] = check_byteenable; |
check_byteenable = check_byteenable << 64; |
end |
end |
if (AV_NUMSYMBOLS > 64) begin |
byteenable_counter++; |
legal_byteenable[byteenable_counter] = byteenable_128_bit; |
end |
end |
|
// Counter for back to back transfers |
always @(posedge clk) begin |
if (!USE_CLKEN || clken) begin |
if ((!read && !write) || waitrequest) begin |
b2b_transfer[3] = 1; |
b2b_transfer[2] = 0; |
end else begin |
if (read && !waitrequest) begin |
if (!b2b_transfer[3] && !b2b_transfer[2]) |
b2b_transfer[1] = b2b_transfer[0]; |
if (b2b_transfer[3]) begin |
b2b_transfer[3] = 0; |
b2b_transfer[2] = 1; |
b2b_transfer[1] = 0; |
end else begin |
b2b_transfer[0] = 0; |
if (b2b_transfer[2]) |
b2b_transfer[2] = 0; |
end |
end |
if (write && !waitrequest) begin |
if (!b2b_transfer[3] && !b2b_transfer[2]) |
b2b_transfer[1] = b2b_transfer[0]; |
if (b2b_transfer[3]) begin |
b2b_transfer[3] = 0; |
b2b_transfer[2] = 1; |
b2b_transfer[1] = 1; |
end else begin |
b2b_transfer[0] = 1; |
if (b2b_transfer[2]) |
b2b_transfer[2] = 0; |
end |
end |
end |
end |
end |
|
// Counter for write response transition |
always @(posedge clk) begin |
if (!USE_CLKEN || clken) begin |
if (writeresponsevalid) begin |
write_response_transition[3:2] = write_response_transition[1:0]; |
write_response_transition[1:0] = write_response; |
end |
end |
end |
|
// Counter for read response transition |
always @(posedge clk) begin |
if (!USE_CLKEN || clken) begin |
if ((USE_READ_DATA_VALID && readdatavalid) || |
(!USE_READ_DATA_VALID && fix_latency_queued_counter == AV_FIX_READ_LATENCY && fix_latency_queued_counter != 0)) begin |
read_response_transition[3:2] = read_response_transition[1:0]; |
read_response_transition[1:0] = read_response; |
end |
end |
end |
// Counter for reset |
always @(posedge clk) begin |
if (reset) begin |
fix_latency_queued = {}; |
idle_write_flag = 0; |
idle_read_flag = 0; |
read_latency_start_flag = 0; |
read_burst_counter = 0; |
temp_read_burst_counter = 0; |
temp_idle_in_read_response = 0; |
temp_read_latency_counter = 0; |
fix_latency_queued_counter = 0; |
read_transaction_flag = 0; |
read_without_waitrequest_flag = 0; |
idle_in_write_burst_flag = 0; |
write_burst_counter = 0; |
pending_read_counter = 0; |
fix_read_latency_counter = 0; |
idle_in_read_response = 0; |
temp_waitrequested_read_counter = 0; |
waitrequested_read_counter = 0; |
temp_waitrequested_write_counter = 0; |
waitrequested_write_counter = 0; |
byteenable_counter = 0; |
read_latency_counter = 0; |
read_id = 0; |
readdatavalid_id = 0; |
b2b_transfer = 4'b1111; |
check_byteenable = 0; |
reset_flag[1] = 0; |
reset_flag[0] = 1; |
write_after_reset = 1; |
read_after_reset = 1; |
read_reset_transaction = 1; |
write_reset_transaction = 1; |
waitrequest_before_waitrequested_read = 0; |
waitrequest_before_waitrequested_write = 0; |
waitrequest_before_command = 0; |
waitrequest_without_command = 0; |
past_waitrequest = 0; |
idle_before_burst_transaction = 0; |
idle_before_burst_transaction_sampled = 0; |
continuous_read_sampled = 0; |
continuous_read_start_flag = 0; |
continuous_read = 0; |
continuous_write_sampled = 0; |
continuous_write_start_flag = 0; |
continuous_write = 0; |
continuous_readdatavalid_sampled = 0; |
continuous_readdatavalid_start_flag = 0; |
continuous_readdatavalid = 0; |
continuous_waitrequest_sampled = 0; |
continuous_waitrequest_start_flag = 0; |
continuous_waitrequest = 0; |
idle_in_write_burst_with_waitrequest = 0; |
idle_in_write_burst_with_waitrequest_sampled = 0; |
idle_in_write_burst_start_flag = 0; |
idle_before_burst_transaction_with_waitrequest = 0; |
idle_before_burst_transaction_with_waitrequest_sampled = 0; |
waitrequested_before_transaction = 0; |
burst_waitrequested_command = 0; |
write_command_while_clken = 0; |
read_command_while_clken = 0; |
waitrequested_command_while_clken = 0; |
end |
end |
|
// Flag for initial coverage settings |
initial begin |
#1 covergroup_settings_changed_flag = 1; |
end |
|
|
`ifdef DISABLE_ALTERA_AVALON_SIM_SVA |
// SVA coverage code is disabled when this macro is defined |
|
`else |
//-------------------------------------------------------------------------- |
// COVERAGE CODE BEGIN |
//-------------------------------------------------------------------------- |
|
//--------------------------------------------------------------------------- |
// =head2 Master Coverages |
// The following are the cover group code focus on Master component coverage |
//------------------------------------------------------------------------------- |
|
//------------------------------------------------------------------------------- |
// =head3 c_read_byteenable |
// This cover group covers the different byteenable during read transfers. |
// This cover group does not support byteenable value larger than |
// 1073741824. |
//------------------------------------------------------------------------------- |
|
covergroup cg_read_byteenable(logic [63:0] byteenable_max); |
cp_byteenable: coverpoint byteenable |
{ |
bins cg_read_byteenable_cp_byteenable [] = {[0:4], |
8, |
12, |
15, |
16, |
32, |
48, |
64, |
128, |
192, |
255, |
256, |
512, |
768, |
1024, |
2048, |
3072, |
3840, |
4096, |
8192, |
12288, |
16384, |
32768, |
49152, |
65280, |
65535, |
65536, |
131072, |
196608, |
262144, |
524288, |
786432, |
1048576, |
2097152, |
3145728, |
4194304, |
8388608, |
12582912, |
16711680, |
16777216, |
33554432, |
50331648, |
67108864, |
134217728, |
201326592, |
268435456, |
536870912, |
805306368, |
1073741824}; |
|
ignore_bins cg_read_byteenable_cp_byteenable_ignore = {[byteenable_max+1:$]}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_read_byteenable c_read_byteenable; |
|
initial begin |
#1 if (enable_c_read_byteenable && USE_BYTE_ENABLE && USE_READ) begin |
if (AV_NUMSYMBOLS >= 32) |
c_read_byteenable = new(1073741825); |
else |
c_read_byteenable = new((2**AV_NUMSYMBOLS)-1); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_read_byteenable && USE_BYTE_ENABLE && USE_READ) begin |
if (read && !waitrequest && clken) begin |
c_read_byteenable.sample(); |
end |
end |
end |
|
// ------------------------------------------------------------------------------- |
// =head3 c_write_byteenable |
// This cover group covers the different byteenable during write transfers. |
// This cover group does not support byteenable value larger than |
// 1073741824. |
// ------------------------------------------------------------------------------- |
|
covergroup cg_write_byteenable(logic [31:0] byteenable_max); |
cp_byteenable: coverpoint byteenable |
{ |
bins cg_write_byteenable_cp_byteenable [] = {[0:4], |
8, |
12, |
15, |
16, |
32, |
48, |
64, |
128, |
192, |
255, |
256, |
512, |
768, |
1024, |
2048, |
3072, |
3840, |
4096, |
8192, |
12288, |
16384, |
32768, |
49152, |
65280, |
65535, |
65536, |
131072, |
196608, |
262144, |
524288, |
786432, |
1048576, |
2097152, |
3145728, |
4194304, |
8388608, |
12582912, |
16711680, |
16777216, |
33554432, |
50331648, |
67108864, |
134217728, |
201326592, |
268435456, |
536870912, |
805306368, |
1073741824}; |
ignore_bins cg_write_byteenable_cp_byteenable_ignore = {[byteenable_max+1:$]}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_write_byteenable c_write_byteenable; |
|
initial begin |
#1 if (enable_c_write_byteenable && USE_BYTE_ENABLE && USE_WRITE) begin |
if (AV_NUMSYMBOLS >= 32) |
c_write_byteenable = new(1073741825); |
else |
c_write_byteenable = new((2**AV_NUMSYMBOLS)-1); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_write_byteenable && USE_BYTE_ENABLE && USE_WRITE) begin |
if (write && !waitrequest && clken) begin |
c_write_byteenable.sample(); |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_read_burstcount |
// This cover group covers the different sizes of burstcount during read |
// burst transfers |
//------------------------------------------------------------------------------- |
|
covergroup cg_read_burstcount; |
cp_burstcount: coverpoint burstcount |
{ |
bins cg_read_burstcount_cp_burstcount_low = {1}; |
bins cg_read_burstcount_cp_burstcount_mid = |
{[(AV_MAX_BURST < 3? 1:2): |
(AV_MAX_BURST < 3? 1:AV_MAX_BURST-1)]}; |
bins cg_read_burstcount_cp_burstcount_high = |
{(AV_MAX_BURST < 2? 1:AV_MAX_BURST)}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_read_burstcount c_read_burstcount; |
|
initial begin |
#1 if (enable_c_read_burstcount && USE_BURSTCOUNT && USE_READ) begin |
c_read_burstcount = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_read_burstcount && USE_BURSTCOUNT && USE_READ) begin |
if (read && !waitrequest && clken) begin |
c_read_burstcount.sample(); |
#1; |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_write_burstcount |
// This cover group covers the different sizes of burstcount during write |
// burst transfers |
//------------------------------------------------------------------------------- |
|
covergroup cg_write_burstcount; |
cp_burstcount: coverpoint burstcount |
{ |
bins cg_write_burstcount_cp_burstcount_low = {1}; |
bins cg_write_burstcount_cp_burstcount_mid = |
{[(AV_MAX_BURST < 3? 1:2): |
(AV_MAX_BURST < 3? 1:AV_MAX_BURST-1)]}; |
bins cg_write_burstcount_cp_burstcount_high = |
{(AV_MAX_BURST < 2? 1:AV_MAX_BURST)}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_write_burstcount c_write_burstcount; |
|
initial begin |
#1 if (enable_c_write_burstcount && USE_BURSTCOUNT && USE_WRITE) begin |
c_write_burstcount = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_write_burstcount && USE_BURSTCOUNT && USE_WRITE) begin |
if (write && write_burst_counter == 0 && clken) begin |
c_write_burstcount.sample(); |
#1; |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_pending_read |
// This cover group covers the different number of pending read transfers |
//------------------------------------------------------------------------------- |
|
covergroup cg_pending_read; |
cp_pending_read_count: coverpoint pending_read_counter |
{ |
bins cg_pending_read_cp_pending_read_count[] = |
{[1:(AV_MAX_PENDING_READS < 2? 1:AV_MAX_PENDING_READS)]}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_pending_read c_pending_read; |
|
initial begin |
#1 if (enable_c_pending_read && USE_READ && USE_READ_DATA_VALID && AV_MAX_PENDING_READS > 0) begin |
c_pending_read = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_pending_read && USE_READ && USE_READ_DATA_VALID && AV_MAX_PENDING_READS > 0) begin |
if (read_transaction_flag && clken) begin |
c_pending_read.sample(); |
#1; |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_read |
// This cover group covers read transfers |
//------------------------------------------------------------------------------- |
|
covergroup cg_read; |
cp_read: coverpoint read |
{ |
bins cg_read_cp_read = {1}; |
option.comment = "This cover group covers read transfers"; |
} |
option.per_instance = 1; |
option.comment = "This cover group covers how many read transfers happen"; |
endgroup |
|
cg_read c_read; |
|
initial begin |
#1 if (enable_c_read && USE_READ) begin |
c_read = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_read && USE_READ && clken) begin |
if (read && !waitrequest) begin |
c_read.sample(); |
#1; |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_write |
// This cover group covers write transfers |
//------------------------------------------------------------------------------- |
|
covergroup cg_write; |
cp_write: coverpoint write |
{ |
bins cg_write_cp_write = {1}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_write c_write; |
|
initial begin |
#1 if (enable_c_write && USE_WRITE) begin |
c_write = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_write && USE_WRITE && clken) begin |
if (write && write_burst_counter == 0) begin |
c_write.sample(); |
#1; |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_b2b_read_read |
// This cover group covers back to back read to read transfers |
//------------------------------------------------------------------------------- |
|
covergroup cg_b2b_read_read; |
cp_b2b_read_read: coverpoint b2b_transfer |
{ |
bins cp_b2b_read_read_cp_b2b_read_read = {4'b0000}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_b2b_read_read c_b2b_read_read; |
|
initial begin |
#1 if (enable_c_b2b_read_read && USE_READ) begin |
c_b2b_read_read = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_b2b_read_read && USE_READ && clken) begin |
c_b2b_read_read.sample(); |
#1; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_b2b_read_write |
// This cover group covers back to back read to write transfers |
//------------------------------------------------------------------------------- |
|
covergroup cg_b2b_read_write; |
cp_b2b_read_write: coverpoint b2b_transfer |
{ |
bins cg_b2b_read_write_cp_b2b_read_write = {4'b0001}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_b2b_read_write c_b2b_read_write; |
|
initial begin |
#1 if (enable_c_b2b_read_write && USE_READ && USE_WRITE) begin |
c_b2b_read_write = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_b2b_read_write && USE_READ && USE_WRITE && clken) begin |
c_b2b_read_write.sample(); |
#1; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_b2b_write_write |
// This cover group covers back to back write to write transfers |
//------------------------------------------------------------------------------- |
|
covergroup cg_b2b_write_write; |
cp_b2b_write_write: coverpoint b2b_transfer |
{ |
bins cg_b2b_write_write_cp_b2b_write_write = {4'b0011}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_b2b_write_write c_b2b_write_write; |
|
initial begin |
#1 if (enable_c_b2b_write_write && USE_WRITE) begin |
c_b2b_write_write = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_b2b_write_write && USE_WRITE && clken) begin |
c_b2b_write_write.sample(); |
#1; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_b2b_write_read |
// This cover group covers back to back write to read transfers |
//------------------------------------------------------------------------------- |
|
covergroup cg_b2b_write_read; |
cp_b2b_write_read: coverpoint b2b_transfer |
{ |
bins cg_b2b_write_read_cp_b2b_write_read = {4'b0010}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_b2b_write_read c_b2b_write_read; |
|
initial begin |
#1 if (enable_c_b2b_write_read && USE_READ && USE_WRITE) begin |
c_b2b_write_read = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_b2b_write_read && USE_READ && USE_WRITE && clken) begin |
c_b2b_write_read.sample(); |
#1; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_idle_in_write_burst |
// This cover group covers idle cycles during write burst transfers |
//------------------------------------------------------------------------------- |
|
covergroup cg_idle_in_write_burst; |
cp_idle_in_write_burst: coverpoint idle_in_write_burst_flag |
{ |
bins cg_idle_in_write_burst_cp_idle_in_write_burst_count = {1}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_idle_in_write_burst c_idle_in_write_burst; |
|
initial begin |
#1 if (enable_c_idle_in_write_burst && USE_BURSTCOUNT && USE_WRITE && |
AV_MAX_BURST > 1) begin |
c_idle_in_write_burst = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_idle_in_write_burst && USE_BURSTCOUNT && USE_WRITE && |
AV_MAX_BURST > 1 && clken) begin |
c_idle_in_write_burst.sample(); |
#1; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_idle_before_transaction |
// This cover group covers different cycle numbers of idle before read/write |
// transaction. |
//------------------------------------------------------------------------------- |
|
covergroup cg_idle_before_transaction; |
cp_idle_before_transaction: coverpoint idle_before_burst_transaction |
{ |
bins cg_idle_before_transaction_cp_idle_before_transaction = {1}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_idle_before_transaction c_idle_before_transaction; |
|
initial begin |
#1 if (enable_c_idle_before_transaction) begin |
c_idle_before_transaction = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (idle_before_burst_transaction_sampled == 1 && clken) begin |
if (enable_c_idle_before_transaction) begin |
c_idle_before_transaction.sample(); |
#1; |
end |
idle_before_burst_transaction = 0; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_continuous_read |
// This cover group covers the different cycle numbers of continuous read |
// asserted from 2 until AV_MAX_CONTINUOUS_READ. For the continuous read cycles |
// more than AV_MAX_CONTINUOUS_READ will go to another bin. |
//------------------------------------------------------------------------------- |
|
covergroup cg_continuous_read; |
cp_continuous_read: coverpoint continuous_read |
{ |
bins cg_continuous_read_cp_continuous_read [] = |
{[2:(AV_MAX_CONTINUOUS_READ < 2) ? 2:AV_MAX_CONTINUOUS_READ]}; |
bins cg_continuous_read_cp_continuous_read_high = |
{[AV_MAX_CONTINUOUS_READ+1:$]}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_continuous_read c_continuous_read; |
|
initial begin |
#1 if (enable_c_continuous_read && USE_READ) begin |
c_continuous_read = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_continuous_read && USE_READ && clken) begin |
if (continuous_read_sampled == 1) begin |
c_continuous_read.sample(); |
continuous_read = 0; |
#1; |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_continuous_write |
// This cover group covers the different cycle numbers of continuous write |
// asserted from 2 until AV_MAX_CONTINUOUS_WRITE. For the continuous write cycles |
// more than AV_MAX_CONTINUOUS_WRITE will go to another bin. |
//------------------------------------------------------------------------------- |
|
covergroup cg_continuous_write; |
cp_continuous_write: coverpoint continuous_write |
{ |
bins cg_continuous_write_cp_continuous_write [] = |
{[2:(AV_MAX_CONTINUOUS_WRITE) < 2 ? 2:AV_MAX_CONTINUOUS_WRITE]}; |
bins cg_continuous_write_cp_continuous_write_high = |
{[AV_MAX_CONTINUOUS_WRITE+1:$]}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_continuous_write c_continuous_write; |
|
initial begin |
#1 if (enable_c_continuous_write && USE_WRITE) begin |
c_continuous_write = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_continuous_write && USE_WRITE && clken) begin |
if (continuous_write_sampled == 1) begin |
c_continuous_write.sample(); |
continuous_write = 0; |
#1; |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_write_after_reset |
// This cover group covers write transaction right after reset |
//------------------------------------------------------------------------------- |
|
covergroup cg_write_after_reset; |
cp_write_after_reset: coverpoint write_after_reset |
{ |
bins cg_write_after_reset_cp_write_after_reset = {1}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_write_after_reset c_write_after_reset; |
|
initial begin |
#1 if (enable_c_write_after_reset && USE_WRITE) begin |
c_write_after_reset = new(); |
end |
end |
|
always @(posedge clk) begin |
if (enable_c_write_after_reset && USE_WRITE && !reset && clken) begin |
if (write) begin |
c_write_after_reset.sample(); |
#1; |
end |
if (write_reset_transaction == 0) begin |
write_after_reset = 0; |
end |
write_reset_transaction = 0; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_read_after_reset |
// This cover group covers read transaction right after reset |
// =cut |
//------------------------------------------------------------------------------- |
|
covergroup cg_read_after_reset; |
cp_read_after_reset: coverpoint read_after_reset |
{ |
bins cg_read_after_reset_cp_read_after_reset = {1}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_read_after_reset c_read_after_reset; |
|
initial begin |
#1 if (enable_c_read_after_reset && USE_READ) begin |
c_read_after_reset = new(); |
end |
end |
|
always @(posedge clk) begin |
if (enable_c_read_after_reset && USE_READ && !reset && clken) begin |
if (read) begin |
c_read_after_reset.sample(); |
#1; |
end |
if (read_reset_transaction == 0) begin |
read_after_reset = 0; |
end |
read_reset_transaction = 0; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head2 Slave Coverages |
// The following are the cover group code focus on Slave component coverage |
//------------------------------------------------------------------------------- |
|
//------------------------------------------------------------------------------- |
// =head3 c_idle_in_read_response |
// This cover group covers idle cycles during read response |
//------------------------------------------------------------------------------- |
|
covergroup cg_idle_in_read_response; |
cp_idle_in_read_response: coverpoint idle_in_read_response |
{ |
bins cg_idle_in_read_response_cp_idle_in_read_response_count = {1}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_idle_in_read_response c_idle_in_read_response; |
|
initial begin |
#1 if (enable_c_idle_in_read_response && USE_BURSTCOUNT && USE_READ && |
USE_READ_DATA_VALID) begin |
c_idle_in_read_response = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_idle_in_read_response && USE_BURSTCOUNT && USE_READ && |
USE_READ_DATA_VALID && clken) begin |
c_idle_in_read_response.sample(); |
#1; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_read_latency |
// This cover group covers different read latency cycles |
//------------------------------------------------------------------------------- |
|
covergroup cg_read_latency; |
cp_read_latency: coverpoint read_latency_counter |
{ |
bins cg_read_latency_cp_read_latency_count_low = {1}; |
bins cg_read_latency_cp_read_latency_count_high = |
{[(AV_MAX_READ_LATENCY < 2? 1:2): |
(AV_MAX_READ_LATENCY < 2? 1:AV_MAX_READ_LATENCY)]}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_read_latency c_read_latency; |
|
initial begin |
#1 if (enable_c_read_latency && USE_READ && USE_READ_DATA_VALID && |
AV_MAX_READ_LATENCY > 0) begin |
c_read_latency = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_read_latency && USE_READ && USE_READ_DATA_VALID && |
AV_MAX_READ_LATENCY > 0 && clken) begin |
c_read_latency.sample(); |
#1; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_waitrequested_read |
// This cover group covers different waitrequested read cycles |
//------------------------------------------------------------------------------- |
|
covergroup cg_waitrequested_read; |
cp_waitrequested_read_cycle: coverpoint waitrequested_read_counter |
{ |
bins cg_waitrequested_read_cp_waitrequested_read_cycle_low = {1}; |
bins cg_waitrequested_read_cp_waitrequested_read_cycle_high = |
{[(AV_MAX_WAITREQUESTED_READ < 2? 1:2): |
(AV_MAX_WAITREQUESTED_READ < 2? 1:AV_MAX_WAITREQUESTED_READ)]}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_waitrequested_read c_waitrequested_read; |
|
initial begin |
#1 if (enable_c_waitrequested_read && USE_WAIT_REQUEST && USE_READ && |
AV_MAX_WAITREQUESTED_READ > 0) begin |
c_waitrequested_read = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_waitrequested_read && USE_WAIT_REQUEST && USE_READ && |
AV_MAX_WAITREQUESTED_READ > 0 && clken) begin |
if (temp_waitrequested_read_counter == 0) begin |
c_waitrequested_read.sample(); |
#1; |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_waitrequested_write |
// This cover group covers different waitrequested write cycles |
//------------------------------------------------------------------------------- |
|
covergroup cg_waitrequested_write; |
cp_waitrequested_write_cycle: coverpoint waitrequested_write_counter |
{ |
bins cg_waitrequested_write_cp_waitrequested_write_cycle_low = {1}; |
bins cg_waitrequested_write_cp_waitrequested_write_cycle_high = |
{[(AV_MAX_WAITREQUESTED_WRITE < 2? 1:2): |
(AV_MAX_WAITREQUESTED_WRITE < 2? 1:AV_MAX_WAITREQUESTED_WRITE)]}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_waitrequested_write c_waitrequested_write; |
|
initial begin |
#1 if (enable_c_waitrequested_write && USE_WAIT_REQUEST && USE_WRITE && |
AV_MAX_WAITREQUESTED_WRITE > 0) begin |
c_waitrequested_write = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_waitrequested_write && USE_WAIT_REQUEST && USE_WRITE && |
AV_MAX_WAITREQUESTED_WRITE > 0 && clken) begin |
if (temp_waitrequested_write_counter == 0) begin |
c_waitrequested_write.sample(); |
#1; |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_continuous_waitrequest_from_idle_to_write |
// This cover group covers waitrequest is asserted before waitrequested write. |
//------------------------------------------------------------------------------- |
|
covergroup cg_continuous_waitrequest_from_idle_to_write; |
cp_continuous_waitrequest_from_idle_to_write: coverpoint waitrequest_before_waitrequested_write |
{ |
bins cg_continuous_waitrequest_from_idle_to_write_cp_continuous_waitrequest_from_idle_to_write = {1}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_continuous_waitrequest_from_idle_to_write c_continuous_waitrequest_from_idle_to_write; |
|
initial begin |
#1 if (enable_c_continuous_waitrequest_from_idle_to_write && USE_WAIT_REQUEST && USE_WRITE && |
AV_MAX_WAITREQUESTED_WRITE > 0) begin |
c_continuous_waitrequest_from_idle_to_write = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (!waitrequest && clken) begin |
if (enable_c_continuous_waitrequest_from_idle_to_write && USE_WAIT_REQUEST && USE_WRITE && |
AV_MAX_WAITREQUESTED_WRITE > 0) begin |
c_continuous_waitrequest_from_idle_to_write.sample(); |
#1; |
end |
waitrequest_before_waitrequested_write = 0; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_continuous_waitrequest_from_idle_to_read |
// This cover group covers waitrequest is asserted before waitrequested read. |
//------------------------------------------------------------------------------- |
|
covergroup cg_continuous_waitrequest_from_idle_to_read; |
cp_continuous_waitrequest_from_idle_to_read: coverpoint waitrequest_before_waitrequested_read |
{ |
bins cg_continuous_waitrequest_from_idle_to_read_cp_continuous_waitrequest_from_idle_to_read = {1}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_continuous_waitrequest_from_idle_to_read c_continuous_waitrequest_from_idle_to_read; |
|
initial begin |
#1 if (enable_c_continuous_waitrequest_from_idle_to_read && USE_WAIT_REQUEST && USE_READ && |
AV_MAX_WAITREQUESTED_READ > 0) begin |
c_continuous_waitrequest_from_idle_to_read = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (!waitrequest && clken) begin |
if (enable_c_continuous_waitrequest_from_idle_to_read && USE_WAIT_REQUEST && USE_READ && |
AV_MAX_WAITREQUESTED_READ > 0) begin |
c_continuous_waitrequest_from_idle_to_read.sample(); |
#1; |
end |
waitrequest_before_waitrequested_read = 0; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_waitrequest_without_command |
// This cover group covers no command has been asserted for the period |
// waitrequest is asserted and then deasserted. |
//------------------------------------------------------------------------------- |
|
covergroup cg_waitrequest_without_command; |
cp_waitrequest_without_command: coverpoint waitrequest_without_command |
{ |
bins cg_waitrequest_without_command_cp_waitrequest_without_command = {1}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_waitrequest_without_command c_waitrequest_without_command; |
|
initial begin |
#1 if (enable_c_waitrequest_without_command && USE_WAIT_REQUEST) begin |
c_waitrequest_without_command = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_waitrequest_without_command && USE_WAIT_REQUEST && clken) begin |
c_waitrequest_without_command.sample(); |
waitrequest_without_command = 0; |
#1; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_continuous_readdatavalid |
// This cover group covers the different cycle numbers of continuous |
// readdatavalid asserted from 2 until AV_MAX_CONTINUOUS_READDATAVALID. For the |
// continuous readdatavalid cycles more than AV_MAX_CONTINUOUS_READDATAVALID will |
// go to another bin. |
//------------------------------------------------------------------------------- |
|
covergroup cg_continuous_readdatavalid; |
cp_continuous_readdatavalid: coverpoint continuous_readdatavalid |
{ |
bins cg_continuous_readdatavalid_cp_continuous_readdatavalid [] = |
{[2:(AV_MAX_CONTINUOUS_READDATAVALID < 2) ? 2:AV_MAX_CONTINUOUS_READDATAVALID]}; |
bins cg_continuous_readdatavalid_cp_continuous_readdatavalid_high = |
{[AV_MAX_CONTINUOUS_READDATAVALID+1:$]}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_continuous_readdatavalid c_continuous_readdatavalid; |
|
initial begin |
#1 if (enable_c_continuous_readdatavalid && USE_READ_DATA_VALID) begin |
c_continuous_readdatavalid = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_continuous_readdatavalid && USE_READ_DATA_VALID && clken) begin |
if (continuous_readdatavalid_sampled == 1) begin |
c_continuous_readdatavalid.sample(); |
continuous_readdatavalid = 0; |
#1; |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_continuous_waitrequest |
// This cover group covers the different cycle numbers of continuous waitrequest |
// asserted from 2 until AV_MAX_CONTINUOUS_WAITREQUEST. For the continuous |
// waitrequest cycles more than AV_MAX_CONTINUOUS_WAITREQUEST will go to another |
// bin. |
//------------------------------------------------------------------------------- |
|
covergroup cg_continuous_waitrequest; |
cp_continuous_waitrequest: coverpoint continuous_waitrequest |
{ |
bins cg_continuous_waitrequest_cp_continuous_waitrequest [] = |
{[2:(AV_MAX_CONTINUOUS_WAITREQUEST < 2) ? 2:AV_MAX_CONTINUOUS_WAITREQUEST]}; |
bins cg_continuous_waitrequest_cp_continuous_waitrequest_high = |
{[AV_MAX_CONTINUOUS_WAITREQUEST+1:$]}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_continuous_waitrequest c_continuous_waitrequest; |
|
initial begin |
#1 if (enable_c_continuous_waitrequest && USE_WAIT_REQUEST) begin |
c_continuous_waitrequest = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_continuous_waitrequest && USE_WAIT_REQUEST && clken) begin |
if (continuous_waitrequest_sampled == 1) begin |
c_continuous_waitrequest.sample(); |
continuous_waitrequest = 0; |
#1; |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_waitrequest_in_write_burst |
// This cover group covers the different number of cycles for idle cycle during |
// write burst transaction with different number of cycles for waitrequest. |
//------------------------------------------------------------------------------- |
|
covergroup cg_waitrequest_in_write_burst; |
cp_waitrequest_in_write_burst: coverpoint idle_in_write_burst_with_waitrequest |
{ |
bins cg_waitrequest_in_write_burst_cp_waitrequest_in_write_burst = {1}; |
} |
option.per_instance = 1; |
endgroup |
|
cg_waitrequest_in_write_burst c_waitrequest_in_write_burst; |
|
initial begin |
#1 if (enable_c_waitrequest_in_write_burst && USE_WAIT_REQUEST && USE_WRITE && USE_BURSTCOUNT && (AV_BURSTCOUNT_W > 1)) begin |
c_waitrequest_in_write_burst = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_waitrequest_in_write_burst && USE_WAIT_REQUEST && USE_BURSTCOUNT && USE_WRITE && (AV_BURSTCOUNT_W > 1)) begin |
if (idle_in_write_burst_with_waitrequest_sampled == 1 && clken) begin |
c_waitrequest_in_write_burst.sample(); |
idle_in_write_burst_with_waitrequest = 0; |
idle_in_write_burst_with_waitrequest_sampled = 0; |
#1; |
end |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_readresponse |
// This cover group covers each bits of the valid readresponse which represent |
// different status. |
//------------------------------------------------------------------------------- |
|
// covergroup cg_readresponse; |
// cp_readresponse: coverpoint readresponse_bit_num |
// { |
// bins cg_readresponse_cp_readresponse [] = {[0:(AV_READRESPONSE_W-1)]}; |
// } |
// option.per_instance = 1; |
// endgroup |
|
// cg_readresponse c_readresponse; |
|
// initial begin |
// #1 if (enable_c_readresponse && USE_READRESPONSE && USE_READ) begin |
// c_readresponse = new(); |
// end |
// end |
|
// always @(posedge clk && !reset) begin |
// if (enable_c_readresponse && USE_READRESPONSE && USE_READ && clken) begin |
// if ((USE_READ_DATA_VALID && readdatavalid) || (!USE_READ_DATA_VALID)) begin |
// for (int i=0; i<AV_READRESPONSE_W; i++) begin |
// if (readresponse[i] == 1) |
// readresponse_bit_num = i; |
// else |
// readresponse_bit_num = AV_READRESPONSE_W; |
// c_readresponse.sample(); |
// end |
// end |
// #1; |
// end |
// end |
|
//------------------------------------------------------------------------------- |
// =head3 c_writeresponse |
// This cover group covers each bits of the valid writeresponse which represent |
// different status. |
//------------------------------------------------------------------------------- |
|
// covergroup cg_writeresponse; |
// cp_writeresponse : coverpoint writeresponse_bit_num |
// { |
// bins cg_writeresponse_cp_writeresponse [] = {[0:(AV_WRITERESPONSE_W-1)]}; |
// } |
// option.per_instance = 1; |
// endgroup |
|
// cg_writeresponse c_writeresponse; |
|
// initial begin |
// #1 if (enable_c_writeresponse && USE_WRITERESPONSE && USE_WRITE) begin |
// c_writeresponse = new(); |
// end |
// end |
|
// always @(posedge clk && !reset) begin |
// if (enable_c_writeresponse && USE_WRITERESPONSE && USE_WRITE && clken) begin |
// if (writeresponsevalid) begin |
// for (int i=0; i<AV_WRITERESPONSE_W; i++) begin |
// if (writeresponse[i] == 1) |
// writeresponse_bit_num = i; |
// else |
// writeresponse_bit_num = AV_WRITERESPONSE_W; |
// c_writeresponse.sample(); |
// end |
// end |
// #1; |
// end |
// end |
|
//------------------------------------------------------------------------------- |
// =head3 c_write_response |
// This cover group covers the value of write response |
//------------------------------------------------------------------------------- |
|
covergroup cg_write_response; |
cp_write_response : coverpoint write_response |
{ |
bins cg_write_response_cp_write_response [] = {AV_OKAY, AV_DECODE_ERROR, AV_SLAVE_ERROR}; |
} |
endgroup |
|
cg_write_response c_write_response; |
|
initial begin |
#1 if (enable_c_write_response && USE_WRITERESPONSE && USE_WRITE) begin |
c_write_response = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_write_response && USE_WRITERESPONSE && USE_WRITE && clken) begin |
if (writeresponsevalid) begin |
if (!$cast(write_response, response)) |
begin |
$sformat(message, "%m: Response value is not valid when write response is valid"); |
print(VERBOSITY_FAILURE, message); |
end |
c_write_response.sample(); |
end |
#1; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_read_response |
// This cover group covers the value of read response |
//------------------------------------------------------------------------------- |
|
covergroup cg_read_response; |
cp_read_response : coverpoint read_response |
{ |
bins cg_read_response_cp_read_response [] = {AV_OKAY, AV_DECODE_ERROR, AV_SLAVE_ERROR}; |
} |
endgroup |
|
cg_read_response c_read_response; |
|
initial begin |
#1 if (enable_c_read_response && USE_READRESPONSE && USE_READ) begin |
c_read_response = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_read_response && USE_READRESPONSE && USE_READ && clken) begin |
if ((USE_READ_DATA_VALID && readdatavalid) || |
(!USE_READ_DATA_VALID && fix_latency_queued_counter == AV_FIX_READ_LATENCY && fix_latency_queued_counter != 0)) begin |
|
if (!$cast(read_response, response)) |
begin |
$sformat(message, "%m: Response value is not valid when read response is valid"); |
print(VERBOSITY_FAILURE, message); |
end |
c_read_response.sample(); |
end |
#1; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_write_response_transition |
// This cover group covers the value of write response |
//------------------------------------------------------------------------------- |
|
covergroup cg_write_response_transition; |
cp_write_response_transition : coverpoint write_response_transition |
{ |
bins cg_write_response_transition_cp_write_response_transition_OKAY_TO_OKAY = {4'b0000}; |
bins cg_write_response_transition_cp_write_response_transition_OKAY_TO_SLAVE_ERROR = {4'b0010}; |
bins cg_write_response_transition_cp_write_response_transition_OKAY_TO_DECODE_ERROR = {4'b0011}; |
bins cg_write_response_transition_cp_write_response_transition_SLAVE_ERROR_TO_OKAY = {4'b1000}; |
bins cg_write_response_transition_cp_write_response_transition_SLAVE_ERROR_TO_SLAVE_ERROR = {4'b1010}; |
bins cg_write_response_transition_cp_write_response_transition_SLAVE_ERROR_TO_DECODE_ERROR = {4'b1011}; |
bins cg_write_response_transition_cp_write_response_transition_DECODE_ERROR_TO_OKAY = {4'b1100}; |
bins cg_write_response_transition_cp_write_response_transition_DECODE_ERROR_TO_SLAVE_ERROR = {4'b1110}; |
bins cg_write_response_transition_cp_write_response_transition_DECODE_ERROR_TO_DECODE_ERROR = {4'b1111}; |
} |
endgroup |
|
cg_write_response_transition c_write_response_transition; |
|
initial begin |
#1 if (enable_c_write_response_transition && USE_WRITERESPONSE && USE_WRITE) begin |
c_write_response_transition = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_write_response_transition && USE_WRITERESPONSE && USE_WRITE && clken) begin |
if (writeresponsevalid) begin |
c_write_response_transition.sample(); |
end |
#1; |
end |
end |
|
//------------------------------------------------------------------------------- |
// =head3 c_read_response_transition |
// This cover group covers the value of read response |
//------------------------------------------------------------------------------- |
|
covergroup cg_read_response_transition; |
cp_read_response_transition : coverpoint read_response_transition |
{ |
bins cg_read_response_transition_cp_read_response_transition_OKAY_TO_OKAY = {4'b0000}; |
bins cg_read_response_transition_cp_read_response_transition_OKAY_TO_SLAVE_ERROR = {4'b0010}; |
bins cg_read_response_transition_cp_read_response_transition_OKAY_TO_DECODE_ERROR = {4'b0011}; |
bins cg_read_response_transition_cp_read_response_transition_SLAVE_ERROR_TO_OKAY = {4'b1000}; |
bins cg_read_response_transition_cp_read_response_transition_SLAVE_ERROR_TO_SLAVE_ERROR = {4'b1010}; |
bins cg_read_response_transition_cp_read_response_transition_SLAVE_ERROR_TO_DECODE_ERROR = {4'b1011}; |
bins cg_read_response_transition_cp_read_response_transition_DECODE_ERROR_TO_OKAY = {4'b1100}; |
bins cg_read_response_transition_cp_read_response_transition_DECODE_ERROR_TO_SLAVE_ERROR = {4'b1110}; |
bins cg_read_response_transition_cp_read_response_transition_DECODE_ERROR_TO_DECODE_ERROR = {4'b1111}; |
} |
endgroup |
|
cg_read_response_transition c_read_response_transition; |
|
initial begin |
#1 if (enable_c_read_response_transition && USE_READRESPONSE && USE_READ) begin |
c_read_response_transition = new(); |
end |
end |
|
always @(posedge clk && !reset) begin |
if (enable_c_read_response_transition && USE_READRESPONSE && USE_READ && clken) begin |
if ((USE_READ_DATA_VALID && readdatavalid) || |
(!USE_READ_DATA_VALID && fix_latency_queued_counter == AV_FIX_READ_LATENCY && fix_latency_queued_counter != 0)) begin |
c_read_response_transition.sample(); |
end |
#1; |
end |
end |
|
//-------------------------------------------------------------------------- |
// COVERAGE CODE END |
//-------------------------------------------------------------------------- |
`endif |
|
// synthesis translate_on |
|
endmodule |
/sim/src/amm_monitor/altera_avalon_mm_monitor_transactions.sv
0,0 → 1,1323
// (C) 2001-2016 Intel Corporation. All rights reserved. |
// Your use of Intel Corporation's design tools, logic functions and other |
// software and tools, and its AMPP partner logic functions, and any output |
// files any of the foregoing (including device programming or simulation |
// files), and any associated documentation or information are expressly subject |
// to the terms and conditions of the Intel Program License Subscription |
// Agreement, Intel MegaCore Function License Agreement, or other applicable |
// license agreement, including, without limitation, that your use is for the |
// sole purpose of programming logic devices manufactured by Intel and sold by |
// Intel or its authorized distributors. Please refer to the applicable |
// agreement for further details. |
|
|
// $File: //acds/rel/16.1/ip/sopc/components/verification/altera_avalon_mm_monitor_bfm/altera_avalon_mm_monitor_transactions.sv $ |
// $Revision: #1 $ |
// $Date: 2016/08/07 $ |
// $Author: swbranch $ |
//----------------------------------------------------------------------------- |
// =head1 NAME |
// altera_avalon_mm_monitor_transactions |
// =head1 SYNOPSIS |
// Memory Mapped Avalon Bus Protocol Checker |
//----------------------------------------------------------------------------- |
// =head1 DESCRIPTION |
// This module implements Avalon MM protocol transaction recording. |
//----------------------------------------------------------------------------- |
|
`timescale 1ps / 1ps |
|
module altera_avalon_mm_monitor_transactions( |
clk, |
reset, |
tap |
); |
|
// =head1 PARAMETERS |
parameter AV_ADDRESS_W = 32; // address width |
parameter AV_SYMBOL_W = 8; // default symbol is byte |
parameter AV_NUMSYMBOLS = 4; // number of symbols per word |
parameter AV_BURSTCOUNT_W = 3; // burst port width |
|
// deprecated parameter |
parameter AV_WRITERESPONSE_W = 8; |
parameter AV_READRESPONSE_W = 8; |
|
parameter AV_CONSTANT_BURST_BEHAVIOR = 1; // Address, burstcount, transactionid and |
// avm_writeresponserequest need to be held constant |
// in burst transaction |
parameter AV_BURST_LINEWRAP = 0; // line wrapping addr is set to 1 |
parameter AV_BURST_BNDR_ONLY = 0; // addr is multiple of burst size |
parameter REGISTER_WAITREQUEST = 0; // Waitrequest is registered at the slave |
parameter AV_MAX_PENDING_READS = 1; // maximum pending read transfer count |
parameter AV_MAX_PENDING_WRITES = 0; // maximum pending write transfer count |
parameter AV_FIX_READ_LATENCY = 0; // fixed read latency in cycles |
|
parameter USE_READ = 1; // use read port |
parameter USE_WRITE = 1; // use write port |
parameter USE_ADDRESS = 1; // use address port |
parameter USE_BYTE_ENABLE = 1; // use byteenable port |
parameter USE_BURSTCOUNT = 0; // use burstcount port |
parameter USE_READ_DATA = 1; // use readdata port |
parameter USE_READ_DATA_VALID = 1; // use readdatavalid port |
parameter USE_WRITE_DATA = 1; // use writedata port |
parameter USE_BEGIN_TRANSFER = 0; // use begintransfer port |
parameter USE_BEGIN_BURST_TRANSFER = 0; // use begintbursttransfer port |
parameter USE_WAIT_REQUEST = 1; // use waitrequest port |
parameter USE_ARBITERLOCK = 0; // Use arbiterlock pin on interface |
parameter USE_LOCK = 0; // Use lock pin on interface |
parameter USE_DEBUGACCESS = 0; // Use debugaccess pin on interface |
parameter USE_TRANSACTIONID = 0; // Use transactionid interface pin |
parameter USE_WRITERESPONSE = 0; // Use write response interface pins |
parameter USE_READRESPONSE = 0; // Use read response interface pins |
parameter USE_CLKEN = 0; // Use clken interface pins |
|
parameter AV_READ_WAIT_TIME = 0; // Fixed wait time cycles when |
parameter AV_WRITE_WAIT_TIME = 0; // USE_WAIT_REQUEST is 0 |
|
localparam AV_DATA_W = AV_SYMBOL_W * AV_NUMSYMBOLS; |
localparam MAX_BURST_SIZE = USE_BURSTCOUNT ? 2**(lindex(AV_BURSTCOUNT_W)) : 1; |
localparam AV_TRANSACTIONID_W = 8; |
localparam INT_W = 32; |
localparam FIFO_MAX_LEVEL = 100; |
localparam FIFO_THRESHOLD = 50; |
parameter STORE_COMMAND = 1; // Store commands inside command queue |
parameter STORE_RESPONSE = 1; // Store responses inside response queue |
|
localparam TAP_W = 1 + // clken |
1 + // arbiterlock |
1 + // lock |
1 + // debugaccess |
((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) + // transactionid |
((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) + // readid |
((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) + // writeid |
2 + // response |
1 + // writeresponserequest |
1 + // writeresponsevalid |
1 + // waitrequest |
1 + // readdatavalid |
((AV_DATA_W == 0)? 1:AV_DATA_W) + // readdata |
1 + // write |
1 + // read |
((AV_ADDRESS_W == 0)? 1:AV_ADDRESS_W) + // address |
((AV_NUMSYMBOLS == 0)? 1:AV_NUMSYMBOLS) + // byteenable |
((AV_BURSTCOUNT_W == 0)? 1:AV_BURSTCOUNT_W) + // burstcount |
1 + // beginbursttransfer |
1 + // begintransfer |
((AV_DATA_W == 0)? 1:AV_DATA_W); // writedata |
|
// =head1 PINS |
// =head2 Clock Interface |
input clk; |
input reset; |
|
// =head2 Avalon Monitor Interface |
// Interface consists of Avalon Memory-Mapped Interface. |
// =cut |
|
// =pod |
input [TAP_W-1:0] tap; |
// =cut |
|
function int lindex; |
// returns the left index for a vector having a declared width |
// when width is 0, then the left index is set to 0 rather than -1 |
input [31:0] width; |
lindex = (width > 0) ? (width-1) : 0; |
endfunction |
|
//-------------------------------------------------------------------------- |
// synthesis translate_off |
|
import verbosity_pkg::*; |
import avalon_mm_pkg::*; |
|
localparam VERSION = "16.1"; |
|
typedef logic [lindex(AV_ADDRESS_W):0 ] AvalonAddress_t; |
typedef logic [lindex(AV_BURSTCOUNT_W):0 ] AvalonBurstCount_t; |
typedef logic [lindex(AV_TRANSACTIONID_W):0 ] AvalonTransactionId_t; |
typedef logic [lindex(MAX_BURST_SIZE):0][lindex(AV_NUMSYMBOLS):0 ] AvalonByteEnable_t; |
typedef logic [lindex(MAX_BURST_SIZE):0][lindex(AV_DATA_W):0 ] AvalonData_t; |
typedef logic [lindex(MAX_BURST_SIZE):0][lindex(INT_W):0 ] AvalonIdle_t; |
typedef logic [lindex(MAX_BURST_SIZE):0][lindex(INT_W):0 ] AvalonLatency_t; |
typedef logic [lindex(MAX_BURST_SIZE):0][lindex(AV_READRESPONSE_W):0 ] AvalonReadResponse_t; |
typedef logic [lindex(MAX_BURST_SIZE):0][lindex(AV_WRITERESPONSE_W):0] AvalonWriteResponse_t; |
typedef logic [lindex(MAX_BURST_SIZE):0][1:0] AvalonReadResponseStatus_t; |
|
typedef struct packed { |
Request_t request; |
AvalonAddress_t address; |
AvalonBurstCount_t burst_count; |
AvalonData_t data; |
AvalonByteEnable_t byte_enable; |
AvalonIdle_t idle; |
int burst_cycle; |
logic arbiterlock; |
logic lock; |
logic debugaccess; |
AvalonTransactionId_t transaction_id; |
time begin_time; |
} Command_t; |
|
typedef struct packed { |
Request_t request; |
AvalonAddress_t address; |
AvalonBurstCount_t burst_count; |
AvalonData_t data; |
AvalonByteEnable_t byte_enable; |
AvalonLatency_t wait_latency; |
AvalonLatency_t read_latency; |
int write_latency; |
int seq_count; |
int burst_size; |
AvalonTransactionId_t read_id; |
AvalonTransactionId_t write_id; |
AvalonReadResponseStatus_t read_response; |
AvalonResponseStatus_t write_response; |
time begin_time; |
time end_time; |
} Response_t; |
|
// unpack Avalon bus interface tap into individual port signals |
logic avs_waitrequest; |
logic avs_readdatavalid; |
logic [lindex(AV_DATA_W):0] avs_readdata; |
logic avs_write; |
logic avs_read; |
logic [lindex(AV_ADDRESS_W):0] avs_address; |
logic [lindex(AV_NUMSYMBOLS):0] avs_byteenable; |
logic [lindex(AV_BURSTCOUNT_W):0] avs_burstcount; |
logic avs_beginbursttransfer; |
logic avs_begintransfer; |
logic [lindex(AV_DATA_W):0] avs_writedata; |
|
logic avs_arbiterlock; |
logic avs_lock; |
logic avs_debugaccess; |
|
logic [lindex(AV_TRANSACTIONID_W):0] avs_transactionid; |
logic [lindex(AV_TRANSACTIONID_W):0] avs_readid; |
logic [lindex(AV_TRANSACTIONID_W):0] avs_writeid; |
logic [1:0] avs_response; |
logic avs_writeresponserequest; |
logic avs_writeresponsevalid; |
logic avs_clken; |
logic clken_register = 1'b1; |
|
string message = "*uninitialized*"; |
int transaction_fifo_max = FIFO_MAX_LEVEL; |
int transaction_fifo_threshold = FIFO_THRESHOLD; |
|
int response_addr_offset = 0; |
int command_addr_offset = 0; |
int command_sequence_counter = 1; |
|
Command_t command_queue[$]; |
Command_t current_command = '0; |
Command_t client_command = '0; |
|
Response_t write_response_queue[$]; |
Response_t read_response_queue[$]; |
Response_t new_response = '0; |
|
Response_t return_response = 'x; |
Response_t completed_command = 'x; |
Response_t completed_read_command = 'x; |
Response_t completed_write_command = 'x; |
Response_t issued_read_command_queue[$]; |
Response_t issued_write_command_queue[$]; |
|
AvalonResponseStatus_t null_response_status; |
|
int consolidate_write_burst_transactions = 1; |
int wait_time = 0; |
int write_burst_response_counter = 0; |
int write_latency = 0; |
int write_burst_command_counter = 0; |
int read_latency = 0; |
int command_waitrequested_start = 0; |
int read_response_burst_counter = 0; |
bit start_construct_complete_read_response = 0; |
bit start_construct_complete_write_response = 0; |
int clock_counter = 0; |
int current_time = 0; |
int clock_snapshot[$]; |
AvalonBurstCount_t avs_burstcount_int; |
|
//-------------------------------------------------------------------------- |
// =head1 Public Methods API |
// This section describes the public methods in the application programming |
// interface (API). In this case the application program is the test bench |
// which instantiates and controls and queries state of this component. |
// Test programs must only use these public access methods and events to |
// communicate with this BFM component. The API and the module pins |
// are the only interfaces in this component that are guaranteed to be |
// stable. The API will be maintained for the life of the product. |
// While we cannot prevent a test program from directly accessing internal |
// tasks, functions, or data private to the BFM, there is no guarantee that |
// these will be present in the future. In fact, it is best for the user |
// to assume that the underlying implementation of this component can |
// and will change. |
//-------------------------------------------------------------------------- |
event signal_fatal_error; // public |
// Signal that a fatal error has occurred. Terminates simulation. |
|
event signal_transaction_fifo_threshold; // public |
// Signal that the transaction FIFO threshold level has been exceeded |
|
event signal_transaction_fifo_overflow; // public |
// Signal that the FIFO is full and further transactions are being dropped |
|
function automatic string get_version(); // public |
// Return component version as a string of three integers separated by |
// periods. For example, version 9.1 sp1 is encoded as "9.1.1". |
string ret_version = "10.1"; |
return ret_version; |
endfunction |
|
function automatic void set_transaction_fifo_max( // public |
int level |
); |
// Set the maximum fullness level of the FIFO. The event |
// signal_transaction_fifo_max is triggered when this |
// level is exceeded. |
transaction_fifo_max = level; |
endfunction |
|
function automatic int get_transaction_fifo_max(); |
// Get the maximum transaction FIFO depth. |
return transaction_fifo_max; |
endfunction |
|
function automatic void set_transaction_fifo_threshold( // public |
int level |
); |
// Set the threshold alert level of the FIFO. The event |
// signal_transaction_fifo_threshold is triggered when this |
// level is exceeded. |
transaction_fifo_threshold = level; |
endfunction |
|
function automatic int get_transaction_fifo_threshold(); |
// Get the transaction FIFO threshold level. |
return transaction_fifo_threshold; |
endfunction |
|
//-------------------------------------------------------------------------- |
// Command Transaction API |
//-------------------------------------------------------------------------- |
event signal_command_received; // public |
// This event notifies the test bench that a command has been detected |
// on the Avalon port. |
// The testbench can respond with a set_interface_wait_time |
// call on receiving this event to dynamically back pressure the driving |
// Avalon master. Alternatively, wait_time which was previously set may |
// be used continuously for a set of transactions. |
|
function automatic void set_command_transaction_mode( // public |
int mode |
); |
// By default, write burst commands are consolidated into a single |
// command transaction containing the write data for all burst cycles |
// in that command. This mode is set when the mode argument equals 0. |
// When the mode argument is set to 1, the default is overridden and |
// write burst commands yield one command transaction per burst cycle. |
|
$sformat(message, "%m: method called arg0 %0d ", mode); |
print(VERBOSITY_DEBUG, message); |
consolidate_write_burst_transactions = (mode == 0) ? 1:0; |
endfunction |
|
function automatic void pop_command(); // public |
// Pop the command descriptor from the queue so that it can be |
// queried with the get_command methods by the test bench. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
client_command = command_queue.pop_back(); |
|
case(client_command.request) |
REQ_READ: $sformat(message, "%m: read addr %0x", |
client_command.address); |
REQ_WRITE: $sformat(message,"%m: write addr %0x", |
client_command.address); |
REQ_IDLE: $sformat(message, "%m: idle transaction"); |
default: $sformat(message, "%m: illegal transaction"); |
endcase |
print(VERBOSITY_DEBUG, message); |
endfunction |
|
function automatic int get_command_queue_size(); // public |
// Query the command queue to determine number of pending commands |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return command_queue.size(); |
endfunction |
|
function automatic Request_t get_command_request(); // public |
// Get the received command descriptor to determine command request type. |
// A command type may be REQ_READ or REQ_WRITE. These type values |
// are defined in the enumerated type called Request_t which is |
// imported with the package named avalon_mm_pkg. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return client_command.request; |
endfunction |
|
function automatic logic [lindex(AV_ADDRESS_W):0] get_command_address(); // public |
// Query the received command descriptor for the transaction address. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return client_command.address; |
endfunction |
|
function automatic [lindex(AV_BURSTCOUNT_W):0] get_command_burst_count();// public |
// Query the received command descriptor for the transaction burst count. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return client_command.burst_count; |
endfunction |
|
function automatic logic [AV_DATA_W-1:0] get_command_data( // public |
int index |
); |
// Query the received command descriptor for the transaction write data. |
// The burst commands with burst count greater than 1, the index |
// selects the write data cycle. |
$sformat(message, "%m: method called arg0 %0d", index); |
print(VERBOSITY_DEBUG, message); |
|
if (__check_transaction_index(index)) |
return client_command.data[index]; |
else |
return('x); |
endfunction |
|
function automatic logic [AV_NUMSYMBOLS-1:0] get_command_byte_enable(// public |
int index |
); |
// Query the received command descriptor for the transaction byte enable. |
// The burst commands with burst count greater than 1, the index |
// selects the data cycle. |
$sformat(message, "%m: method called arg0 %0d", index); |
print(VERBOSITY_DEBUG, message); |
|
if (__check_transaction_index(index)) |
return client_command.byte_enable[index]; |
else |
return('x); |
endfunction |
|
function automatic int get_command_burst_cycle(); // public |
// Write burst commands are received and processed by the slave BFM as |
// a sequence of discrete commands. The number of commands corresponds |
// to the burst count. A separate command descriptor is constructed for |
// each write burst cycle, corresponding to a partially completed burst. |
// Write data is incrementally added to each new descriptor in each burst |
// cycle until the command descriptor in final burst cycle contains |
// the full burst command data array. |
// The burst cycle field returned by this method tells the test bench |
// which burst cycle was active when this descriptor was constructed. |
// This facility enables the testbench to query partially completed |
// write burst operations. In other words, the testbench can query |
// the write data word on each burst cycle as it arrives and begin to |
// process it immediately rather than waiting until the entire burst |
// has been received. This makes it possible to perform pipelined write |
// burst processing in the test bench. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return client_command.burst_cycle; |
endfunction |
|
function automatic logic get_command_arbiterlock(); // public |
// Query the received command descriptor for the transaction arbiterlock. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
return client_command.arbiterlock; |
endfunction |
|
function automatic logic get_command_lock(); // public |
// Query the received command descriptor for the transaction lock. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
return client_command.lock; |
endfunction |
|
function automatic logic get_command_debugaccess(); // public |
// Query the received command descriptor for the transaction debugaccess. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
return client_command.debugaccess; |
endfunction |
|
function automatic logic [AV_TRANSACTIONID_W-1:0] get_command_transaction_id(); // public |
// Query the received command descriptor for the transaction ID. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return client_command.transaction_id; |
endfunction |
|
function automatic logic [AV_TRANSACTIONID_W-1:0] get_command_write_response_request(); // public |
$sformat(message, "%m: This API is no longer supported."); |
print(VERBOSITY_DEBUG, message); |
|
return 0; |
endfunction |
|
function automatic time get_command_begin_time(); // public |
// Returns the begin time of the transaction in the response descriptor that |
// has been popped from the response queue. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return client_command.begin_time; |
endfunction |
|
|
//-------------------------------------------------------------------------- |
// Response Transaction API |
//-------------------------------------------------------------------------- |
event signal_read_response_complete; // public |
// This event signals that the read response has been received and |
// pushed into the response queue. |
|
event signal_write_response_complete; // public |
// This event signals that the write response has been received and |
// pushed into the response queue. |
|
event signal_response_complete; // public |
// This event will fire when either signal_read_response_complete |
// or signal_write_response_complete fires and indicates that either |
// a read or a write response has been received and pushed into the |
// response queue. |
|
function automatic int get_command_issued_queue_size(); // public |
// Query the issued command queue to determine the number of |
// commands that have been driven to the system interconnect |
// fabric, but have not yet completed. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return (issued_read_command_queue.size() + issued_write_command_queue.size()); |
endfunction |
|
function automatic logic [lindex(AV_ADDRESS_W):0] get_response_address(); // public |
// Returns the transaction address in the response descriptor that |
// has been popped from the response queue. |
$sformat(message, "%m: called"); |
print(VERBOSITY_DEBUG, message); |
|
return return_response.address; |
endfunction |
|
function automatic logic [AV_NUMSYMBOLS-1:0] get_response_byte_enable(// public |
int index |
); |
// Returns the value of the byte enables in the response descriptor |
// that has been popped from the response queue. Each cycle of a |
// burst response is addressed individually by the specified index. |
$sformat(message, "%m: method called arg0 %0d", index); |
print(VERBOSITY_DEBUG, message); |
|
if (__check_transaction_index(index)) |
return return_response.byte_enable[index]; |
else |
return 'x; |
endfunction |
|
function automatic logic [lindex(AV_BURSTCOUNT_W):0] get_response_burst_size();// public |
// Returns the size of the response transaction burst in the |
// response descriptor that has been popped from the response queue. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return return_response.burst_count; |
endfunction |
|
function automatic logic [AV_DATA_W-1:0] get_response_data( //public |
int index |
); |
// Returns the transaction data in the response descriptor |
// that has been popped from the response queue. Each cycle in a |
// burst response is addressed individually by the specified index. |
// In the case of read responses, the data is the data captured on |
// the avs_readdata interface pin. In the case of write responses, |
// the data on the driven avs_writedata pin is captured and |
// reflected here. |
$sformat(message, "%m: method called arg0 %0d", index); |
print(VERBOSITY_DEBUG, message); |
|
if (__check_transaction_index(index)) |
return return_response.data[index]; |
else |
return 'x; |
endfunction |
|
function automatic int get_response_latency( // public |
int index = 0 |
); |
// Returns the transaction read latency in the response descriptor |
// that has been popped from the response queue. Each cycle in a |
// burst read has its own latency entry. For write transaction |
// responses the returned value will always be 0. |
$sformat(message, "%m: method called arg0 %0d", index); |
print(VERBOSITY_DEBUG, message); |
|
if (return_response.request == REQ_READ) |
if (__check_transaction_index(index)) begin |
return return_response.read_latency[index]; |
end else begin |
return -1; |
end |
else if (return_response.request == REQ_WRITE) begin |
if (index > 0) begin |
$sformat(message, "%m: Write response does not require burst index. Index value will be ignored"); |
print(VERBOSITY_WARNING, message); |
end |
return return_response.write_latency; |
end else begin |
return -1; |
end |
endfunction |
|
function automatic time get_response_begin_time(); // public |
// Returns the begin time of the transaction in the response descriptor that |
// has been popped from the response queue. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return return_response.begin_time; |
endfunction |
|
function automatic time get_response_end_time(); // public |
// Returns the begin time of the transaction in the response descriptor that |
// has been popped from the response queue. |
$sformat(message, "%m: method called. Returning %0t", return_response.end_time); |
print(VERBOSITY_DEBUG, message); |
|
return return_response.end_time; |
endfunction |
|
function automatic Request_t get_response_request(); // public |
// Returns the transaction command type in the response descriptor |
// that has been popped from the response queue. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return return_response.request; |
endfunction |
|
function automatic int get_response_queue_size(); // public |
// Queries the write and read response queue to determine |
// number of response descriptors currently stored in the BFM. |
// This is the number of responses the test program can immediately |
// pop off the response queue for further processing. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return read_response_queue.size() + write_response_queue.size(); |
endfunction |
|
function automatic int get_response_wait_time( // public |
int index |
); |
// Returns the wait time for a transaction in the response descriptor |
// that has been popped from the response queue. Each cycle in a burst |
// has its own wait time entry. |
$sformat(message, "%m: method called arg0 %0d", index); |
print(VERBOSITY_DEBUG, message); |
|
if (__check_transaction_index(index)) |
return return_response.wait_latency[index]; |
else |
return -1; |
endfunction |
|
function automatic void pop_response(); // public |
// Pop the transaction descriptor from the queue so that it can be |
// queried with the get_response methods by the test bench. |
|
int read_queue_head_seq_count = read_response_queue[$].seq_count; |
int write_queue_head_seq_count = write_response_queue[$].seq_count; |
|
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
if (read_queue_head_seq_count == write_queue_head_seq_count) begin |
$sformat(message, |
"%m: Identical sequence count in read and write response queues"); |
print(VERBOSITY_ERROR, message); |
-> signal_fatal_error; |
return; |
end else begin |
if ((read_response_queue.size() > 0) && |
((read_queue_head_seq_count < write_queue_head_seq_count) || |
(write_queue_head_seq_count == 0))) begin |
|
return_response = read_response_queue.pop_back(); |
$sformat(message,"%m: Pop read response"); |
print(VERBOSITY_DEBUG, message); |
end else if (write_response_queue.size() > 0) begin |
return_response = write_response_queue.pop_back(); |
$sformat(message,"%m: Pop write response"); |
print(VERBOSITY_DEBUG, message); |
end else begin |
$sformat(message,"%m: Failed to pop from response queues"); |
print(VERBOSITY_ERROR, message); |
-> signal_fatal_error; |
return; |
end |
end |
|
if (return_response.seq_count == 0) begin |
// sequence counter is initialized to 1 |
$sformat(message,"%m: Response transaction has sequence count of 0"); |
print(VERBOSITY_WARNING, message); |
end |
|
__print_response("Master Response", return_response);///foo |
|
endfunction |
|
function automatic AvalonResponseStatus_t get_read_response_status( // public |
int index |
); |
// Returns the transaction response status in the read response |
// descriptor that has been popped from the response queue. |
// If API is called when read response is not enabled, it will |
// return default value i.e. OKAY |
$sformat(message, "%m: called"); |
print(VERBOSITY_DEBUG, message); |
|
if (return_response.request == REQ_READ) begin |
if (USE_READRESPONSE == 1) begin |
return AvalonResponseStatus_t'(return_response.read_response[index]); |
end else begin |
$sformat(message, "%m: Read response is disabled, returning default value"); |
print(VERBOSITY_WARNING, message); |
return null_response_status; |
end |
end else begin |
$sformat(message, "%m: Read response queried on write response transaction"); |
print(VERBOSITY_WARNING, message); |
return null_response_status; |
end |
endfunction |
|
function automatic AvalonReadResponse_t get_response_read_response( // public |
int index |
); |
// API is no longer supported |
$sformat(message, "%m: API is not longer supported. Please use get_read_response_status API"); |
print(VERBOSITY_WARNING, message); |
|
return '0; |
endfunction |
|
function automatic AvalonWriteResponse_t get_response_write_response( // public |
int index |
); |
// API is no longer supported |
$sformat(message, "%m: API is not longer supported. Please use get_write_response_status API"); |
print(VERBOSITY_WARNING, message); |
|
return '0; |
endfunction |
|
function automatic AvalonTransactionId_t get_response_read_id(); // public |
// Returns the read id of transaction in the response descriptor that |
// has been popped from the response queue. |
$sformat(message, "%m: called"); |
print(VERBOSITY_DEBUG, message); |
if (return_response.request == REQ_WRITE) begin |
$sformat(message, "%m: Read response queried on write response transaction"); |
print(VERBOSITY_WARNING, message); |
end |
return return_response.read_id; |
endfunction |
|
function automatic AvalonResponseStatus_t get_write_response_status(); // public |
// Returns the transaction response status in the write response |
// descriptor that has been popped from the response queue. |
// If API is called when write response is not enabled or enabled but |
// write response not requested, it will return default value i.e. OKAY |
$sformat(message, "%m: called"); |
print(VERBOSITY_DEBUG, message); |
if (return_response.request == REQ_WRITE) begin |
if (USE_WRITERESPONSE == 1) begin |
return return_response.write_response; |
end else begin |
$sformat(message, |
"%m: Write response is disabled or enabled but no write response requested, returning default value"); |
print(VERBOSITY_WARNING, message); |
return null_response_status; |
end |
end else begin |
$sformat(message, "%m: Write response queried on read response transaction"); |
print(VERBOSITY_WARNING, message); |
return null_response_status; |
end |
endfunction |
|
function automatic AvalonTransactionId_t get_response_write_id(); // public |
// Returns the write id of transaction in the response descriptor that |
// has been popped from the response queue. |
$sformat(message, "%m: called"); |
print(VERBOSITY_DEBUG, message); |
if (return_response.request == REQ_READ) begin |
$sformat(message, "%m: Write response queried on read response transaction"); |
print(VERBOSITY_WARNING, message); |
end |
return return_response.write_id; |
endfunction |
|
function automatic logic get_clken(); // public |
// Return the clken status |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
return clken_register; |
endfunction |
|
function automatic int get_write_response_queue_size(); // public |
// Queries the write response queue to determine |
// number of response descriptors currently stored in the BFM. |
// This is the number of responses the test program can immediately |
// pop off the response queue for further processing. |
|
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return write_response_queue.size(); |
endfunction |
|
function automatic int get_read_response_queue_size(); // public |
// Queries the read response queue to determine |
// number of response descriptors currently stored in the BFM. |
// This is the number of responses the test program can immediately |
// pop off the response queue for further processing. |
|
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
return read_response_queue.size(); |
endfunction |
|
task automatic init(); // public |
// Initializes the counters and clear the queue. |
$sformat(message, "%m: method called"); |
print(VERBOSITY_DEBUG, message); |
|
__init_descriptors(); |
__init_queues(); |
endtask |
|
// =cut |
//-------------------------------------------------------------------------- |
// Private Methods |
// Note that private methods and events are prefixed with '__' |
//-------------------------------------------------------------------------- |
|
event __command_issued; |
|
function automatic int __check_transaction_index(int index); |
if (index > lindex(MAX_BURST_SIZE)) begin |
$sformat(message,"%m: Cycle index %0d exceeds MAX_BURST_SIZE-1 %0d", |
index, lindex(MAX_BURST_SIZE)); |
print(VERBOSITY_ERROR, message); |
->signal_fatal_error; |
return 0; |
end else begin |
return 1; |
end |
endfunction |
|
function automatic void __print_response(string text, |
Response_t response); |
string message = ""; |
print_divider(VERBOSITY_DEBUG); |
$sformat(message, "%m: %s", text); |
print(VERBOSITY_DEBUG, message); |
$sformat(message, "Request: %s", __request_str(response.request)); |
print(VERBOSITY_DEBUG, message); |
$sformat(message, "Address: %0x", response.address); |
print(VERBOSITY_DEBUG, message); |
$sformat(message, "Burst Count: %0x", response.burst_count); |
print(VERBOSITY_DEBUG, message); |
|
for (int i=0; i<response.burst_count; i++) begin |
if (response.request == REQ_WRITE) begin |
$sformat(message, " index: %0d wait: %0d", |
i, response.wait_latency[i]); |
end else if (response.request == REQ_READ) begin |
$sformat(message, |
" index: %0d data: %0x wait: %0d read latency: %0d", |
i, response.data[i], |
response.wait_latency[i], response.read_latency[i]); |
end else begin |
$sformat(message, " Invalid request field"); |
end |
print(VERBOSITY_DEBUG, message); |
end |
endfunction |
|
function automatic void __init_descriptors(); |
new_response = '0; |
current_command = '0; |
return_response = '0; |
completed_command = '0; |
command_addr_offset = 0; |
response_addr_offset = 0; |
client_command = '0; |
return_response = '0; |
command_sequence_counter = 1; |
wait_time = 0; |
write_burst_response_counter = 0; |
write_latency = 0; |
write_burst_command_counter = 0; |
read_latency = 0; |
command_waitrequested_start = 0; |
start_construct_complete_read_response = 0; |
start_construct_complete_write_response = 0; |
read_response_burst_counter = 0; |
endfunction |
|
function automatic void __init_queues(); |
issued_read_command_queue = {}; |
issued_write_command_queue = {}; |
read_response_queue = {}; |
write_response_queue = {}; |
command_queue = {}; |
endfunction |
|
function automatic string __request_str(Request_t request); |
case(request) |
REQ_READ: return "Read"; |
REQ_WRITE: return "Write"; |
REQ_IDLE: return "Idle"; |
endcase |
endfunction |
|
//-------------------------------------------------------------------------- |
// Local Machinery |
//-------------------------------------------------------------------------- |
always @(signal_fatal_error) abort_simulation(); |
|
always @(*) begin |
{ |
avs_clken, |
avs_arbiterlock, |
avs_lock, |
avs_debugaccess, |
avs_transactionid, |
avs_readid, |
avs_writeid, |
avs_response, |
avs_writeresponserequest, |
avs_writeresponsevalid, |
|
avs_waitrequest, |
avs_readdatavalid, |
avs_readdata, |
|
avs_write, |
avs_read, |
avs_address, |
avs_byteenable, |
avs_burstcount, |
avs_beginbursttransfer, |
avs_begintransfer, |
avs_writedata |
} <= tap; |
|
end |
|
assign avs_burstcount_int = (USE_BURSTCOUNT ? avs_burstcount : 'd1); |
|
//----------------------------------------------------------------------------- |
// This two block monitoring the response transaction |
//----------------------------------------------------------------------------- |
always @(posedge clk or posedge reset) begin |
clock_counter = clock_counter +1; |
if (reset) begin |
init(); |
end else begin |
if (!USE_CLKEN || avs_clken == 1) begin |
sampled_response(); |
end |
end |
end |
|
always @(posedge clk or posedge reset) begin |
if (reset) begin |
init(); |
end else begin |
if (!USE_CLKEN || avs_clken == 1) begin |
if ((get_command_issued_queue_size() == 0) && |
(start_construct_complete_write_response == 0) && |
start_construct_complete_read_response == 0) begin |
@__command_issued; |
end |
|
if (issued_write_command_queue.size() > 0) begin |
if (start_construct_complete_write_response == 0) begin |
completed_write_command = issued_write_command_queue.pop_back(); |
start_construct_complete_write_response = 1; |
end |
end |
|
if (issued_read_command_queue.size() > 0) begin |
if (read_response_burst_counter == 0 && |
start_construct_complete_read_response == 0) begin |
completed_read_command = issued_read_command_queue.pop_back(); |
start_construct_complete_read_response = 1; |
end |
end |
|
if (start_construct_complete_read_response) |
monitor_response(completed_read_command); |
|
if (start_construct_complete_write_response) |
monitor_response(completed_write_command); |
|
end |
end |
end |
|
//----------------------------------------------------------------------------- |
// This task monitoring the command port info and pass it to response |
// transaction. |
//----------------------------------------------------------------------------- |
task automatic sampled_response(); |
|
if (avs_read) begin |
response_addr_offset = 0; |
new_response.request = REQ_READ; |
new_response.data = 'x; |
new_response.wait_latency = 'x; |
new_response.byte_enable = 'x; |
new_response.write_latency = 'x; |
new_response.burst_count = avs_burstcount_int; |
new_response.burst_size = avs_burstcount_int; |
new_response.seq_count = command_sequence_counter++;; |
new_response.address = avs_address; |
new_response.read_id = 'x; |
new_response.read_response = 'x; |
new_response.begin_time = $time; |
|
if (USE_READ_DATA_VALID || USE_BURSTCOUNT) |
new_response.read_latency = 'x; |
else |
new_response.read_latency = AV_FIX_READ_LATENCY; |
|
if (avs_waitrequest) begin |
wait_time++; |
return; |
end |
|
new_response.wait_latency[response_addr_offset] = wait_time; |
new_response.byte_enable[response_addr_offset] = avs_byteenable; |
issued_read_command_queue.push_front(new_response); |
-> __command_issued; |
write_burst_response_counter = 0; |
wait_time = 0; |
clock_snapshot.push_front(clock_counter); |
end else if (avs_write) begin |
if (write_burst_response_counter == 0) begin |
write_burst_response_counter = avs_burstcount_int; |
new_response.seq_count = command_sequence_counter++;; |
response_addr_offset = 0; |
end |
|
new_response.read_latency = 'x; |
new_response.request = REQ_WRITE; |
new_response.data[response_addr_offset] = avs_writedata; |
new_response.byte_enable[response_addr_offset] = avs_byteenable; |
new_response.write_latency = 'x; |
if (response_addr_offset == 0) begin |
new_response.burst_count = avs_burstcount_int; |
new_response.burst_size = avs_burstcount_int; |
new_response.address = avs_address; |
new_response.begin_time = $time; |
end |
new_response.read_id = 'x; |
new_response.read_response = 'x; |
|
if (avs_waitrequest) begin |
wait_time++; |
return; |
end |
|
new_response.wait_latency[response_addr_offset] = wait_time; |
|
if (USE_WRITERESPONSE == 0) begin |
if (response_addr_offset == (new_response.burst_count-1)) begin |
if (STORE_RESPONSE == 1) begin |
if (get_response_queue_size() < transaction_fifo_max) begin |
new_response.end_time = $time; |
write_response_queue.push_front(new_response); |
if (get_response_queue_size() > transaction_fifo_threshold) |
->signal_transaction_fifo_threshold; |
end else begin |
$sformat(message, "%m(%0d): FIFO overflow! Transaction dropped.", `__LINE__); |
print(VERBOSITY_WARNING, message); |
->signal_transaction_fifo_overflow; |
end |
end |
-> signal_write_response_complete; |
end |
end else begin |
if (response_addr_offset == (new_response.burst_count-1)) begin |
issued_write_command_queue.push_front(new_response); |
-> __command_issued; |
end |
end |
|
response_addr_offset++; |
write_burst_response_counter--; |
wait_time = 0; |
end |
|
endtask |
|
//----------------------------------------------------------------------------- |
// This task monitoring the response port and construct a full response |
// transaction. |
//----------------------------------------------------------------------------- |
task automatic monitor_response(ref Response_t completed_response); |
case(completed_response.request) |
REQ_WRITE: begin |
// no response transaction while USE_WRITERESPONSE = 0 |
if (USE_WRITERESPONSE == 1) begin |
if (!avs_writeresponsevalid) begin |
write_latency++; |
return; |
end |
|
completed_response.write_id = avs_writeid; |
completed_response.write_latency = write_latency; |
|
if (!$cast(completed_response.write_response, avs_response)) |
begin |
$sformat(message, "%m: Response value is not valid when write response is valid"); |
print(VERBOSITY_FAILURE, message); |
end |
|
write_latency = 0; |
|
if (STORE_RESPONSE == 1) begin |
if (get_response_queue_size() < transaction_fifo_max) begin |
completed_response.end_time = $time; |
write_response_queue.push_front(completed_response); |
if (get_response_queue_size() > transaction_fifo_threshold) begin |
->signal_transaction_fifo_threshold; |
end |
end else begin |
$sformat(message, "%m(%0d): FIFO overflow! Transaction dropped.", `__LINE__); |
print(VERBOSITY_WARNING, message); |
->signal_transaction_fifo_overflow; |
end |
end |
-> signal_write_response_complete; |
start_construct_complete_write_response = 0; |
end |
end |
REQ_READ: begin |
if (USE_READ_DATA_VALID || USE_BURSTCOUNT) begin |
if (!avs_readdatavalid) begin |
read_latency++; |
return; |
end |
completed_response.data[read_response_burst_counter] = avs_readdata; |
completed_response.read_latency[read_response_burst_counter] = read_latency; |
|
if (USE_READRESPONSE) begin |
completed_response.read_id = avs_readid; |
|
if (!$cast(completed_response.read_response[read_response_burst_counter], avs_response)) |
begin |
$sformat(message, "%m: Response value is not valid when read response is valid"); |
print(VERBOSITY_FAILURE, message); |
end |
end |
|
read_latency = 0; |
|
end else begin |
if (AV_FIX_READ_LATENCY > 0) begin |
if (clock_counter - clock_snapshot[$] < AV_FIX_READ_LATENCY) begin |
return; |
end |
current_time = clock_snapshot.pop_back(); |
end |
|
completed_response.read_latency[0] = AV_FIX_READ_LATENCY; |
completed_response.data[0] = avs_readdata; |
|
if (USE_READRESPONSE) begin |
completed_response.read_id = avs_readid; |
|
if (!$cast(completed_response.read_response[0], avs_response)) |
begin |
$sformat(message, "%m: Response value is not valid when read response is valid"); |
print(VERBOSITY_FAILURE, message); |
end |
end |
read_latency = 0; |
end |
|
if (read_response_burst_counter == completed_response.burst_count-1) begin |
if (STORE_RESPONSE == 1) begin |
if (get_response_queue_size() < transaction_fifo_max) begin |
completed_response.end_time = $time; |
read_response_queue.push_front(completed_response); |
if (get_response_queue_size() > transaction_fifo_threshold) |
->signal_transaction_fifo_threshold; |
end else begin |
$sformat(message, "%m(%0d): FIFO overflow! Transaction dropped.", `__LINE__); |
print(VERBOSITY_WARNING, message); |
->signal_transaction_fifo_overflow; |
end |
end |
->signal_read_response_complete; |
read_response_burst_counter = 0; |
start_construct_complete_read_response = 0; |
end else begin |
read_response_burst_counter++; |
end |
end |
endcase |
endtask |
|
always @(signal_read_response_complete or |
signal_write_response_complete or |
posedge reset) begin |
if (!reset) begin |
->signal_response_complete; |
end |
end |
|
|
//----------------------------------------------------------------------------- |
// This block monitoring the command transaction |
//----------------------------------------------------------------------------- |
always @(posedge clk or posedge reset) begin |
clken_register <= avs_clken; |
if (reset) begin |
init(); |
end else begin |
if (!USE_CLKEN || avs_clken == 1) begin |
monitor_command(); |
end |
end |
end |
|
//----------------------------------------------------------------------------- |
// This task monitoring the command port and construct a full command |
// transaction. |
//----------------------------------------------------------------------------- |
task automatic monitor_command(); |
if (avs_write) begin |
if (write_burst_command_counter == 0) begin |
write_burst_command_counter = avs_burstcount_int; |
command_addr_offset = 0; |
end |
|
current_command.request = REQ_WRITE; |
current_command.data[command_addr_offset] = avs_writedata; |
current_command.byte_enable[command_addr_offset] = avs_byteenable; |
if (command_addr_offset == 0) begin |
current_command.address = avs_address; |
current_command.burst_count = avs_burstcount_int; |
current_command.transaction_id = avs_transactionid; |
end |
|
current_command.burst_cycle = command_addr_offset; |
current_command.arbiterlock = avs_arbiterlock; |
current_command.lock = avs_lock; |
current_command.debugaccess = avs_debugaccess; |
|
if (command_waitrequested_start == 0) begin |
if ((consolidate_write_burst_transactions && |
(command_addr_offset == current_command.burst_count-1)) || |
!consolidate_write_burst_transactions) begin |
if (STORE_COMMAND == 1) begin |
if (get_command_queue_size() < transaction_fifo_max) begin |
current_command.begin_time = $time; |
command_queue.push_front(current_command); |
if (get_command_queue_size() > transaction_fifo_threshold) |
->signal_transaction_fifo_threshold; |
end else begin |
$sformat(message, "%m(%0d): FIFO overflow! Transaction dropped.", `__LINE__); |
print(VERBOSITY_WARNING, message); |
->signal_transaction_fifo_overflow; |
end |
end |
->signal_command_received; |
end |
if (avs_waitrequest) begin |
command_waitrequested_start = 1; |
return; |
end |
end else begin |
if (avs_waitrequest) |
return; |
else |
command_waitrequested_start = 0; |
end |
command_addr_offset++; |
write_burst_command_counter--; |
end else if (avs_read) begin |
|
current_command = 'x; |
write_burst_command_counter = 0; |
command_addr_offset = 0; |
|
current_command.request = REQ_READ; |
current_command.address = avs_address; |
current_command.data = 'x; |
current_command.byte_enable = avs_byteenable; |
current_command.burst_count = avs_burstcount_int; |
current_command.arbiterlock = avs_arbiterlock; |
current_command.lock = avs_lock; |
current_command.debugaccess = avs_debugaccess; |
current_command.transaction_id = avs_transactionid; |
|
if (command_waitrequested_start == 0) begin |
if (STORE_COMMAND == 1) begin |
if (get_command_queue_size() < transaction_fifo_max) begin |
current_command.begin_time = $time; |
command_queue.push_front(current_command); |
if (get_command_queue_size() > transaction_fifo_threshold) |
->signal_transaction_fifo_threshold; |
end else begin |
$sformat(message, "%m(%0d): FIFO overflow! Transaction dropped.", `__LINE__); |
print(VERBOSITY_WARNING, message); |
->signal_transaction_fifo_overflow; |
end |
end |
->signal_command_received; |
if (avs_waitrequest) begin |
command_waitrequested_start = 1; |
return; |
end |
end else begin |
if (avs_waitrequest) |
return; |
else |
command_waitrequested_start = 0; |
end |
end |
endtask |
|
// synthesis translate_on |
endmodule |
|
|
|
/sim/src/amm_monitor/amm_checker.sv
0,0 → 1,149
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 |
amm_checker |
#( |
A = 32, // address bus width |
N = 8, // data bus width in bytes |
B = 7 // burstcount width |
) |
( |
amm_if amm_s, |
amm_if amm_m, |
|
input clk, // amm_monitor_clk.clk |
input reset // amm_monitor_clk_reset.reset |
); |
|
// -------------------------------------------------------------------- |
// |
localparam A_S = A - $clog2(N) - 1; |
|
|
// -------------------------------------------------------------------- |
// |
altera_avalon_mm_monitor #( |
.AV_ADDRESS_W (A), |
.AV_SYMBOL_W (8), |
.AV_NUMSYMBOLS (N), |
.AV_BURSTCOUNT_W (B), |
.USE_READ (1), |
.USE_WRITE (1), |
.USE_ADDRESS (1), |
.USE_BYTE_ENABLE (1), |
.USE_BURSTCOUNT (1), |
.USE_READ_DATA (1), |
.USE_READ_DATA_VALID (1), |
.USE_WRITE_DATA (1), |
.USE_BEGIN_TRANSFER (0), |
.USE_BEGIN_BURST_TRANSFER (0), |
.USE_WAIT_REQUEST (1), |
.AV_CONSTANT_BURST_BEHAVIOR (1), |
.AV_BURST_LINEWRAP (0), |
.AV_BURST_BNDR_ONLY (0), |
.AV_READ_TIMEOUT (256), |
.AV_WRITE_TIMEOUT (256), |
.AV_WAITREQUEST_TIMEOUT (1024), |
.AV_MAX_PENDING_READS (3), |
.AV_MAX_PENDING_WRITES (3), |
.AV_FIX_READ_LATENCY (0), |
.AV_MAX_READ_LATENCY (100), |
.AV_MAX_WAITREQUESTED_READ (100), |
.AV_MAX_WAITREQUESTED_WRITE (100), |
.MASTER_ADDRESS_TYPE ("SYMBOLS"), |
.SLAVE_ADDRESS_TYPE ("WORDS"), |
.VHDL_ID (0), |
.AV_READRESPONSE_W (8), |
.AV_WRITERESPONSE_W (8), |
.USE_ARBITERLOCK (0), |
.USE_LOCK (0), |
.USE_DEBUGACCESS (0), |
.USE_TRANSACTIONID (0), |
.USE_WRITERESPONSE (0), |
.USE_READRESPONSE (0), |
.USE_CLKEN (0), |
.AV_MAX_CONTINUOUS_READ (5), |
.AV_MAX_CONTINUOUS_WRITE (5), |
.AV_MAX_CONTINUOUS_WAITREQUEST (5), |
.AV_MAX_CONTINUOUS_READDATAVALID (5), |
.AV_READ_WAIT_TIME (1), |
.AV_WRITE_WAIT_TIME (0), |
.REGISTER_WAITREQUEST (0), |
.AV_REGISTERINCOMINGSIGNALS (0) |
) amm_monitor ( |
.clk (clk), // clk.clk |
.reset (reset), // clk_reset.reset |
.avs_waitrequest (amm_s.waitrequest), // s0.waitrequest |
.avs_write (amm_s.write), // .write |
.avs_read (amm_s.read), // .read |
.avs_address (amm_s.address[A_S:0]), // .address |
.avs_byteenable (amm_s.byteenable), // .byteenable |
.avs_burstcount (amm_s.burstcount), // .burstcount |
.avs_readdata (amm_s.readdata), // .readdata |
.avs_readdatavalid (amm_s.readdatavalid), // .readdatavalid |
.avs_writedata (amm_s.writedata), // .writedata |
.avm_waitrequest (amm_m.waitrequest), // m0.waitrequest |
.avm_write (amm_m.write), // .write |
.avm_read (amm_m.read), // .read |
.avm_address (amm_m.address), // .address |
.avm_byteenable (amm_m.byteenable), // .byteenable |
.avm_burstcount (amm_m.burstcount), // .burstcount |
.avm_readdata (amm_m.readdata), // .readdata |
.avm_readdatavalid (amm_m.readdatavalid), // .readdatavalid |
.avm_writedata (amm_m.writedata), // .writedata |
.avs_begintransfer (1'b0), // (terminated) |
.avm_begintransfer (), // (terminated) |
.avs_beginbursttransfer (1'b0), // (terminated) |
.avm_beginbursttransfer (), // (terminated) |
.avs_transactionid (8'b00000000), // (terminated) |
.avm_transactionid (), // (terminated) |
.avs_response (), // (terminated) |
.avm_response (2'b00), // (terminated) |
.avs_readid (), // (terminated) |
.avm_readid (8'b00000000), // (terminated) |
.avs_writeresponserequest (1'b0), // (terminated) |
.avm_writeresponserequest (), // (terminated) |
.avs_writeresponsevalid (), // (terminated) |
.avm_writeresponsevalid (1'b0), // (terminated) |
.avs_writeid (), // (terminated) |
.avm_writeid (8'b00000000), // (terminated) |
.avs_arbiterlock (1'b0), // (terminated) |
.avm_arbiterlock (), // (terminated) |
.avs_lock (1'b0), // (terminated) |
.avm_lock (), // (terminated) |
.avs_debugaccess (1'b0), // (terminated) |
.avm_debugaccess (), // (terminated) |
.avs_clken (1'b1), // (terminated) |
.avm_clken (), // (terminated) |
.avm_readresponse (8'b00000000), // (terminated) |
.avs_readresponse (), // (terminated) |
.avm_writeresponse (8'b00000000), // (terminated) |
.avs_writeresponse () // (terminated) |
); |
|
endmodule |
/sim/src/amm_monitor/avalon_mm_pkg.sv
0,0 → 1,77
// (C) 2001-2016 Intel Corporation. All rights reserved. |
// Your use of Intel Corporation's design tools, logic functions and other |
// software and tools, and its AMPP partner logic functions, and any output |
// files any of the foregoing (including device programming or simulation |
// files), and any associated documentation or information are expressly subject |
// to the terms and conditions of the Intel Program License Subscription |
// Agreement, Intel MegaCore Function License Agreement, or other applicable |
// license agreement, including, without limitation, that your use is for the |
// sole purpose of programming logic devices manufactured by Intel and sold by |
// Intel or its authorized distributors. Please refer to the applicable |
// agreement for further details. |
|
|
// $Id: //acds/rel/16.1/ip/sopc/components/verification/lib/avalon_mm_pkg.sv#1 $ |
// $Revision: #1 $ |
// $Date: 2016/08/07 $ |
//----------------------------------------------------------------------------- |
// =head1 NAME |
// avalon_mm_pkg |
// =head1 SYNOPSIS |
// Package for shared Avalon MM component types. |
//----------------------------------------------------------------------------- |
// =head1 COPYRIGHT |
// Copyright (c) 2008 Altera Corporation. All Rights Reserved. |
// The information contained in this file is the property of Altera |
// Corporation. Except as specifically authorized in writing by Altera |
// Corporation, the holder of this file shall keep all information |
// contained herein confidential and shall protect same in whole or in part |
// from disclosure and dissemination to all third parties. Use of this |
// program confirms your agreement with the terms of this license. |
//----------------------------------------------------------------------------- |
// =head1 DESCRIPTION |
// This package contains shared non-parameterized type definitions. |
// =cut |
`timescale 1ns / 1ns |
|
`ifndef _AVALON_MM_PKG_ |
`define _AVALON_MM_PKG_ |
|
package avalon_mm_pkg; |
import verbosity_pkg::*; |
|
// Transaction request types |
typedef enum int { // public |
REQ_READ = 0, // Read Request |
REQ_WRITE = 1, // Write Request |
REQ_IDLE = 2 // Idle |
} Request_t; |
|
// Slave BFM wait state logic operates in one of three distinct modes |
typedef enum int { |
WAIT_FIXED = 0, // default: fixed wait cycles per burst cycle |
WAIT_RANDOM = 1, // random min =< wait cycles <= max |
WAIT_ADDRESSABLE = 2 // fixed wait cycles per command address |
} SlaveWaitMode_t; |
|
// Avalon MM transaction response status |
typedef enum logic[1:0] { |
AV_OKAY = 0, |
AV_RESERVED = 1, |
AV_SLAVE_ERROR = 2, |
AV_DECODE_ERROR = 3 |
} AvalonResponseStatus_t; |
|
function automatic string request_string(Request_t request); |
case(request) |
REQ_READ: return("read"); |
REQ_WRITE: return("write"); |
REQ_IDLE: return("idle"); |
default: return("INVALID_REQUEST"); |
endcase |
endfunction |
|
endpackage |
|
`endif |
|
/sim/src/amm_monitor/verbosity_pkg.sv
0,0 → 1,193
// (C) 2001-2016 Intel Corporation. All rights reserved. |
// Your use of Intel Corporation's design tools, logic functions and other |
// software and tools, and its AMPP partner logic functions, and any output |
// files any of the foregoing (including device programming or simulation |
// files), and any associated documentation or information are expressly subject |
// to the terms and conditions of the Intel Program License Subscription |
// Agreement, Intel MegaCore Function License Agreement, or other applicable |
// license agreement, including, without limitation, that your use is for the |
// sole purpose of programming logic devices manufactured by Intel and sold by |
// Intel or its authorized distributors. Please refer to the applicable |
// agreement for further details. |
|
|
// $Id: //acds/rel/16.1/ip/sopc/components/verification/lib/verbosity_pkg.sv#1 $ |
// $Revision: #1 $ |
// $Date: 2016/08/07 $ |
//----------------------------------------------------------------------------- |
// =head1 NAME |
// verbosity_pkg |
// =head1 SYNOPSIS |
// Package for controlling verbosity of messages sent to the console |
//----------------------------------------------------------------------------- |
// =head1 COPYRIGHT |
// Copyright (c) 2008 Altera Corporation. All Rights Reserved. |
// The information contained in this file is the property of Altera |
// Corporation. Except as specifically authorized in writing by Altera |
// Corporation, the holder of this file shall keep all information |
// contained herein confidential and shall protect same in whole or in part |
// from disclosure and dissemination to all third parties. Use of this |
// program confirms your agreement with the terms of this license. |
//----------------------------------------------------------------------------- |
// =head1 DESCRIPTION |
// This module will dump diagnostic messages to the console during |
// simulation. The level of verbosity can be controlled in the test |
// bench by using the *set_verbosity* method in the imported package |
// verbosity_pkg. For a given setting, message at that level and all |
// lower levels are dumped. For example, setting VERBOSITY_DEBUG level |
// causes all messages to be dumped, while VERBOSITY_FAILURE restricts |
// only failure messages and those tagged as VERBOSITY_NONE to be |
// dumped. |
// The different levels are: |
// =over 4 |
// =item 1 VERBOSITY_NONE |
// Messages tagged with this level are always dumped to the console. |
// =item 2 VERBOSITY_FAILURE |
// A fatal simulation error has occurred and the simulator will exit. |
// =item 3 VERBOSITY_ERROR |
// A non-fatal error has occured. An example is a data comparison mismatch. |
// =item 4 VERBOSITY_WARNING |
// Warn the user that a potential error has occurred. |
// =item 5 VERBOSITY_INFO |
// Informational message. |
// =item 6 VERBOSITY_DEBUG |
// Dump enough state to diagnose problem scenarios. |
// =back |
|
|
`ifndef _AVALON_VERBOSITY_PKG_ |
`define _AVALON_VERBOSITY_PKG_ |
|
package verbosity_pkg; |
|
timeunit 1ps; |
timeprecision 1ps; |
|
typedef enum int {VERBOSITY_NONE, |
VERBOSITY_FAILURE, |
VERBOSITY_ERROR, |
VERBOSITY_WARNING, |
VERBOSITY_INFO, |
VERBOSITY_DEBUG} Verbosity_t; |
|
Verbosity_t verbosity = VERBOSITY_INFO; |
string message = ""; |
int dump_file; |
int dump = 0; |
|
//-------------------------------------------------------------------------- |
// =head1 Public Methods API |
// =pod |
// This section describes the public methods in the application programming |
// interface (API). In this case the application program is the test bench |
// or component which imports this package. |
// =cut |
//-------------------------------------------------------------------------- |
|
function automatic Verbosity_t get_verbosity(); // public |
// Returns the global verbosity setting. |
return verbosity; |
endfunction |
|
function automatic void set_verbosity ( // public |
Verbosity_t v |
); |
// Sets the global verbosity setting. |
|
string verbosity_str; |
verbosity = v; |
|
case(verbosity) |
VERBOSITY_NONE: verbosity_str = "VERBOSITY_"; |
VERBOSITY_FAILURE: verbosity_str = "VERBOSITY_FAILURE"; |
VERBOSITY_ERROR: verbosity_str = "VERBOSITY_ERROR"; |
VERBOSITY_WARNING: verbosity_str = "VERBOSITY_WARNING"; |
VERBOSITY_INFO: verbosity_str = "VERBOSITY_INFO"; |
VERBOSITY_DEBUG: verbosity_str = "VERBOSITY_DEBUG"; |
default: verbosity_str = "UNKNOWN"; |
endcase |
$sformat(message, "%m: Setting Verbosity level=%0d (%s)", |
verbosity, verbosity_str); |
print(VERBOSITY_NONE, message); |
endfunction |
|
function automatic void print( // public |
Verbosity_t level, |
string message |
); |
// Print a message to the console if the verbosity argument |
// is less than or equal to the global verbosity setting. |
string level_str; |
|
if (level <= verbosity) begin |
case(level) |
VERBOSITY_NONE: level_str = ""; |
VERBOSITY_FAILURE: level_str = "FAILURE:"; |
VERBOSITY_ERROR: level_str = "ERROR:"; |
VERBOSITY_WARNING: level_str = "WARNING:"; |
VERBOSITY_INFO: level_str = "INFO:"; |
VERBOSITY_DEBUG: level_str = "DEBUG:"; |
default: level_str = "UNKNOWN:"; |
endcase |
|
$display("%t: %s %s",$time, level_str, message); |
if (dump) begin |
$fdisplay(dump_file, "%t: %s %s",$time, level_str, message); |
end |
end |
endfunction |
|
function automatic void print_divider( // public |
Verbosity_t level |
); |
// Prints a divider line to the console to make a block of related text |
// easier to identify and read. |
string message; |
$sformat(message, |
"------------------------------------------------------------"); |
print(level, message); |
endfunction |
|
function automatic void open_dump_file ( // public |
string dump_file_name = "avalon_bfm_sim.log" |
); |
// Opens a dump file which collects console messages. |
|
if (dump) begin |
$sformat(message, "%m: Dump file already open - ignoring open."); |
print(VERBOSITY_ERROR, message); |
end else begin |
dump_file = $fopen(dump_file_name, "w"); |
$fdisplay(dump_file, "testing dump file"); |
$sformat(message, "%m: Opening dump file: %s", dump_file_name); |
print(VERBOSITY_INFO, message); |
dump = 1; |
end |
endfunction |
|
function automatic void close_dump_file(); // public |
// Close the console message dump file. |
if (!dump) begin |
$sformat(message, "%m: No open dump file - ignoring close."); |
print(VERBOSITY_ERROR, message); |
end else begin |
dump = 0; |
$fclose(dump_file); |
$sformat(message, "%m: Closing dump file"); |
print(VERBOSITY_INFO, message); |
end |
endfunction |
|
function automatic void abort_simulation(); |
string message; |
$sformat(message, "%m: Abort the simulation due to fatal error incident."); |
print(VERBOSITY_FAILURE, message); |
$stop; |
endfunction |
|
endpackage |
|
// =cut |
|
`endif |
|
/sim/src/tb_amm_bfm.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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
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; |
wire clk = tb_clk; |
wire reset = tb_rst; |
|
tb_base #(.PERIOD(10_000)) tb(clk_100mhz, tb_rst); |
|
|
// -------------------------------------------------------------------- |
// |
localparam A = 32; |
localparam N = 8; |
localparam B = 7; |
|
|
// -------------------------------------------------------------------- |
// |
amm_if #(.A(A), .N(N), .B(B)) |
amm_m(.*); |
|
amm_if #(.A(A), .N(N), .B(B)) |
amm_s(.*); |
|
|
// -------------------------------------------------------------------- |
// |
|
|
// -------------------------------------------------------------------- |
// sim models |
// | | | | | | | | | | | | | | | | | |
// \|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/ |
// ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' |
|
// -------------------------------------------------------------------- |
// |
import tb_amm_bfm_agent_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
amm_checker #(.A(A), .N(N), .B(B)) |
amm_checker_i(.*); |
|
|
// -------------------------------------------------------------------- |
// |
amm_master_bfm_if #(.A(A), .N(N)) |
tb_amm_m(.*); |
|
amm_slave_bfm_if #(.A(A), .N(N)) |
tb_amm_s(.*); |
|
|
// -------------------------------------------------------------------- |
// |
tb_amm_bfm_agent_class bfm; |
|
initial |
bfm = new(tb_amm_m, tb_amm_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/tests/tb_amm_bfm/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 avalon_lib |
|
# simulation $root |
vlog $env(PROJECT_DIR)/sim/src/tb_amm_bfm.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/tb_amm_bfm/sim.do
0,0 → 1,22
# |
# |
|
|
quit -sim |
|
# vsim opt_tb_top |
|
vsim -novopt 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/tb_amm_bfm/the_test.sv
0,0 → 1,92
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 amm_transaction_pkg::*; |
amm_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(10000us); |
|
|
// -------------------------------------------------------------------- |
wait(~tb_rst); |
|
#100ns; |
|
|
// // -------------------------------------------------------------------- |
// #100ns; |
// repeat(5000) |
// // repeat(50) |
// tb_top.bfm.random_read_burst; |
|
|
// -------------------------------------------------------------------- |
// #2000us; |
#20us; |
|
|
// -------------------------------------------------------------------- |
// insert test above |
// -------------------------------------------------------------------- |
|
endtask |
|
|
endmodule |
|
/sim/tests/tb_amm_bfm/wip.do
0,0 → 1,17
# |
|
# vlog -f ../../libs/packages_verilog/tb_lib.f |
# vlog -f ../../libs/sim_verilog/axi4_bfm.f |
# vlog -f ../../libs/axi4_lib_verilog/axi4_base.f |
|
vlog -f ../../libs/packages_verilog/amm_bfm.f |
vlog -f ../../libs/sim_verilog/amm_bfm.f |
vlog -f ../../libs/avalon_lib_verilog/amm_base.f |
|
# simulation $root |
vlog ../../src/tb_amm_bfm.sv |
|
# compile test last |
vlog ./the_test.sv |
|
|
/src/amm_if.sv
53,6 → 53,7
logic readyfordata; |
logic dataavailable; |
logic resetrequest; |
logic chipselect; |
|
|
// -------------------------------------------------------------------- |
/syn/ip/amm_monitor.qsys
0,0 → 1,119
<?xml version="1.0" encoding="UTF-8"?> |
<system name="$${FILENAME}"> |
<component |
name="$${FILENAME}" |
displayName="$${FILENAME}" |
version="1.0" |
description="" |
tags="" |
categories="" /> |
<parameter name="bonusData"><![CDATA[bonusData |
{ |
element amm_monitor |
{ |
datum _sortIndex |
{ |
value = "0"; |
type = "int"; |
} |
} |
} |
]]></parameter> |
<parameter name="clockCrossingAdapter" value="HANDSHAKE" /> |
<parameter name="device" value="10AS066N3F40E2SG" /> |
<parameter name="deviceFamily" value="Arria 10" /> |
<parameter name="deviceSpeedGrade" value="2" /> |
<parameter name="fabricMode" value="QSYS" /> |
<parameter name="generateLegacySim" value="false" /> |
<parameter name="generationId" value="0" /> |
<parameter name="globalResetBus" value="false" /> |
<parameter name="hdlLanguage" value="VERILOG" /> |
<parameter name="hideFromIPCatalog" value="false" /> |
<parameter name="lockedInterfaceDefinition" value="" /> |
<parameter name="maxAdditionalLatency" value="1" /> |
<parameter name="projectName" value="" /> |
<parameter name="sopcBorderPoints" value="false" /> |
<parameter name="systemHash" value="0" /> |
<parameter name="testBenchDutName" value="" /> |
<parameter name="timeStamp" value="0" /> |
<parameter name="useTestBenchNamingPattern" value="false" /> |
<instanceScript></instanceScript> |
<interface |
name="amm_monitor_clk" |
internal="amm_monitor.clk" |
type="clock" |
dir="end" /> |
<interface |
name="amm_monitor_clk_reset" |
internal="amm_monitor.clk_reset" |
type="reset" |
dir="end" /> |
<interface |
name="amm_monitor_m0" |
internal="amm_monitor.m0" |
type="avalon" |
dir="start" /> |
<interface |
name="amm_monitor_s0" |
internal="amm_monitor.s0" |
type="avalon" |
dir="end" /> |
<module |
name="amm_monitor" |
kind="altera_avalon_mm_monitor" |
version="16.1" |
enabled="1"> |
<parameter name="AV_ADDRESS_W" value="32" /> |
<parameter name="AV_ALWAYS_BURST_MAX_BURST" value="0" /> |
<parameter name="AV_BURSTCOUNT_W" value="7" /> |
<parameter name="AV_BURST_BNDR_ONLY" value="0" /> |
<parameter name="AV_BURST_LINEWRAP" value="0" /> |
<parameter name="AV_CONSTANT_BURST_BEHAVIOR" value="1" /> |
<parameter name="AV_FIX_READ_LATENCY" value="0" /> |
<parameter name="AV_MAX_CONTINUOUS_READ" value="5" /> |
<parameter name="AV_MAX_CONTINUOUS_READDATAVALID" value="5" /> |
<parameter name="AV_MAX_CONTINUOUS_WAITREQUEST" value="5" /> |
<parameter name="AV_MAX_CONTINUOUS_WRITE" value="5" /> |
<parameter name="AV_MAX_PENDING_READS" value="1" /> |
<parameter name="AV_MAX_PENDING_WRITES" value="0" /> |
<parameter name="AV_MAX_READ_LATENCY" value="100" /> |
<parameter name="AV_MAX_WAITREQUESTED_READ" value="100" /> |
<parameter name="AV_MAX_WAITREQUESTED_WRITE" value="100" /> |
<parameter name="AV_NUMSYMBOLS" value="8" /> |
<parameter name="AV_READRESPONSE_W" value="8" /> |
<parameter name="AV_READ_TIMEOUT" value="100" /> |
<parameter name="AV_READ_WAIT_TIME" value="1" /> |
<parameter name="AV_REGISTERINCOMINGSIGNALS" value="0" /> |
<parameter name="AV_SYMBOL_W" value="8" /> |
<parameter name="AV_WAITREQUEST_TIMEOUT" value="1024" /> |
<parameter name="AV_WRITERESPONSE_W" value="8" /> |
<parameter name="AV_WRITE_TIMEOUT" value="100" /> |
<parameter name="AV_WRITE_WAIT_TIME" value="0" /> |
<parameter name="MASTER_ADDRESS_TYPE" value="SYMBOLS" /> |
<parameter name="REGISTER_WAITREQUEST" value="0" /> |
<parameter name="SLAVE_ADDRESS_TYPE" value="WORDS" /> |
<parameter name="USE_ADDRESS" value="1" /> |
<parameter name="USE_ARBITERLOCK" value="0" /> |
<parameter name="USE_BEGIN_BURST_TRANSFER" value="0" /> |
<parameter name="USE_BEGIN_TRANSFER" value="0" /> |
<parameter name="USE_BURSTCOUNT" value="1" /> |
<parameter name="USE_BYTE_ENABLE" value="1" /> |
<parameter name="USE_CLKEN" value="0" /> |
<parameter name="USE_DEBUGACCESS" value="0" /> |
<parameter name="USE_LOCK" value="0" /> |
<parameter name="USE_READ" value="1" /> |
<parameter name="USE_READRESPONSE" value="0" /> |
<parameter name="USE_READ_DATA" value="1" /> |
<parameter name="USE_READ_DATA_VALID" value="1" /> |
<parameter name="USE_TRANSACTIONID" value="0" /> |
<parameter name="USE_WAIT_REQUEST" value="1" /> |
<parameter name="USE_WRITE" value="1" /> |
<parameter name="USE_WRITERESPONSE" value="0" /> |
<parameter name="USE_WRITE_DATA" value="1" /> |
<parameter name="VHDL_ID" value="0" /> |
</module> |
<interconnectRequirement for="$system" name="qsys_mm.clockCrossingAdapter" value="HANDSHAKE" /> |
<interconnectRequirement for="$system" name="qsys_mm.enableEccProtection" value="FALSE" /> |
<interconnectRequirement for="$system" name="qsys_mm.insertDefaultSlave" value="FALSE" /> |
<interconnectRequirement for="$system" name="qsys_mm.maxAdditionalLatency" value="1" /> |
</system> |