OpenCores
URL https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk

Subversion Repositories qaz_libs

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /qaz_libs/trunk/avalon_lib
    from Rev 50 to Rev 35
    Reverse comparison

Rev 50 → Rev 35

/docs/Avalon Verification IP Suite User Guide .pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
docs/Avalon Verification IP Suite User Guide .pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: docs/mnl_avalon_spec.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/mnl_avalon_spec.pdf =================================================================== --- docs/mnl_avalon_spec.pdf (nonexistent) +++ docs/mnl_avalon_spec.pdf (revision 35)
docs/mnl_avalon_spec.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: src/ast_ready_cycle_fsm.sv =================================================================== --- src/ast_ready_cycle_fsm.sv (nonexistent) +++ src/ast_ready_cycle_fsm.sv (revision 35) @@ -0,0 +1,106 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// 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 + ast_ready_cycle_fsm + ( + input axis_en, + output axis_tvalid, + input axis_tready, + + input fifo_watermark, // OK to use fifo_almost_full if FIFO is synchronous, assert to flush also + input fifo_empty, + output fifo_rd_en, + + output data_to_axis_fsm_error, + + input aclk, + input aresetn + ); + + //--------------------------------------------------- + // state machine binary definitions + enum reg [3:0] { + IDLE_STATE = 4'b0001, + TVALID = 4'b0010, + TREADY = 4'b0100, + ERROR_STATE = 4'b1000 + } state, next_state; + + + //--------------------------------------------------- + // state machine flop + always_ff @(posedge aclk) + if(~aresetn) + state <= IDLE_STATE; + else + state <= next_state; + + + //--------------------------------------------------- + // state machine + always_comb + case(state) + IDLE_STATE: if(axis_en & fifo_watermark & ~fifo_empty) + if(axis_tready) + next_state <= TREADY; + else + next_state <= TVALID; + else + next_state <= IDLE_STATE; + + TVALID: if(axis_tready) // wait for slave to be ready + next_state <= TREADY; + else + next_state <= TVALID; + + TREADY: if(fifo_empty) // slave can accept data + next_state <= IDLE_STATE; + else if(axis_tready) + next_state <= TREADY; + else + next_state <= TVALID; + + ERROR_STATE: next_state <= IDLE_STATE; + + default: next_state <= ERROR_STATE; + + endcase + + + //--------------------------------------------------- + // outputs + assign axis_tvalid = (next_state == TVALID) | (next_state == TREADY); + assign fifo_rd_en = axis_tvalid & axis_tready; + assign data_to_axis_fsm_error = (state == ERROR_STATE); + + +//--------------------------------------------------- +// +endmodule + Index: syn/ast_monitor/altera_avalon_st_monitor_171/sim/altera_avalon_st_monitor.sv =================================================================== --- syn/ast_monitor/altera_avalon_st_monitor_171/sim/altera_avalon_st_monitor.sv (nonexistent) +++ syn/ast_monitor/altera_avalon_st_monitor_171/sim/altera_avalon_st_monitor.sv (revision 35) @@ -0,0 +1,292 @@ +// (C) 2001-2017 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 from 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 FPGA IP 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/17.1std/ip/sopc/components/verification/altera_avalon_st_monitor_bfm/altera_avalon_st_monitor.sv#1 $ +// $Revision: #1 $ +// $Date: 2017/07/30 $ +//----------------------------------------------------------------------------- +// =head1 NAME +// altera_avalon_st_monitor +// =head1 SYNOPSIS +// Bridge with Avalon Bus Protocol Assertion Checker +//----------------------------------------------------------------------------- +// =head1 DESCRIPTION +// This module implements Avalon ST protocol assertion checking for simulation. +// The component acts as a simple repeater with Avalon bus signals +// passed through from the sink to source interface. +// The instantiated altera_avalon_st_monitor snoops all passing Avalon +// bus signals and performs assertion checking and measures coverage on +// Avalon Streaming protocol properties. +// Transactions in transit may also be captured in a transaction buffer and +// extracted from the monitor via the API. +// The macro ALTERA_AVALON_SIM_SVA is defined to disable SVA processing +// The macro ENABLE_ALTERA_AVALON_TRANSACTION_RECORDING must be defined to +// enable transaction monitoring +//----------------------------------------------------------------------------- + +`timescale 1ps / 1ps + +module altera_avalon_st_monitor( + clk, + reset, + + sink_data, + sink_channel, + sink_valid, + sink_startofpacket, + sink_endofpacket, + sink_error, + sink_empty, + sink_ready, + + src_data, + src_channel, + src_valid, + src_startofpacket, + src_endofpacket, + src_error, + src_empty, + src_ready + ); + + // =head1 PARAMETERS + parameter ST_SYMBOL_W = 8; // number of bits in one symbols + parameter ST_NUMSYMBOLS = 4; // number of symbols in one data + parameter ST_CHANNEL_W = 0; // width of channel signal + parameter ST_ERROR_W = 0; // width of error signal + parameter ST_EMPTY_W = 0; // width of empty signal, ST_EMPTY_W = log2(`ST_NUMSYMBOLS) + + parameter ST_READY_LATENCY = 0; // fixed ready latency in cycles + parameter ST_MAX_CHANNELS = 1; // maximum number of channels + + parameter USE_PACKET = 0; // data transfer in packet format + parameter USE_CHANNEL = 0; // use channel port + parameter USE_ERROR = 0; // use error port + parameter USE_READY = 1; // use ready port + parameter USE_VALID = 1; // use valid port + parameter USE_EMPTY = 0; // use empty port + parameter ST_BEATSPERCYCLE = 1; // Max number of packets per cycle + + parameter ST_MAX_PACKET_SIZE = 1; // Max number of packet size covered + parameter VHDL_ID = 0; // VHDL BFM ID number + + localparam ST_DATA_W = ST_SYMBOL_W * ST_NUMSYMBOLS; + localparam ST_MDATA_W = ST_BEATSPERCYCLE * ST_DATA_W; + localparam ST_MCHANNEL_W = ST_BEATSPERCYCLE * ST_CHANNEL_W; + localparam ST_MERROR_W = ST_BEATSPERCYCLE * ST_ERROR_W; + localparam ST_MEMPTY_W = ST_BEATSPERCYCLE * ST_EMPTY_W; + + localparam TAP_W = ((ST_DATA_W == 0)? 1:ST_DATA_W) + // data + ((ST_CHANNEL_W == 0)? 1:ST_CHANNEL_W) + // channel + 1 + // valid + 1 + // startofpacket + 1 + // endofpacket + ((ST_ERROR_W == 0)? 1:ST_ERROR_W) + // error + ((ST_EMPTY_W == 0)? 1:ST_EMPTY_W) + // empty + 1; // ready + + localparam MTAP_W = ST_BEATSPERCYCLE*TAP_W; + + // =head1 PINS + // =head2 Clock Interface + input clk; + input reset; + + // =head2 Avalon Streaming Sink Interface + input [lindex(ST_MDATA_W) : 0] sink_data; + input [lindex(ST_MCHANNEL_W) : 0] sink_channel; + input [lindex(ST_BEATSPERCYCLE) : 0] sink_valid; + input [lindex(ST_BEATSPERCYCLE) : 0] sink_startofpacket; + input [lindex(ST_BEATSPERCYCLE) : 0] sink_endofpacket; + input [lindex(ST_MERROR_W) : 0] sink_error; + input [lindex(ST_MEMPTY_W) : 0] sink_empty; + output sink_ready; + + // =head2 Avalon Streaming Source Interface + output [lindex(ST_MDATA_W) : 0] src_data; + output [lindex(ST_MCHANNEL_W) : 0] src_channel; + output [lindex(ST_BEATSPERCYCLE) : 0] src_valid; + output [lindex(ST_BEATSPERCYCLE) : 0] src_startofpacket; + output [lindex(ST_BEATSPERCYCLE) : 0] src_endofpacket; + output [lindex(ST_MERROR_W) : 0] src_error; + output [lindex(ST_MEMPTY_W) : 0] src_empty; + input src_ready; + + // =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 + + // outputs + logic sink_ready; + logic [lindex(ST_MDATA_W) : 0] src_data; + logic [lindex(ST_MCHANNEL_W) : 0] src_channel; + logic [lindex(ST_BEATSPERCYCLE) : 0] src_valid; + logic [lindex(ST_BEATSPERCYCLE) : 0] src_startofpacket; + logic [lindex(ST_BEATSPERCYCLE) : 0] src_endofpacket; + logic [lindex(ST_MERROR_W) : 0] src_error; + logic [lindex(ST_MEMPTY_W) : 0] src_empty; + + logic [(MTAP_W)-ST_BEATSPERCYCLE : 0] tap; + + always @(*) begin + sink_ready <= src_ready; + src_data <= sink_data; + src_channel <= sink_channel; + src_valid <= sink_valid; + src_startofpacket <= sink_startofpacket; + src_endofpacket <= sink_endofpacket; + src_error <= sink_error; + src_empty <= sink_empty; + + tap <= { + sink_data, + sink_channel, + sink_valid, + sink_startofpacket, + sink_endofpacket, + sink_error, + sink_empty, + src_ready + }; + end + + //-------------------------------------------------------------------------- + // =head1 ALTERA_AVALON_ST_MONITOR_ASSERTION + // This module implements Avalon-ST protocol simulation assertion checkers + // =cut + //-------------------------------------------------------------------------- + altera_avalon_st_monitor_assertion + #( + .ST_SYMBOL_W (ST_SYMBOL_W), + .ST_NUMSYMBOLS (ST_NUMSYMBOLS), + .ST_CHANNEL_W (ST_CHANNEL_W), + .ST_ERROR_W (ST_ERROR_W), + .ST_EMPTY_W (ST_EMPTY_W), + + .ST_READY_LATENCY(ST_READY_LATENCY), + .ST_MAX_CHANNELS (ST_MAX_CHANNELS), + .ST_BEATSPERCYCLE(ST_BEATSPERCYCLE), + + .USE_PACKET (USE_PACKET), + .USE_CHANNEL (USE_CHANNEL), + .USE_ERROR (USE_ERROR), + .USE_READY (USE_READY), + .USE_VALID (USE_VALID), + .USE_EMPTY (USE_EMPTY) + ) + monitor_assertion ( + .clk (clk), + .reset (reset), + .tap (tap) + ); + + //-------------------------------------------------------------------------- + // =head1 ALTERA_AVALON_ST_MONITOR_COVERAGE + // This module implements Avalon-ST protocol functional coverage measurements + // =cut + //-------------------------------------------------------------------------- + altera_avalon_st_monitor_coverage + #( + .ST_SYMBOL_W (ST_SYMBOL_W), + .ST_NUMSYMBOLS (ST_NUMSYMBOLS), + .ST_CHANNEL_W (ST_CHANNEL_W), + .ST_ERROR_W (ST_ERROR_W), + .ST_EMPTY_W (ST_EMPTY_W), + .ST_BEATSPERCYCLE (ST_BEATSPERCYCLE), + + .ST_READY_LATENCY (ST_READY_LATENCY), + .ST_MAX_CHANNELS (ST_MAX_CHANNELS), + + .USE_PACKET (USE_PACKET), + .USE_CHANNEL (USE_CHANNEL), + .USE_ERROR (USE_ERROR), + .USE_READY (USE_READY), + .USE_VALID (USE_VALID), + .USE_EMPTY (USE_EMPTY), + .ST_MAX_PACKET_SIZE (ST_MAX_PACKET_SIZE) + ) + monitor_coverage ( + .clk (clk), + .reset (reset), + .tap (tap) + ); + + //-------------------------------------------------------------------------- + // =head1 ALTERA_AVALON_ST_MONITOR_TRANSACTIONS + // This module implements Avalon-ST the transaction recorder. + // =cut + //-------------------------------------------------------------------------- + + `ifdef ENABLE_ALTERA_AVALON_TRANSACTION_RECORDING + altera_avalon_st_monitor_transactions + #( + .ST_SYMBOL_W (ST_SYMBOL_W), + .ST_NUMSYMBOLS (ST_NUMSYMBOLS), + .ST_CHANNEL_W (ST_CHANNEL_W), + .ST_ERROR_W (ST_ERROR_W), + .ST_EMPTY_W (ST_EMPTY_W), + .ST_BEATSPERCYCLE (ST_BEATSPERCYCLE), + + .ST_READY_LATENCY (ST_READY_LATENCY), + .ST_MAX_CHANNELS (ST_MAX_CHANNELS), + + .USE_PACKET (USE_PACKET), + .USE_CHANNEL (USE_CHANNEL), + .USE_ERROR (USE_ERROR), + .USE_READY (USE_READY), + .USE_VALID (USE_VALID), + .USE_EMPTY (USE_EMPTY), + .ST_MAX_PACKET_SIZE (ST_MAX_PACKET_SIZE) + ) + monitor_trans ( + .clk (clk), + .reset (reset), + .tap (tap) + ); + `endif + + // synthesis translate_off + import verbosity_pkg::*; + + localparam VERSION = "17.1"; + + function automatic void hello(); + // introduction message to the console + string message; + $sformat(message, "%m: - Hello from altera_avalon_st_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); + $sformat(message, "%m: - $Revision: #1 $"); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - $Date: 2017/07/30 $"); + print(VERBOSITY_INFO, message); + print_divider(VERBOSITY_INFO); + endfunction + + initial begin + hello(); + end + + // synthesis translate_on + +endmodule Index: syn/ast_monitor/altera_avalon_st_monitor_171/sim/altera_avalon_st_monitor_assertion.sv =================================================================== --- syn/ast_monitor/altera_avalon_st_monitor_171/sim/altera_avalon_st_monitor_assertion.sv (nonexistent) +++ syn/ast_monitor/altera_avalon_st_monitor_171/sim/altera_avalon_st_monitor_assertion.sv (revision 35) @@ -0,0 +1,550 @@ +// (C) 2001-2017 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 from 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 FPGA IP 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/main/ip/sopc/components/verification/altera_avalon_st_monitor_bfm/altera_avalon_st_monitor_tap.sv $ +// $Revision: #7 $ +// $Date: 2009/04/16 $ +// $Author: pscheidt $ +//----------------------------------------------------------------------------- +// =head1 NAME +// altera_avalon_st_monitor_assertion +// =head1 SYNOPSIS +// Streaming Avalon Bus Protocol Checker +//----------------------------------------------------------------------------- +// =head1 DESCRIPTION +// This module implements Avalon ST protocol assertion checking for simulation. +//----------------------------------------------------------------------------- + +`timescale 1ns / 1ns + +module altera_avalon_st_monitor_assertion( + clk, + reset, + tap + ); + + // =head1 PARAMETERS + parameter ST_SYMBOL_W = 8; // number of bits in one symbols + parameter ST_NUMSYMBOLS = 4; // number of symbols in one data + parameter ST_CHANNEL_W = 0; // width of channel signal + parameter ST_ERROR_W = 0; // width of error signal + parameter ST_EMPTY_W = 0; // width of empty signal, ST_EMPTY_W = log2(`ST_NUMSYMBOLS) + + parameter ST_READY_LATENCY = 0; // fixed ready latency in cycles + parameter ST_MAX_CHANNELS = 1; // maximum number of channels + + parameter USE_PACKET = 0; // data transfer in packet format + parameter USE_CHANNEL = 0; // use channel port + parameter USE_ERROR = 0; // use error port + parameter USE_READY = 1; // use ready port + parameter USE_VALID = 1; // use valid port + parameter USE_EMPTY = 0; // use empty port + parameter ST_BEATSPERCYCLE = 1; // Max number of packets per cycle + + localparam ST_DATA_W = ST_SYMBOL_W * ST_NUMSYMBOLS; + localparam ST_MAX_EMPTY = 2**(ST_EMPTY_W) - 1; + localparam NUM_CHANNEL = ST_MAX_CHANNELS+1; + + localparam TAP_W = ((ST_DATA_W == 0)? 1:ST_DATA_W) + // data + ((ST_CHANNEL_W == 0)? 1:ST_CHANNEL_W) + // channel + 1 + // valid + 1 + // startofpacket + 1 + // endofpacket + ((ST_ERROR_W == 0)? 1:ST_ERROR_W) + // error + ((ST_EMPTY_W == 0)? 1:ST_EMPTY_W) + // empty + 1; // ready + + // =head1 PINS + // =head2 Clock Interface + input clk; + input reset; + + // =head2 Avalon Monitor Interface - will be defined as Streaming Sink + input [(TAP_W*ST_BEATSPERCYCLE)-ST_BEATSPERCYCLE: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::*; + + typedef bit [lindex(ST_DATA_W) :0] STData_t; + typedef bit [lindex(ST_CHANNEL_W) :0] STChannel_t; + typedef bit [lindex(ST_EMPTY_W) :0] STEmpty_t; + typedef bit [lindex(ST_ERROR_W) :0] STError_t; + + event signal_fatal_error; + + event event_a_valid_legal; + event event_a_empty_legal; + event event_a_no_data_outside_packet; + event event_a_non_missing_endofpacket; + event event_a_non_missing_startofpacket; + event event_a_less_than_max_channel; + + string fatal_message = "*unitialized*"; + string message = "*unitialized*"; + + bit enable_a_valid_legal = 1; + bit enable_a_empty_legal = 1; + bit enable_a_no_data_outside_packet = 1; + bit enable_a_non_missing_endofpacket = 1; + bit enable_a_non_missing_startofpacket = 1; + bit enable_a_less_than_max_channel = 1; + + //-------------------------------------------------------------------------- + // unpack Avalon bus interface tap into individual port signals + logic ready; + logic [lindex(ST_BEATSPERCYCLE):0][lindex(ST_DATA_W):0] data; + logic [lindex(ST_BEATSPERCYCLE):0][lindex(ST_CHANNEL_W):0] channel; + logic [lindex(ST_BEATSPERCYCLE):0] valid; + logic [lindex(ST_BEATSPERCYCLE):0] startofpacket; + logic [lindex(ST_BEATSPERCYCLE):0] endofpacket; + logic [lindex(ST_BEATSPERCYCLE):0][lindex(ST_ERROR_W):0] error; + logic [lindex(ST_BEATSPERCYCLE):0][lindex(ST_EMPTY_W):0] empty; + + always_comb begin + data <= tap[lindex(ST_DATA_W*ST_BEATSPERCYCLE)+lindex(ST_CHANNEL_W*ST_BEATSPERCYCLE)+ + lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+3*ST_BEATSPERCYCLE+4: + lindex(ST_CHANNEL_W*ST_BEATSPERCYCLE)+lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+3*ST_BEATSPERCYCLE+4]; + + channel <= (USE_CHANNEL == 1)? + tap[lindex(ST_CHANNEL_W*ST_BEATSPERCYCLE)+lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+ + lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+3*ST_BEATSPERCYCLE+3: + lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+3*ST_BEATSPERCYCLE+3] : 0; + + valid <= (USE_VALID == 1)? + tap[lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+3*ST_BEATSPERCYCLE+2: + lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+2*ST_BEATSPERCYCLE+3] : 1; + + startofpacket <= (USE_PACKET == 1)? + tap[lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+2*ST_BEATSPERCYCLE+2: + lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+ST_BEATSPERCYCLE+3] : 0; + + endofpacket <= (USE_PACKET == 1)? + tap[lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+ST_BEATSPERCYCLE+2: + lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+3] : 0; + + error <= (USE_ERROR == 1)? + tap[lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+2: + lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+2] : 0; + + empty <= (USE_EMPTY == 1)? tap[lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+1:1] : 0; + + ready <= (USE_READY == 1)? tap[0:0] : 1; + end + + //-------------------------------------------------------------------------- + // General Statistics Counters + //-------------------------------------------------------------------------- + + logic [31:0] clock_counter; + logic [31:0] sop_counter; + logic [31:0] eop_counter; + + logic sop_counter_reset = 0; + logic eop_counter_reset = 0; + logic [255:0] sop_channel_used = '0; + logic [255:0] eop_channel_used = '1; + logic [lindex(ST_BEATSPERCYCLE):0] sop_error_in_channel = '0; + logic [lindex(ST_BEATSPERCYCLE):0] eop_error_in_channel = '0; + logic [lindex(ST_BEATSPERCYCLE):0] data_outside_packet = '0; + + always @(posedge clk) begin + if (reset) + clock_counter <= 0; + else + clock_counter <= clock_counter + 1; + end + + always @(posedge clk) begin + if (reset) begin + sop_counter <= 0; + end else if (sop_counter_reset) begin + sop_counter_reset <= 0; + sop_counter <= 0; + end else begin + for (int i=0; i 0) || (USE_READY && (ST_READY_LATENCY == 0) && ready) || !USE_READY) begin + sop_counter <= (USE_PACKET && valid[i] && startofpacket[i]) ? sop_counter + 1 : sop_counter; + end + end + end + end + end + + always @(posedge clk) begin + if (reset) begin + eop_counter <= 0; + end else if (eop_counter_reset) begin + eop_counter_reset <= 0; + eop_counter <= 0; + end else begin + for (int i=0; i 0) || (USE_READY && (ST_READY_LATENCY == 0) && ready) || !USE_READY) begin + eop_counter <= (USE_PACKET && valid[i] && endofpacket[i]) ? eop_counter + 1 : eop_counter; + end + end + end + end + end + + //-------------------------------------------------------------------------- + // Private Methods + //-------------------------------------------------------------------------- + + //-------------------------------------------------------------------------- + // =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_valid_legal( // public + bit assert_enable + ); + // enable or disable a_valid_legal assertion + + enable_a_valid_legal = assert_enable; + endfunction + + function automatic void set_enable_a_empty_legal( // public + bit assert_enable + ); + // enable or disable a_empty_legal assertion + + enable_a_empty_legal = assert_enable; + endfunction + + function automatic void set_enable_a_no_data_outside_packet( // public + bit assert_enable + ); + // enable or disable a_no_data_outside_packet assertion + + enable_a_no_data_outside_packet = assert_enable; + endfunction + + function automatic void set_enable_a_non_missing_endofpacket( // public + bit assert_enable + ); + // enable or disable a_non_missing_endofpacket assertion + + enable_a_non_missing_endofpacket = assert_enable; + endfunction + + function automatic void set_enable_a_non_missing_startofpacket( // public + bit assert_enable + ); + // enable or disable a_non_missing_startofpacket assertion + + enable_a_non_missing_startofpacket = assert_enable; + endfunction + + function automatic void set_enable_a_less_than_max_channel( // public + bit assert_enable + ); + // enable or disable a_less_than_max_channel assertion + + enable_a_less_than_max_channel = assert_enable; + endfunction + // =cut + + function automatic logic [31:0] get_sop_counter(); + return sop_counter; + if (USE_PACKET == 0) begin + $sformat(message, "%m: No packet signals in this stream (USE_PACKET=0)."); + print(VERBOSITY_WARNING, message); + end + endfunction + + function automatic void reset_sop_counter(); + sop_counter_reset = 1'b1; + endfunction + + function automatic logic [31:0] get_eop_counter(); + return eop_counter; + if (USE_PACKET == 0) begin + $sformat(message, "%m: No packet signals in this stream (USE_PACKET=0)."); + print(VERBOSITY_WARNING, message); + end + endfunction + + function automatic void reset_eop_counter(); + eop_counter_reset = 1'b1; + endfunction + + // remaining API declarations will go here + //-------------------------------------------------------------------------- + event fatal_error; + + always @(fatal_error) begin + $sformat(message, "%m: Terminate simulation."); + print(VERBOSITY_FAILURE, message); + abort_simulation(); + end + + //-------------------------------------------------------------------------- + // =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 + //-------------------------------------------------------------------------- + + function automatic void print_assertion( + string message_in + ); + string message_out; + $sformat(message_out, "ASSERTION: %s", message_in); + print(VERBOSITY_FAILURE, message_out); + endfunction + + + // Counter for general assertion counters + always @(posedge clk) + begin + for (int i=0; i 0) || (USE_READY && (ST_READY_LATENCY == 0) && ready) || !USE_READY) begin + check_sop_eop_valid(i); + end + end else begin + data_outside_packet[i] = 0; + end + end + end + + always @(posedge clk) + begin + if (reset) begin + sop_channel_used = '0; + eop_channel_used = '1; + sop_error_in_channel = '0; + eop_error_in_channel = '0; + data_outside_packet = '0; + end + end + + task automatic check_sop_eop_valid(int current_beat); + if (startofpacket[current_beat]) begin + if (sop_channel_used[channel[current_beat]] == 1) + sop_error_in_channel[current_beat] = 1; + else begin + sop_channel_used[channel[current_beat]] = 1; + sop_error_in_channel[current_beat] = 0; + end + eop_channel_used[channel[current_beat]] = 0; + end + + if (endofpacket[current_beat]) begin + if (eop_channel_used[channel[current_beat]] == 1) + eop_error_in_channel[current_beat] = 1; + else begin + eop_channel_used[channel[current_beat]] = 1; + eop_error_in_channel[current_beat] = 0; + end + sop_channel_used[channel[current_beat]] = 0; + end + + if (!startofpacket[current_beat] && !endofpacket[current_beat]) begin + if (!sop_channel_used[channel[current_beat]]) begin + data_outside_packet[current_beat] = 1; + end else begin + data_outside_packet[current_beat] = 0; + end + end else begin + data_outside_packet[current_beat] = 0; + end + + endtask + + + // 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 Avalon Streaming Assertions + // The following are the assertions code focus on Streaming Source and Sink + // component checking + //------------------------------------------------------------------------------- + + //------------------------------------------------------------------------------------ + // =head3 p_valid_legal + // This property check if valid is not deasserted ST_READY_LATENCY cycle after ready + // is deasserted. + //------------------------------------------------------------------------------------ + property p_valid_legal(current_beat); + @(posedge clk && enable_a_valid_legal && USE_VALID && USE_READY && ST_READY_LATENCY > 0) + disable iff (reset) + !ready |-> ##ST_READY_LATENCY !valid[current_beat]; + endproperty + + genvar i; + for (i=0; i event_a_valid_legal; + print_assertion("valid asserted after ready deasserted"); + end + end + + //------------------------------------------------------------------------------------ + // =head3 p_empty_legal + // This property check if empty non zero while endofpacket is asserted or empty value + // larger or equal to ST_NUMSYMBOLS + //------------------------------------------------------------------------------------ + property p_empty_legal(current_beat); + @(posedge clk && enable_a_empty_legal && USE_EMPTY && USE_PACKET) + disable iff (reset) + valid[current_beat] && (empty[current_beat] > 0) && (clock_counter > 0) && + ((USE_READY && (ST_READY_LATENCY == 0) && ready) || + !USE_READY || (ST_READY_LATENCY > 0)) + |-> endofpacket[current_beat] && (empty[current_beat] < ST_NUMSYMBOLS); + endproperty + + for (i=0; i event_a_empty_legal; + print_assertion("illegal empty value"); + end + end + + //------------------------------------------------------------------------------------ + // =head3 p_no_data_outside_packet + // This property check if that valid is asserted outside the packet transfer + //------------------------------------------------------------------------------------ + property p_no_data_outside_packet(current_beat); + @(posedge clk && enable_a_no_data_outside_packet && USE_VALID && USE_PACKET) + disable iff (reset) + valid[current_beat] && !startofpacket[current_beat] && !endofpacket[current_beat] && + ((USE_READY && (ST_READY_LATENCY == 0) && ready) || + !USE_READY || (ST_READY_LATENCY > 0)) + |-> ##1 !data_outside_packet[current_beat]; + endproperty + + for (i=0; i event_a_no_data_outside_packet; + print_assertion("valid is asserted outside the packet transfer"); + end + end + + //------------------------------------------------------------------------------------ + // =head3 p_non_missing_endofpacket + // This property check if consecutive startofpacket without endofpacket occurs + //------------------------------------------------------------------------------------ + property p_non_missing_endofpacket(current_beat); + @(posedge clk && enable_a_non_missing_endofpacket && USE_PACKET) + disable iff (reset) + startofpacket[current_beat] && valid[current_beat] && + ((USE_READY && (ST_READY_LATENCY == 0) && ready) || + !USE_READY || (ST_READY_LATENCY > 0)) + |-> ##1 !sop_error_in_channel[current_beat]; + endproperty + + for (i=0; i event_a_non_missing_endofpacket; + print_assertion("consecutive startofpacket without endofpacket"); + end + end + + //------------------------------------------------------------------------------------ + // =head3 p_non_missing_startofpacket + // This property check if consecutive endofpacket without endofpacket occurs + //------------------------------------------------------------------------------------ + property p_non_missing_startofpacket(current_beat); + @(posedge clk && enable_a_non_missing_startofpacket && USE_PACKET) + disable iff (reset) + endofpacket[current_beat] && valid[current_beat] && !startofpacket[current_beat] && + ((USE_READY && (ST_READY_LATENCY == 0) && ready) || + !USE_READY || (ST_READY_LATENCY > 0)) + |-> ##1 !eop_error_in_channel[current_beat]; + endproperty + + for (i=0; i event_a_non_missing_startofpacket; + print_assertion("consecutive endofpacket without startofpacket"); + end + end + + //------------------------------------------------------------------------------------ + // =head3 p_less_than_max_channel + // This property checks if channel size is less than ST_MAX_CHANNELS + //------------------------------------------------------------------------------------ + property p_less_than_max_channel(current_beat); + @(posedge clk && enable_a_less_than_max_channel && USE_CHANNEL) + disable iff (reset) + valid[current_beat] && (channel[current_beat] > 0) && (clock_counter > 0) && + ((USE_READY && (ST_READY_LATENCY == 0) && ready) || + !USE_READY || (ST_READY_LATENCY > 0)) + |-> (channel[current_beat] <= ST_MAX_CHANNELS); + endproperty + + for (i=0; i event_a_less_than_max_channel; + print_assertion("channel size must be within ST_MAX_CHANNELS"); + end + end + + // =cut + + //-------------------------------------------------------------------------- + // ASSERTION CODE END + //-------------------------------------------------------------------------- + `endif + + // synthesis translate_on + +endmodule + + Index: syn/ast_monitor/altera_avalon_st_monitor_171/sim/altera_avalon_st_monitor_coverage.sv =================================================================== --- syn/ast_monitor/altera_avalon_st_monitor_171/sim/altera_avalon_st_monitor_coverage.sv (nonexistent) +++ syn/ast_monitor/altera_avalon_st_monitor_171/sim/altera_avalon_st_monitor_coverage.sv (revision 35) @@ -0,0 +1,1651 @@ +// (C) 2001-2017 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 from 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 FPGA IP 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/main/ip/sopc/components/verification/altera_avalon_st_monitor_bfm/altera_avalon_st_monitor_coverage.sv $ +// $Revision: #7 $ +// $Date: 2009/04/16 $ +// $Author: klong $ +//----------------------------------------------------------------------------- +// =head1 NAME +// altera_avalon_st_monitor_coverage +// =head1 SYNOPSIS +// Streaming Avalon Bus Protocol Checker +//----------------------------------------------------------------------------- +// =head1 DESCRIPTION +// This module implements Avalon ST protocol coverage processing for simulation. +//----------------------------------------------------------------------------- + +`timescale 1ns / 1ns + +module altera_avalon_st_monitor_coverage( + clk, + reset, + tap + ); + + // =head1 PARAMETERS + parameter ST_SYMBOL_W = 8; // number of bits in one symbols + parameter ST_NUMSYMBOLS = 4; // number of symbols in one data + parameter ST_CHANNEL_W = 0; // width of channel signal + parameter ST_ERROR_W = 0; // width of error signal + parameter ST_EMPTY_W = 0; // width of empty signal + + parameter ST_READY_LATENCY = 0; // fixed ready latency in cycles + parameter ST_MAX_CHANNELS = 1; // maximum number of channels + + parameter USE_PACKET = 0; // data transfer in packet format + parameter USE_CHANNEL = 0; // use channel port + parameter USE_ERROR = 0; // use error port + parameter USE_READY = 1; // use ready port + parameter USE_VALID = 1; // use valid port + parameter USE_EMPTY = 0; // use empty port + parameter ST_BEATSPERCYCLE = 1; // Max number of packets per cycle + + parameter ST_MAX_PACKET_SIZE = 1; // Max number of packet size covered + + localparam ST_DATA_W = ST_SYMBOL_W * ST_NUMSYMBOLS; + localparam ST_MAX_EMPTY = 2**(ST_EMPTY_W) - 1; + localparam NUM_CHANNEL = ST_MAX_CHANNELS+1; + + + localparam TAP_W = ((ST_DATA_W == 0)? 1:ST_DATA_W) + // data + ((ST_CHANNEL_W == 0)? 1:ST_CHANNEL_W) + // channel + 1 + // valid + 1 + // startofpacket + 1 + // endofpacket + ((ST_ERROR_W == 0)? 1:ST_ERROR_W) + // error + ((ST_EMPTY_W == 0)? 1:ST_EMPTY_W) + // empty + 1; // ready + + // =head1 PINS + // =head2 Clock Interface + input clk; + input reset; + + // =head2 Avalon Monitor Interface - will be defined as Streaming Sink + input [(TAP_W*ST_BEATSPERCYCLE)-ST_BEATSPERCYCLE: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::*; + + typedef bit [lindex(ST_DATA_W) :0] STData_t; + typedef bit [lindex(ST_CHANNEL_W) :0] STChannel_t; + typedef bit [lindex(ST_EMPTY_W) :0] STEmpty_t; + typedef bit [lindex(ST_ERROR_W) :0] STError_t; + + string message = "*unitialized*"; + + bit covergroup_settings_changed_flag = 0; + bit enable_c_packet_no_idles_no_back_pressure = 1; + bit enable_c_packet_with_idles = 1; + bit enable_c_packet_with_back_pressure = 1; + bit enable_c_channel_change_in_packet = 1; + bit enable_c_empty = 1; + bit enable_c_transfer = 1; + bit enable_c_error = 1; + bit enable_c_packet = 1; + bit enable_c_b2b_packet_different_channel = 1; + bit enable_c_b2b_packet_same_channel = 1; + bit enable_c_b2b_data_different_channel = 1; + bit enable_c_b2b_data_same_channel = 1; + bit enable_c_valid_non_ready = 1; + bit enable_c_non_valid_ready = 1; + bit enable_c_non_valid_non_ready = 1; + bit enable_c_transaction_after_reset = 1; + bit enable_c_packet_size = 1; + bit enable_c_multiple_packet_per_cycle = 1; + bit enable_c_single_packet_per_cycle = 1; + bit enable_c_idle_beat_between_packet = 1; + bit enable_c_all_idle_beats = 1; + bit enable_c_all_valid_beats = 1; + bit enable_c_partial_valid_beats = 1; + bit enable_c_b2b_packet_within_single_cycle = 1; + bit enable_c_b2b_packet_in_different_cycle = 1; + bit enable_c_error_in_middle_of_packet = 1; + + //-------------------------------------------------------------------------- + // unpack Avalon bus interface tap into individual port signals + logic ready; + logic [lindex(ST_BEATSPERCYCLE):0][lindex(ST_DATA_W):0] data; + logic [lindex(ST_BEATSPERCYCLE):0][lindex(ST_CHANNEL_W):0] channel; + logic [lindex(ST_BEATSPERCYCLE):0] valid; + logic [lindex(ST_BEATSPERCYCLE):0] startofpacket; + logic [lindex(ST_BEATSPERCYCLE):0] endofpacket; + logic [lindex(ST_BEATSPERCYCLE):0][lindex(ST_ERROR_W):0] error; + logic [lindex(ST_BEATSPERCYCLE):0][lindex(ST_EMPTY_W):0] empty; + + always_comb begin + data <= tap[lindex(ST_DATA_W*ST_BEATSPERCYCLE)+lindex(ST_CHANNEL_W*ST_BEATSPERCYCLE)+ + lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+3*ST_BEATSPERCYCLE+4: + lindex(ST_CHANNEL_W*ST_BEATSPERCYCLE)+lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+3*ST_BEATSPERCYCLE+4]; + + channel <= (USE_CHANNEL == 1)? + tap[lindex(ST_CHANNEL_W*ST_BEATSPERCYCLE)+lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+ + lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+3*ST_BEATSPERCYCLE+3: + lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+3*ST_BEATSPERCYCLE+3] : 0; + + valid <= (USE_VALID == 1)? + tap[lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+3*ST_BEATSPERCYCLE+2: + lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+2*ST_BEATSPERCYCLE+3] : + (reset == 1)? 'x: 1; + + startofpacket <= (USE_PACKET == 1)? + tap[lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+2*ST_BEATSPERCYCLE+2: + lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+ST_BEATSPERCYCLE+3] : 0; + + endofpacket <= (USE_PACKET == 1)? + tap[lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+ST_BEATSPERCYCLE+2: + lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+3] : 0; + + error <= (USE_ERROR == 1)? + tap[lindex(ST_ERROR_W*ST_BEATSPERCYCLE)+lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+2: + lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+2] : 0; + + empty <= (USE_EMPTY == 1)? tap[lindex(ST_EMPTY_W*ST_BEATSPERCYCLE)+1:1] : 0; + + ready <= (USE_READY == 1)? tap[0:0] : 1; + end + + //-------------------------------------------------------------------------- + // General Statistics Counters + //-------------------------------------------------------------------------- + + logic [31:0] clock_counter; + logic [31:0] sop_counter; + logic [31:0] eop_counter; + + logic sop_counter_reset = 0; + logic eop_counter_reset = 0; + + logic [lindex(NUM_CHANNEL):0] packet_no_idles_no_back_pressure_flag = '1; + logic [lindex(NUM_CHANNEL):0] packet_with_back_pressure_flag = 0; + logic [lindex(NUM_CHANNEL):0] channel_change_in_packet_flag = 0; + logic [lindex(NUM_CHANNEL):0] packet_with_idles_flag = 0; + logic [31:0] idles_between_b2b_packet_same_channel_counter = 0; + logic [31:0] idles_between_b2b_packet_different_channel_counter = 0; + logic [31:0] idles_between_b2b_data_same_channel_counter = 0; + logic [31:0] idles_between_b2b_data_different_channel_counter = 0; + logic [lindex(NUM_CHANNEL):0] current_packet = 0; + logic [lindex(ST_BEATSPERCYCLE):0][lindex(ST_CHANNEL_W):0] past_channel = 0; + logic [lindex(ST_BEATSPERCYCLE):0] past_endofpacket = 0; + logic idles_between_packet_same_channel_sampled = 0; + logic idles_between_packet_different_channel_sampled = 0; + logic non_valid_ready_sampled = 0; + logic non_valid_non_ready_sampled = 0; + logic [lindex(ST_BEATSPERCYCLE):0] current_beat = 0; + logic [lindex(ST_BEATSPERCYCLE):0] current_beat_2 = 0; + logic [31:0] error_bit_num = 0; + logic [31:0] changed_channel = 0; + logic transaction_after_reset = 0; + logic all_valid_beats_flag = 0; + logic all_invalid_beats_flag = 0; + logic partial_valid_beats_flag = 0; + logic [31:0] idles_between_b2b_packet_transaction_counter = 0; + logic [31:0] idles_between_packet_within_single_transaction_sampled = 0; + logic [31:0] packet_per_transaction = 0; + logic [lindex(NUM_CHANNEL):0][31:0] packet_size = 0; + logic [31:0] error_in_middle_of_packet = 0; + logic [31:0] idles_between_packet_in_different_transaction_sampled = 0; + logic [31:0] invalid_beat_between_packet = 0; + logic packet_per_transaction_flag = 0; + logic channel_change = 0; + logic reset_status = 0; + + always @(posedge clk) begin + if (reset) + clock_counter <= 0; + else + clock_counter <= clock_counter + 1; + end + + always @(posedge clk) begin + if (reset) begin + sop_counter <= 0; + end else if (sop_counter_reset) begin + sop_counter_reset <= 0; + sop_counter <= 0; + end else begin + sop_counter <= (USE_PACKET && valid && startofpacket) ? + sop_counter + 1 : + sop_counter; + end + end + + always @(posedge clk) begin + if (reset) begin + eop_counter <= 0; + end else if (eop_counter_reset) begin + eop_counter_reset <= 0; + eop_counter <= 0; + end else begin + eop_counter <= (USE_PACKET && valid && endofpacket) ? + eop_counter + 1 : eop_counter; + end + 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 + //-------------------------------------------------------------------------- + + // ST Coverage API + function automatic void set_enable_c_packet_no_idles_no_back_pressure( // public + bit cover_enable + ); + // enable or disable c_packet_no_idles_no_back_pressure cover group + + enable_c_packet_no_idles_no_back_pressure = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_packet_no_idles_no_back_pressure"); + endfunction + + function automatic void set_enable_c_packet_with_idles( // public + bit cover_enable + ); + // enable or disable c_packet_with_idles cover group + + enable_c_packet_with_idles = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_packet_with_idles"); + endfunction + + function automatic void set_enable_c_packet_with_back_pressure( // public + bit cover_enable + ); + // enable or disable c_packet_with_back_pressure cover group + + enable_c_packet_with_back_pressure = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_packet_with_back_pressure"); + endfunction + + function automatic void set_enable_c_channel_change_in_packet( // public + bit cover_enable + ); + // enable or disable c_channel_change_in_packet cover group + + enable_c_channel_change_in_packet = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_channel_change_in_packet"); + endfunction + + function automatic void set_enable_c_empty( // public + bit cover_enable + ); + // enable or disable c_empty cover group + + enable_c_empty = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_empty"); + endfunction + + function automatic void set_enable_c_transfer( // public + bit cover_enable + ); + // enable or disable c_transfer cover group + + enable_c_transfer = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_transfer"); + endfunction + + function automatic void set_enable_c_error( // public + bit cover_enable + ); + // enable or disable c_error cover group + + enable_c_error = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_error"); + endfunction + + function automatic void set_enable_c_packet( // public + bit cover_enable + ); + // enable or disable c_packet cover group + + enable_c_packet = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_packet"); + endfunction + + function automatic void set_enable_c_b2b_packet_different_channel( // public + bit cover_enable + ); + // enable or disable c_b2b_packet_different_channel cover group + + enable_c_b2b_packet_different_channel = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_b2b_packet_different_channel"); + endfunction + + function automatic void set_enable_c_b2b_packet_same_channel( // public + bit cover_enable + ); + // enable or disable c_b2b_packet_same_channel cover group + + enable_c_b2b_packet_same_channel = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_b2b_packet_same_channel"); + endfunction + + function automatic void set_enable_c_b2b_data_different_channel( // public + bit cover_enable + ); + // enable or disable c_b2b_data_different_channel cover group + + enable_c_b2b_data_different_channel = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_b2b_data_different_channel"); + endfunction + + function automatic void set_enable_c_b2b_data_same_channel( // public + bit cover_enable + ); + // enable or disable c_b2b_data_same_channel cover group + + enable_c_b2b_data_same_channel = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_b2b_data_same_channel"); + endfunction + + function automatic void set_enable_c_valid_non_ready( // public + bit cover_enable + ); + // enable or disable c_valid_non_ready cover group + + enable_c_valid_non_ready = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_valid_non_ready"); + endfunction + + function automatic void set_enable_c_non_valid_ready( // public + bit cover_enable + ); + // enable or disable c_non_valid_ready cover group + + enable_c_non_valid_ready = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_non_valid_ready"); + endfunction + + function automatic void set_enable_c_non_valid_non_ready( // public + bit cover_enable + ); + // enable or disable c_non_valid_non_ready cover group + + enable_c_non_valid_non_ready = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_non_valid_non_ready"); + endfunction + + function automatic void set_enable_c_transaction_after_reset( // public + bit cover_enable + ); + // enable or disable transaction_after_reset cover group + + enable_c_transaction_after_reset = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_transaction_after_reset"); + endfunction + + function automatic void set_enable_c_packet_size( // public + bit cover_enable + ); + // enable or disable c_packet_size cover group + + enable_c_packet_size = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_packet_size"); + endfunction + + function automatic void set_enable_c_multiple_packet_per_cycle( // public + bit cover_enable + ); + // enable or disable c_multiple_packet_per_cycle cover group + + enable_c_multiple_packet_per_cycle = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_multiple_packet_per_cycle"); + endfunction + + function automatic void set_enable_c_single_packet_per_cycle( // public + bit cover_enable + ); + // enable or disable c_single_packet_per_cycle cover group + + enable_c_single_packet_per_cycle = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_single_packet_per_cycle"); + endfunction + + function automatic void set_enable_c_idle_beat_between_packet( // public + bit cover_enable + ); + // enable or disable c_idle_beat_between_packet cover group + + enable_c_idle_beat_between_packet = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_idle_beat_between_packet"); + endfunction + + function automatic void set_enable_c_all_valid_beats( // public + bit cover_enable + ); + // enable or disable c_all_valid_beats cover group + + enable_c_all_valid_beats = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_all_valid_beats"); + endfunction + + function automatic void set_enable_c_all_idle_beats( // public + bit cover_enable + ); + // enable or disable c_all_idle_beats cover group + + enable_c_all_idle_beats = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_all_idle_beats"); + endfunction + + function automatic void set_enable_c_partial_valid_beats( // public + bit cover_enable + ); + // enable or disable c_partial_valid_beats cover group + + enable_c_partial_valid_beats = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_partial_valid_beats"); + endfunction + + function automatic void set_enable_c_b2b_packet_within_single_cycle( // public + bit cover_enable + ); + // enable or disable c_b2b_packet_within_single_cycle cover group + + enable_c_b2b_packet_within_single_cycle = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_b2b_packet_within_single_cycle"); + endfunction + + function automatic void set_enable_c_b2b_packet_in_different_transaction( // public + bit cover_enable + ); + // enable or disable c_b2b_packet_in_different_transaction cover group + + enable_c_b2b_packet_in_different_cycle = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_b2b_packet_in_different_cycle"); + endfunction + + function automatic void set_enable_c_error_in_middle_of_packet( // public + bit cover_enable + ); + // enable or disable c_error_in_middle_of_packet cover group + + enable_c_error_in_middle_of_packet = cover_enable; + coverage_settings_check(covergroup_settings_changed_flag, "c_error_in_middle_of_packet"); + endfunction + + // =cut + + function automatic logic [31:0] get_sop_counter(); + return sop_counter; + if (USE_PACKET == 0) begin + $sformat(message, "%m: No packet signals in this stream (USE_PACKET = 0)."); + print(VERBOSITY_WARNING, message); + end + endfunction + + function automatic void reset_sop_counter(); + sop_counter_reset = 1'b1; + endfunction + + function automatic logic [31:0] get_eop_counter(); + return eop_counter; + if (USE_PACKET == 0) begin + $sformat(message, "%m: No packet signals in this stream (USE_PACKET = 0)."); + print(VERBOSITY_WARNING, message); + end + endfunction + + function automatic void reset_eop_counter(); + eop_counter_reset = 1'b1; + endfunction + + function 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 + + `ifdef DISABLE_ALTERA_AVALON_SIM_SVA + // SVA coverage code is disabled when this macro is defined + `else + //-------------------------------------------------------------------------- + // COVERAGE CODE BEGIN + //-------------------------------------------------------------------------- + + function automatic void print_assertion( //private + string message_in + ); + string message_out; + $sformat(message_out, "ASSERTION: %s", message_in); + print(VERBOSITY_FAILURE, message_out); + endfunction + + function logic [1023:0] pow( //private + input int power_value + ); + // This method return the maximum supported value for the port width. + pow = (2**(power_value) - 1); + endfunction + + function automatic logic [31:0] count_ones ( //private + input logic [1023:0] value + ); + // This method return number of 1 bits + if (value == 0) + count_ones = 0; + else if (value == 'x) begin + count_ones = 'x; + end else begin + for( count_ones = 0; value!= 0; value = value >> 1 ) + count_ones += value & 1'b1; + end + endfunction + + function integer log2( //private + 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 + + task sample_non_valid_ready(); + fork + begin + repeat(ST_READY_LATENCY) begin + @(posedge clk); + end + non_valid_ready_sampled = 1; + end + join_none + endtask + + //-------------------------------------------------------------------------- + // =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 + //-------------------------------------------------------------------------- + + + always @(posedge clk) + begin + if (!reset) begin + for (int i=0; i 0) || (USE_READY && (ST_READY_LATENCY == 0) && ready) || !USE_READY) begin + + if (enable_c_transaction_after_reset && USE_VALID) begin + c_transaction_after_reset.sample(); + transaction_after_reset = 0; + end + + if (enable_c_transfer && USE_VALID && USE_READY) begin + c_transfer.sample(); + end + + if (enable_c_empty && USE_EMPTY) begin + c_empty.sample(); + end + + if (enable_c_error && USE_ERROR) begin + for (int j = 0; j < ST_ERROR_W; j++) begin + if (error[current_beat][j] == 1) begin + error_bit_num = j; + c_error.sample(); + end + end + end + + if (startofpacket[i]) begin + if (!endofpacket[i]) begin + current_packet[channel[i]] = 1; + end else begin + packet_size[channel[i]]++; + end + + if (error[i] > 0) begin + error_in_middle_of_packet = 1; + end else begin + error_in_middle_of_packet = 0; + end + + if (enable_c_error_in_middle_of_packet && USE_ERROR && USE_PACKET) begin + c_error_in_middle_of_packet.sample(); + error_in_middle_of_packet = 0; + end + + packet_no_idles_no_back_pressure_flag[channel[i]] = 1; + + //counter to determine time to sample signal + if (i == 0) begin + if (channel[i] != past_channel[ST_BEATSPERCYCLE-1]) begin + idles_between_packet_same_channel_sampled = 0; + if (past_endofpacket[ST_BEATSPERCYCLE-1] == 1) begin + idles_between_packet_different_channel_sampled = 1; + idles_between_packet_in_different_transaction_sampled = 1; + end else begin + idles_between_packet_different_channel_sampled = 0; + idles_between_packet_in_different_transaction_sampled = 0; + end + end else begin + idles_between_packet_different_channel_sampled = 0; + if (past_endofpacket[ST_BEATSPERCYCLE-1] == 1) begin + idles_between_packet_same_channel_sampled = 1; + idles_between_packet_in_different_transaction_sampled = 1; + end else begin + idles_between_packet_same_channel_sampled = 0; + idles_between_packet_in_different_transaction_sampled = 0; + end + end + idles_between_packet_within_single_transaction_sampled = 0; + end else begin + if (channel[i] != channel[i-1]) begin + idles_between_packet_same_channel_sampled = 0; + if (endofpacket[i-1] == 1) begin + idles_between_packet_different_channel_sampled = 1; + idles_between_packet_within_single_transaction_sampled = 1; + end else begin + idles_between_packet_different_channel_sampled = 0; + idles_between_packet_within_single_transaction_sampled = 0; + end + end else begin + idles_between_packet_different_channel_sampled = 0; + if (endofpacket[i-1] == 1) begin + idles_between_packet_same_channel_sampled = 1; + idles_between_packet_within_single_transaction_sampled = 1; + end else begin + idles_between_packet_same_channel_sampled = 0; + idles_between_packet_within_single_transaction_sampled = 0; + end + end + idles_between_packet_in_different_transaction_sampled = 0; + end + + if (enable_c_b2b_packet_different_channel && USE_CHANNEL && USE_PACKET && USE_VALID && (ST_MAX_CHANNELS > 0)) begin + if (idles_between_packet_different_channel_sampled) begin + c_b2b_packet_different_channel.sample(); + end + end + + if (enable_c_b2b_packet_same_channel && USE_PACKET && USE_VALID) begin + if (idles_between_packet_same_channel_sampled) begin + c_b2b_packet_same_channel.sample(); + end + end + + if (enable_c_b2b_packet_within_single_cycle && USE_PACKET && USE_VALID && (ST_BEATSPERCYCLE > 1)) begin + if (idles_between_packet_within_single_transaction_sampled) begin + c_b2b_packet_within_single_cycle.sample(); + end + end + + if (enable_c_b2b_packet_in_different_cycle && USE_PACKET && USE_VALID && (ST_BEATSPERCYCLE > 1)) begin + if (idles_between_packet_in_different_transaction_sampled) begin + c_b2b_packet_in_different_cycle.sample(); + end + end + + if ((count_ones(current_packet) == 1) || ((count_ones(current_packet) == 0) &&(endofpacket[i]))) begin + if (enable_c_idle_beat_between_packet && USE_VALID && USE_PACKET && (ST_BEATSPERCYCLE > 1)) begin + c_idle_beat_between_packet.sample(); + invalid_beat_between_packet = 0; + end + end + end + + for (int j = 0; j 0)) begin + c_channel_change_in_packet.sample(); + channel_change_in_packet_flag[channel[i]] = 0; + end + + if (enable_c_packet_with_back_pressure && USE_READY && USE_PACKET) begin + c_packet_with_back_pressure.sample(); + packet_with_back_pressure_flag[channel[i]] = 0; + end + + if (enable_c_packet_size && USE_PACKET) begin + c_packet_size.sample(); + packet_size[channel[i]] = 0; + end + + end + + if (i == 0) begin + if (channel[i] != past_channel[ST_BEATSPERCYCLE-1]) begin + if (((count_ones(current_packet) == 1) && !startofpacket[i]) || + (count_ones(current_packet) > 1)) begin + if(current_packet[past_channel[ST_BEATSPERCYCLE-1]] == 1) begin + channel_change_in_packet_flag[past_channel[ST_BEATSPERCYCLE-1]] = 1; + end + end + end + end else begin + if (channel[i] != channel[i-1]) begin + if (((count_ones(current_packet) == 1) && !startofpacket[i]) || + (count_ones(current_packet) > 1)) begin + if(current_packet[channel[i-1]] == 1) begin + channel_change_in_packet_flag[channel[i-1]] = 1; + end + end + end + end + + end else begin + if (count_ones(current_packet) == 0) begin + invalid_beat_between_packet = 1; + end + end + end else if (USE_VALID && (valid[i] == 0)) begin + if (count_ones(current_packet) == 0) begin + invalid_beat_between_packet = 1; + end + end + + //counter for idles transaction + if (!valid[i]) begin + for (int j = 0; j 0) || (USE_READY && (ST_READY_LATENCY == 0) && ready) || !USE_READY) begin + if (endofpacket[i]) begin + idles_between_b2b_packet_same_channel_counter = 0; + idles_between_b2b_packet_different_channel_counter = 0; + idles_between_b2b_packet_transaction_counter = 0; + end + end + + if ((!startofpacket[i] && !endofpacket[i]) || (USE_READY && (ST_READY_LATENCY == 0) && !ready)) begin + idles_between_b2b_packet_different_channel_counter++; + idles_between_b2b_packet_transaction_counter++; + end + end + + if (((USE_VALID && valid[i]) || !USE_VALID)) begin + if ((ST_READY_LATENCY > 0) || (USE_READY && (ST_READY_LATENCY == 0) && ready) || !USE_READY) begin + if (enable_c_b2b_data_different_channel && USE_CHANNEL && USE_VALID && (ST_MAX_CHANNELS > 0)) begin + c_b2b_data_different_channel.sample(); + idles_between_b2b_data_different_channel_counter = 0; + end + + if (enable_c_b2b_data_same_channel && USE_VALID) begin + c_b2b_data_same_channel.sample(); + idles_between_b2b_data_same_channel_counter = 0; + end + end + end + + if (!reset_status) + transaction_after_reset = 0; + end + + // counter to capture previous cycle signal value + for (int i=0; i 0) || (USE_READY && (ST_READY_LATENCY == 0) && ready) || !USE_READY) begin + past_endofpacket[i] <= endofpacket[i]; + for (int k = i; k < ST_BEATSPERCYCLE; k++) begin + past_channel[k] <= channel[k]; + end + end else + past_endofpacket[i] <= 0; + end else begin + past_endofpacket[i] <= 0; + end + end + reset_status = 0; + end + end + + always @(posedge clk) + begin + if (!reset) begin + if (ready) begin + if (ST_READY_LATENCY == 0) begin + non_valid_ready_sampled = 1; + end else begin + sample_non_valid_ready(); + end + end + + if (enable_c_valid_non_ready && USE_READY && USE_VALID && (ST_READY_LATENCY == 0)) begin + for (int i=0; i 1)) begin + if ((ST_READY_LATENCY > 0) || (USE_READY && (ST_READY_LATENCY == 0) && ready) || !USE_READY) begin + if (count_ones(valid) == ST_BEATSPERCYCLE) begin + all_valid_beats_flag = 1; + end else begin + all_valid_beats_flag = 0; + end + + if ((count_ones(valid) == 0) && (valid[0] == 0)) begin + all_invalid_beats_flag = 1; + end else begin + all_invalid_beats_flag = 0; + end + + if ((count_ones(valid) > 0) && (count_ones(valid) < ST_BEATSPERCYCLE)) begin + partial_valid_beats_flag = 1; + end else begin + partial_valid_beats_flag = 0; + end + + if (enable_c_all_valid_beats && USE_VALID && (ST_BEATSPERCYCLE > 1)) begin + c_all_valid_beats.sample(); + end + if (enable_c_all_idle_beats && USE_VALID && (ST_BEATSPERCYCLE > 1)) begin + c_all_idle_beats.sample(); + end + if (enable_c_partial_valid_beats && USE_VALID && (ST_BEATSPERCYCLE > 1)) begin + c_partial_valid_beats.sample(); + end + end + end + + if (USE_PACKET && (ST_BEATSPERCYCLE > 1)) begin + for (int i=0; i 0) || (USE_READY && (ST_READY_LATENCY == 0) && ready) || !USE_READY) begin + if (((USE_VALID && valid[i]) || !USE_VALID)) begin + if (i > 0) begin + for (int j = 0; j < i; j++) begin + if (valid[j] == 1) begin + packet_per_transaction_flag = 1; + end + if ((channel[i] != channel[j]) && valid[j]) begin + channel_change = 1; + end + end + if (channel_change && packet_per_transaction_flag) begin + packet_per_transaction++; + end else begin + if ((startofpacket[i]) && packet_per_transaction_flag) begin + packet_per_transaction++; + end + end + channel_change = 0; + end + end + + if (i == (ST_BEATSPERCYCLE-1)) begin + if (enable_c_multiple_packet_per_cycle && USE_PACKET && (ST_BEATSPERCYCLE > 1)) begin + c_multiple_packet_per_cycle.sample(); + end + + if (enable_c_single_packet_per_cycle && USE_PACKET && (ST_BEATSPERCYCLE > 1)) begin + if ((valid > 0)) begin + c_single_packet_per_cycle.sample(); + end + end + packet_per_transaction = 0; + end + end + end + packet_per_transaction_flag = 0; + end + end + end + + + always @(negedge reset) + begin + non_valid_non_ready_sampled = 1; + end + + //counter while reset + always @(posedge clk) + begin + if (reset) begin + non_valid_ready_sampled = 0; + non_valid_non_ready_sampled = 0; + packet_no_idles_no_back_pressure_flag = '1; + packet_with_back_pressure_flag = 0; + idles_between_b2b_packet_same_channel_counter = 0; + idles_between_b2b_packet_different_channel_counter = 0; + channel_change_in_packet_flag = 0; + packet_with_idles_flag = 0; + idles_between_packet_same_channel_sampled = 0; + idles_between_packet_different_channel_sampled = 0; + current_packet = 0; + idles_between_b2b_data_same_channel_counter = 0; + idles_between_b2b_data_different_channel_counter = 0; + past_channel = 0; + past_endofpacket = 0; + transaction_after_reset = 1; + current_beat = 0; + current_beat_2 = 0; + changed_channel = 0; + all_valid_beats_flag = 0; + all_invalid_beats_flag = 0; + partial_valid_beats_flag = 0; + idles_between_b2b_packet_transaction_counter = 0; + idles_between_packet_within_single_transaction_sampled = 0; + packet_per_transaction = 0; + packet_size = 0; + error_in_middle_of_packet = 0; + idles_between_packet_in_different_transaction_sampled = 0; + invalid_beat_between_packet = 0; + packet_per_transaction_flag = 0; + reset_status = 1; + channel_change = 0; + end + end + + // Flag for initial coverage settings + initial begin + #1 covergroup_settings_changed_flag = 1; + end + + //------------------------------------------------------------------------------- + // =head2 Streaming Coverages + // The following are the cover group code focus on ST Monitor component coverage + //------------------------------------------------------------------------------- + + //------------------------------------------------------------------------------- + // =head3 c_empty + // This cover group covers the different empty value + //------------------------------------------------------------------------------- + + covergroup cg_empty; + cp_empty: coverpoint empty[current_beat] + { + bins cg_empty_cp_empty [] = {[0:ST_MAX_EMPTY]}; + } + option.per_instance = 1; + endgroup + + cg_empty c_empty; + + initial begin + #1 if (enable_c_empty && USE_EMPTY) begin + c_empty = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_error + // This cover group covers the different error value + //------------------------------------------------------------------------------- + + covergroup cg_error; + cp_error: coverpoint error_bit_num + { + bins cg_error_cp_error [] = {[0:lindex(ST_ERROR_W)]}; + } + option.per_instance = 1; + endgroup + + cg_error c_error; + + initial begin + #1 if (enable_c_error && USE_ERROR) begin + c_error = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_transfer + // This cover group covers valid is asserted for different channel. + //------------------------------------------------------------------------------- + + covergroup cg_transfer; + cp_transfer: coverpoint (channel[current_beat]) + { + bins cg_transfer_cp_transfer [] = {[0:(USE_CHANNEL == 0? 0:lindex(NUM_CHANNEL))]}; + } + option.per_instance = 1; + endgroup + + cg_transfer c_transfer; + + initial begin + #1 if (enable_c_transfer && USE_VALID && USE_READY) begin + c_transfer = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_packet + // This cover group covers packet transfer for different channel. + //------------------------------------------------------------------------------- + + covergroup cg_packet; + cp_packet: coverpoint (channel[current_beat]) + { + bins cg_packet_cp_packet [] = {[0:(USE_CHANNEL == 0? 0:lindex(NUM_CHANNEL))]}; + } + option.per_instance = 1; + endgroup + + cg_packet c_packet; + + initial begin + #1 if (enable_c_packet && USE_PACKET) begin + c_packet = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_valid_non_ready + // This cover group covers valid is asserted while ready is deasserted. + //------------------------------------------------------------------------------- + + covergroup cg_valid_non_ready; + cp_valid_non_ready: coverpoint ready + { + bins cg_valid_non_ready_cp_valid_non_ready = {0}; + } + option.per_instance = 1; + endgroup + + cg_valid_non_ready c_valid_non_ready; + + initial begin + #1 if (enable_c_valid_non_ready && USE_READY + && USE_VALID && (ST_READY_LATENCY == 0)) begin + c_valid_non_ready = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_non_valid_ready + // This cover group covers valid is deasserted at the N+ST_READ_LATENCY + // clock cycle if ready is asserted at N clock cycle. + //------------------------------------------------------------------------------- + + covergroup cg_non_valid_ready; + cp_non_valid_ready: coverpoint valid[current_beat_2] + { + bins cg_non_valid_ready_cp_non_valid_ready = {0}; + } + option.per_instance = 1; + endgroup + + cg_non_valid_ready c_non_valid_ready; + + initial begin + #1 if (enable_c_non_valid_ready && USE_READY && USE_VALID) begin + c_non_valid_ready = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_non_valid_non_ready + // This cover group covers idle cycle. + //------------------------------------------------------------------------------- + + covergroup cg_non_valid_non_ready; + cp_non_valid_non_ready: coverpoint ready + { + bins cg_non_valid_non_ready_cp_non_valid_non_ready = {0}; + } + option.per_instance = 1; + endgroup + + cg_non_valid_non_ready c_non_valid_non_ready; + + initial begin + #1 if (enable_c_non_valid_non_ready && USE_READY && USE_VALID) begin + c_non_valid_non_ready = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_packet_no_idles_no_back_pressure + // This cover group covers packet transaction without back pressure and idle + // cycles. + //------------------------------------------------------------------------------- + + covergroup cg_packet_no_idles_no_back_pressure; + cp_packet_no_idles_no_back_pressure: coverpoint packet_no_idles_no_back_pressure_flag[channel[current_beat]] + { + bins cg_packet_no_idles_no_back_pressure_cp_packet_no_idles_no_back_pressure = {1}; + } + option.per_instance = 1; + endgroup + + cg_packet_no_idles_no_back_pressure c_packet_no_idles_no_back_pressure; + + initial begin + #1 if (enable_c_packet_no_idles_no_back_pressure && USE_READY && USE_VALID && USE_PACKET) begin + c_packet_no_idles_no_back_pressure = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_packet_with_back_pressure + // This cover group covers packet transaction being back pressured. + //------------------------------------------------------------------------------- + + covergroup cg_packet_with_back_pressure; + cp_packet_with_back_pressure: coverpoint packet_with_back_pressure_flag[channel[current_beat]] + { + bins cg_packet_with_back_pressure_cp_packet_with_back_pressure = {1}; + } + option.per_instance = 1; + endgroup + + cg_packet_with_back_pressure c_packet_with_back_pressure; + + initial begin + #1 if (enable_c_packet_with_back_pressure && USE_READY && USE_PACKET) begin + c_packet_with_back_pressure = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_packet_with_idles + // This cover group covers covers packet transaction with idle cycles + //------------------------------------------------------------------------------- + + covergroup cg_packet_with_idles; + cp_packet_with_idles: coverpoint packet_with_idles_flag[channel[current_beat]] + { + bins cg_packet_with_idles_cp_packet_with_idles = {1}; + } + option.per_instance = 1; + endgroup + + cg_packet_with_idles c_packet_with_idles; + + initial begin + #1 if (enable_c_packet_with_idles && USE_PACKET && USE_VALID) begin + c_packet_with_idles = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_channel_change_in_packet + // This cover group covers changing channel within a packet transaction. + //------------------------------------------------------------------------------- + + covergroup cg_channel_change_in_packet; + cp_channel_change_in_packet: coverpoint channel_change_in_packet_flag[channel[current_beat]] + { + bins cg_channel_change_in_packet_cp_channel_change_in_packet = {1}; + } + option.per_instance = 1; + endgroup + + cg_channel_change_in_packet c_channel_change_in_packet; + + initial begin + #1 if (enable_c_channel_change_in_packet && USE_CHANNEL && USE_PACKET && (ST_MAX_CHANNELS > 0)) begin + c_channel_change_in_packet = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_b2b_packet_different_channel + // This cover group covers back to back packet transfer for different channel. + //------------------------------------------------------------------------------- + + covergroup cg_b2b_packet_different_channel; + cp_b2b_packet_different_channel: coverpoint idles_between_b2b_packet_different_channel_counter + { + bins cg_b2b_packet_different_channel_cp_b2b_packet_different_channel = {0}; + } + option.per_instance = 1; + endgroup + + cg_b2b_packet_different_channel c_b2b_packet_different_channel; + + initial begin + #1 if (enable_c_b2b_packet_different_channel && USE_CHANNEL && USE_PACKET && USE_VALID && (ST_MAX_CHANNELS > 0)) begin + c_b2b_packet_different_channel = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_b2b_packet_same_channel + // This cover group covers back to back packet transfer for same channel. + //------------------------------------------------------------------------------- + + covergroup cg_b2b_packet_same_channel; + cp_b2b_packet_same_channel: coverpoint idles_between_b2b_packet_same_channel_counter + { + bins cg_b2b_packet_same_channel_cp_b2b_packet_same_channel = {0}; + } + option.per_instance = 1; + endgroup + + cg_b2b_packet_same_channel c_b2b_packet_same_channel; + + initial begin + #1 if (enable_c_b2b_packet_same_channel && USE_PACKET && USE_VALID) begin + c_b2b_packet_same_channel = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_b2b_data_different_channel + // This cover group covers back to back data transfer for different channel. + //------------------------------------------------------------------------------- + + covergroup cg_b2b_data_different_channel; + cp_b2b_data_different_channel: coverpoint idles_between_b2b_data_different_channel_counter + { + bins cg_b2b_data_different_channel_cp_b2b_data_different_channel = {0}; + } + option.per_instance = 1; + endgroup + + cg_b2b_data_different_channel c_b2b_data_different_channel; + + initial begin + #1 if (enable_c_b2b_data_different_channel && USE_CHANNEL && USE_VALID && (ST_MAX_CHANNELS > 0)) begin + c_b2b_data_different_channel = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_b2b_data_same_channel + // This cover group covers back to back data transfer for same channel. + //------------------------------------------------------------------------------- + + covergroup cg_b2b_data_same_channel; + cp_b2b_data_same_channel: coverpoint idles_between_b2b_data_same_channel_counter + { + bins cg_b2b_data_same_channel_cp_b2b_data_same_channel = {0}; + } + option.per_instance = 1; + endgroup + + cg_b2b_data_same_channel c_b2b_data_same_channel; + + initial begin + #1 if (enable_c_b2b_data_same_channel && USE_VALID) begin + c_b2b_data_same_channel = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_transaction_after_reset + // This cover group covers first transaction after reset. + //------------------------------------------------------------------------------- + + covergroup cg_transaction_after_reset; + cp_transaction_after_reset: coverpoint transaction_after_reset + { + bins cg_transaction_after_reset_cp_transaction_after_reset = {1}; + } + option.per_instance = 1; + endgroup + + cg_transaction_after_reset c_transaction_after_reset; + + initial begin + #1 if (enable_c_transaction_after_reset && USE_VALID) begin + c_transaction_after_reset = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_packet_size + // This covers different size of packet from one until parameter + // ST_MAX_PACKET_SIZE. For the transaction larger than ST_MAX_PACKET_SIZE will + // count into another bin. + //------------------------------------------------------------------------------- + + covergroup cg_packet_size; + cp_packet_size: coverpoint packet_size[channel[current_beat]] + { + bins cg_packet_size_cp_packet_size [] = {[1:(ST_MAX_PACKET_SIZE < 1)? 1:ST_MAX_PACKET_SIZE]}; + bins cg_packet_size_cp_packet_size_high = {[(ST_MAX_PACKET_SIZE < 1)? 2:ST_MAX_PACKET_SIZE+1:$]}; + } + option.per_instance = 1; + endgroup + + cg_packet_size c_packet_size; + + initial begin + #1 if (enable_c_packet_size && USE_PACKET) begin + c_packet_size = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_multiple_packet_per_cycle + // This cover group covers number of transactions that carry multiple packets + // per single cycle. + //------------------------------------------------------------------------------- + + covergroup cg_multiple_packet_per_cycle; + cp_multiple_packet_per_cycle: coverpoint packet_per_transaction + { + bins cg_multiple_packet_per_cycle_cp_multiple_packet_per_cycle = {[1:(ST_BEATSPERCYCLE > 1)?ST_BEATSPERCYCLE:1]}; + } + option.per_instance = 1; + endgroup + + cg_multiple_packet_per_cycle c_multiple_packet_per_cycle; + + initial begin + #1 if (enable_c_multiple_packet_per_cycle && USE_PACKET && ST_BEATSPERCYCLE > 1) begin + c_multiple_packet_per_cycle = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_single_packet_per_cycle + // This cover group covers number of transactions that carry one packet + // per single cycle. + //------------------------------------------------------------------------------- + + covergroup cg_single_packet_per_cycle; + cp_single_packet_per_cycle: coverpoint packet_per_transaction + { + bins cg_single_packet_per_cycle_cp_single_packet_per_cycle = {0}; + } + option.per_instance = 1; + endgroup + + cg_single_packet_per_cycle c_single_packet_per_cycle; + + initial begin + #1 if (enable_c_single_packet_per_cycle && USE_PACKET && ST_BEATSPERCYCLE > 1) begin + c_single_packet_per_cycle = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_idle_beat_between_packet + // This cover group covers packet transaction that owns idle beats in between. + //------------------------------------------------------------------------------- + + covergroup cg_idle_beat_between_packet; + cp_idle_beat_between_packet: coverpoint invalid_beat_between_packet + { + bins cg_idle_beat_between_packet_cp_idle_beat_between_packet = {1}; + } + option.per_instance = 1; + endgroup + + cg_idle_beat_between_packet c_idle_beat_between_packet; + + initial begin + #1 if (enable_c_idle_beat_between_packet && USE_PACKET && USE_VALID && (ST_BEATSPERCYCLE > 1)) begin + c_idle_beat_between_packet = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_all_valid_beats + // This cover group covers number of transaction with all beats are valid. + //------------------------------------------------------------------------------- + + covergroup cg_all_valid_beats; + cp_all_valid_beats: coverpoint all_valid_beats_flag + { + bins cg_all_valid_beats_cp_all_valid_beats = {1}; + } + option.per_instance = 1; + endgroup + + cg_all_valid_beats c_all_valid_beats; + + initial begin + #1 if (enable_c_all_valid_beats && USE_VALID && (ST_BEATSPERCYCLE > 1)) begin + c_all_valid_beats = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_all_idle_beats + // This cover group covers number of transaction with all beats are idle. + //------------------------------------------------------------------------------- + + covergroup cg_all_idle_beats; + cp_all_idle_beats: coverpoint all_invalid_beats_flag + { + bins cg_all_idle_beats_cp_all_idle_beats = {1}; + } + option.per_instance = 1; + endgroup + + cg_all_idle_beats c_all_idle_beats; + + initial begin + #1 if (enable_c_all_idle_beats && USE_VALID && (ST_BEATSPERCYCLE > 1)) begin + c_all_idle_beats = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_partial_valid_beats + // This cover group covers number of transaction with some beats are invalid and + // some beats are valid. + //------------------------------------------------------------------------------- + + covergroup cg_partial_valid_beats; + cp_partial_valid_beats: coverpoint partial_valid_beats_flag + { + bins cg_partial_valid_beats_cp_partial_valid_beats = {1}; + } + option.per_instance = 1; + endgroup + + cg_partial_valid_beats c_partial_valid_beats; + + initial begin + #1 if (enable_c_partial_valid_beats && USE_VALID && (ST_BEATSPERCYCLE > 1)) begin + c_partial_valid_beats = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_b2b_packet_within_single_cycle + // This cover group covers back to back packet transfer within single cycle. + //------------------------------------------------------------------------------- + + covergroup cg_b2b_packet_within_single_cycle; + cp_b2b_packet_within_single_cycle: coverpoint idles_between_b2b_packet_transaction_counter + { + bins cg_b2b_packet_within_single_cycle_cp_b2b_packet_within_single_cycle = {0}; + } + option.per_instance = 1; + endgroup + + cg_b2b_packet_within_single_cycle c_b2b_packet_within_single_cycle; + + initial begin + #1 if (enable_c_b2b_packet_within_single_cycle && USE_PACKET && USE_VALID && (ST_BEATSPERCYCLE > 1)) begin + c_b2b_packet_within_single_cycle = new(); + end + end + + + //------------------------------------------------------------------------------- + // =head3 c_b2b_packet_in_different_cycle + // This cover group covers back to back packet transfer in different cycle. + //------------------------------------------------------------------------------- + + covergroup cg_b2b_packet_in_different_cycle; + cp_b2b_packet_in_different_cycle: coverpoint idles_between_b2b_packet_transaction_counter + { + bins cg_b2b_packet_in_different_cycle_cp_b2b_packet_in_different_cycle = {0}; + } + option.per_instance = 1; + endgroup + + cg_b2b_packet_in_different_cycle c_b2b_packet_in_different_cycle; + + initial begin + #1 if (enable_c_b2b_packet_in_different_cycle && USE_PACKET && USE_VALID && (ST_BEATSPERCYCLE > 1)) begin + c_b2b_packet_in_different_cycle = new(); + end + end + + //------------------------------------------------------------------------------- + // =head3 c_error_in_middle_of_packet + // This cover group covers assert error in the middle of a packet. + //------------------------------------------------------------------------------- + + covergroup cg_error_in_middle_of_packet; + cp_error_in_middle_of_packet: coverpoint error_in_middle_of_packet + { + bins cg_error_in_middle_of_packet_cp_error_in_middle_of_packet = {1}; + } + option.per_instance = 1; + endgroup + + cg_error_in_middle_of_packet c_error_in_middle_of_packet; + + initial begin + #1 if (enable_c_error_in_middle_of_packet && USE_PACKET && USE_ERROR) begin + c_error_in_middle_of_packet = new(); + end + end + + // =cut + + //-------------------------------------------------------------------------- + // COVERAGE CODE END + //-------------------------------------------------------------------------- + `endif + // synthesis translate_on + +endmodule + + Index: syn/ast_monitor/altera_avalon_st_monitor_171/sim/altera_avalon_st_monitor_transactions.sv =================================================================== --- syn/ast_monitor/altera_avalon_st_monitor_171/sim/altera_avalon_st_monitor_transactions.sv (nonexistent) +++ syn/ast_monitor/altera_avalon_st_monitor_171/sim/altera_avalon_st_monitor_transactions.sv (revision 35) @@ -0,0 +1,404 @@ +// (C) 2001-2017 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 from 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 FPGA IP 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/17.1std/ip/sopc/components/verification/altera_avalon_st_monitor_bfm/altera_avalon_st_monitor_transactions.sv $ +// $Revision: #1 $ +// $Date: 2017/07/30 $ +// $Author: swbranch $ +//----------------------------------------------------------------------------- +// =head1 NAME +// altera_avalon_st_monitor_transactions +// =head1 SYNOPSIS +// Streaming Avalon Bus Protocol Checker +//----------------------------------------------------------------------------- +// =head1 DESCRIPTION +// This module implements Avalon ST protocol transaction recording. +//----------------------------------------------------------------------------- + +`timescale 1ns / 1ns + +module altera_avalon_st_monitor_transactions( + clk, + reset, + tap + ); + + // =head1 PARAMETERS + parameter ST_SYMBOL_W = 8; // number of bits in one symbols + parameter ST_NUMSYMBOLS = 4; // number of symbols in one data + parameter ST_CHANNEL_W = 0; // width of channel signal + parameter ST_ERROR_W = 0; // width of error signal + parameter ST_EMPTY_W = 0; // width of empty signal + + parameter ST_READY_LATENCY = 0; // fixed ready latency in cycles + parameter ST_MAX_CHANNELS = 1; // maximum number of channels + + parameter USE_PACKET = 0; // data transfer in packet format + parameter USE_CHANNEL = 0; // use channel port + parameter USE_ERROR = 0; // use error port + parameter USE_READY = 1; // use ready port + parameter USE_VALID = 1; // use valid port + parameter USE_EMPTY = 0; // use empty port + parameter ST_BEATSPERCYCLE = 1; // Max number of packets per cycle + + parameter ST_MAX_PACKET_SIZE = 1; // Max number of packet size covered + + localparam ST_DATA_W = ST_SYMBOL_W * ST_NUMSYMBOLS; + localparam ST_MDATA_W = ST_BEATSPERCYCLE * ST_DATA_W; + localparam ST_MCHANNEL_W = ST_BEATSPERCYCLE * ST_CHANNEL_W; + localparam ST_MERROR_W = ST_BEATSPERCYCLE * ST_ERROR_W; + localparam ST_MEMPTY_W = ST_BEATSPERCYCLE * ST_EMPTY_W; + + localparam ST_MAX_EMPTY = 2**(ST_EMPTY_W) - 1; + localparam NUM_CHANNEL = (ST_MAX_CHANNELS > 1)? ST_MAX_CHANNELS:1; + localparam FIFO_MAX_LEVEL = 100; + localparam FIFO_THRESHOLD = 50; + + localparam TAP_W = ((ST_DATA_W == 0)? 1:ST_DATA_W) + // data + ((ST_CHANNEL_W == 0)? 1:ST_CHANNEL_W) + // channel + 1 + // valid + 1 + // startofpacket + 1 + // endofpacket + ((ST_ERROR_W == 0)? 1:ST_ERROR_W) + // error + ((ST_EMPTY_W == 0)? 1:ST_EMPTY_W) + // empty + 1; // ready + + // =head1 PINS + // =head2 Clock Interface + input clk; + input reset; + + // =head2 Avalon Monitor Interface - will be defined as Streaming Sink + input [(TAP_W*ST_BEATSPERCYCLE)-ST_BEATSPERCYCLE: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::*; + + //-------------------------------------------------------------------------- + // Private Types and Variables + //-------------------------------------------------------------------------- + + typedef logic [lindex(ST_DATA_W) :0] STData_t; + typedef logic [lindex(ST_CHANNEL_W) :0] STChannel_t; + typedef logic [lindex(ST_EMPTY_W) :0] STEmpty_t; + typedef logic [lindex(ST_ERROR_W) :0] STError_t; + + typedef logic [lindex(ST_MDATA_W) :0] STMData_t; + typedef logic [lindex(ST_MCHANNEL_W) :0] STMChannel_t; + typedef logic [lindex(ST_MEMPTY_W) :0] STMEmpty_t; + typedef logic [lindex(ST_MERROR_W) :0] STMError_t; + typedef logic [ST_BEATSPERCYCLE-1 :0] STBeats_t; + + typedef struct packed + { + bit [31:0] idles; + logic startofpacket; + logic endofpacket; + STChannel_t channel; + STData_t data; + STError_t error; + STEmpty_t empty; + } Transaction_t; + + Transaction_t current_transaction[ST_BEATSPERCYCLE]; + Transaction_t query_transaction; + Transaction_t transaction_queue[$]; + + // unpack Avalon bus interface tap into individual port signals + logic [lindex(ST_MDATA_W): 0] sink_data; + logic [lindex(ST_MCHANNEL_W): 0] sink_channel; + logic [ST_BEATSPERCYCLE-1: 0] sink_valid; + logic [ST_BEATSPERCYCLE-1: 0] sink_startofpacket; + logic [ST_BEATSPERCYCLE-1: 0] sink_endofpacket; + logic [lindex(ST_MERROR_W): 0] sink_error; + logic [lindex(ST_MEMPTY_W): 0] sink_empty; + logic sink_ready; + + string message = "*uninitialized*"; + logic ready = 0; + int idle_ctr = 0; + int transaction_fifo_max = FIFO_MAX_LEVEL; + int transaction_fifo_threshold = FIFO_THRESHOLD; + + STBeats_t sink_valid_qualified; + logic sink_ready_qualified; + + localparam MAX_READY_DELAY = 8; + logic [MAX_READY_DELAY-1:0] sink_ready_delayed; + + //-------------------------------------------------------------------------- + // Private Functions + //-------------------------------------------------------------------------- + + function int __floor(int arg); + // returns the arg if it is greater than 0, else returns 0 + return (arg > 0) ? arg : 0; + endfunction + + //-------------------------------------------------------------------------- + // =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_received; //public + // Signal that a transaction has been received and queued. + + 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 = "17.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 + + function automatic void pop_transaction(); // public + // Pop the transaction descriptor from the queue so that it can be + // queried with the get_transaction methods by the test bench. + if (reset) begin + $sformat(message, "%m: Illegal command while reset asserted"); + print(VERBOSITY_ERROR, message); + ->signal_fatal_error; + end + + query_transaction = transaction_queue.pop_back(); + + $sformat(message, "%m: called pop_transaction"); + print(VERBOSITY_DEBUG, message); + $sformat(message, "%m: Data: %x", query_transaction.data); + print(VERBOSITY_DEBUG, message); + $sformat(message, "%m: Channel: %0d", query_transaction.channel); + print(VERBOSITY_DEBUG, message); + $sformat(message, "%m: SOP: %0d EOP: %0d", + query_transaction.startofpacket, + query_transaction.endofpacket); + print(VERBOSITY_DEBUG, message); + endfunction + + function automatic bit[31:0] get_transaction_idles(); // public + // Return the number of idle cycles in the transaction + $sformat(message, "%m: called get_transaction_idles"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.idles; + endfunction + + function automatic logic [ST_DATA_W-1:0] get_transaction_data(); // public + // Return the data in the transaction + $sformat(message, "%m: called get_transaction_data"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.data; + endfunction + + function automatic logic [ST_CHANNEL_W-1:0] get_transaction_channel(); // public + // Return the channel identifier in the transaction + $sformat(message, "%m: called get_transaction_channel"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.channel; + endfunction + + function automatic logic get_transaction_sop(); // public + // Return the start of packet status in the transaction + $sformat(message, "%m: called get_transaction_sop"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.startofpacket; + endfunction + + function automatic logic get_transaction_eop(); // public + // Return the end of packet status in the transaction + $sformat(message, "%m: called get_transaction_eop"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.endofpacket; + endfunction + + function automatic logic [ST_ERROR_W-1:0] get_transaction_error(); // public + // Return the error status in the transaction + $sformat(message, "%m: called get_transaction_error"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.error; + endfunction + + function automatic logic [ST_EMPTY_W-1:0] get_transaction_empty(); // public + // Return the number of empty symbols in the transaction + $sformat(message, "%m: called get_transaction_empty"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.empty; + endfunction + + function automatic int get_transaction_queue_size(); // public + // Return the length of the queue holding received transactions + $sformat(message, "%m: called get_transaction_queue_size"); + print(VERBOSITY_DEBUG, message); + + // Return the number of transactions in the internal queues. + return transaction_queue.size(); + endfunction + + // =cut + + //-------------------------------------------------------------------------- + // Local Machinery + //-------------------------------------------------------------------------- + always @(signal_fatal_error) abort_simulation(); + + always @(*) begin + { + sink_data, + sink_channel, + sink_valid, + sink_startofpacket, + sink_endofpacket, + sink_error, + sink_empty, + sink_ready + } <= tap; + end + + // delay chain for sink_ready back pressure output to account for latency + always @(posedge clk or posedge reset) begin + if (reset) begin + sink_ready_delayed <= 0; + end else begin + sink_ready_delayed <= {sink_ready_delayed[6:0], sink_ready}; + end + end + + always @(*) begin + if (USE_READY == 0) + sink_ready_qualified = 1'b1; + else begin + if (ST_READY_LATENCY == 0) + sink_ready_qualified = sink_ready; + else + sink_ready_qualified = sink_ready_delayed[__floor(ST_READY_LATENCY-1)]; + end + end + + always @(sink_valid) begin + if (USE_VALID > 0) + sink_valid_qualified = sink_valid; + else + sink_valid_qualified = '1; + end + + always @(posedge clk or posedge reset) begin + if (reset) begin + for (int i=0; i 0; clog2 = clog2 + 1) + i = i >> 1; + + return clog2; + endfunction + + function automatic int max( + bit [31:0] one, + bit [31:0] two + ); + if(one > two) + return one; + else + return two; + endfunction + + function automatic int lindex( + bit [31:0] width + ); + // 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 + lindex = (width > 0) ? (width-1) : 0; + endfunction + + typedef enum int { + LOW = 0, + HIGH = 1, + RANDOM = 2, + UNKNOWN = 3 + } IdleOutputValue_t; + +endpackage + +`endif + Index: syn/ast_monitor/altera_avalon_st_monitor_171/sim/verbosity_pkg.sv =================================================================== --- syn/ast_monitor/altera_avalon_st_monitor_171/sim/verbosity_pkg.sv (nonexistent) +++ syn/ast_monitor/altera_avalon_st_monitor_171/sim/verbosity_pkg.sv (revision 35) @@ -0,0 +1,193 @@ +// (C) 2001-2017 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 from 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 FPGA IP 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/17.1std/ip/sopc/components/verification/lib/verbosity_pkg.sv#1 $ +// $Revision: #1 $ +// $Date: 2017/07/30 $ +//----------------------------------------------------------------------------- +// =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 + Index: syn/ast_monitor.qsys =================================================================== --- syn/ast_monitor.qsys (nonexistent) +++ syn/ast_monitor.qsys (revision 35) @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: syn/ast_sink/altera_avalon_st_sink_bfm_171/sim/altera_avalon_st_sink_bfm.sv =================================================================== --- syn/ast_sink/altera_avalon_st_sink_bfm_171/sim/altera_avalon_st_sink_bfm.sv (nonexistent) +++ syn/ast_sink/altera_avalon_st_sink_bfm_171/sim/altera_avalon_st_sink_bfm.sv (revision 35) @@ -0,0 +1,463 @@ +// (C) 2001-2017 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 from 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 FPGA IP 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/17.1std/ip/sopc/components/verification/altera_avalon_st_sink_bfm/altera_avalon_st_sink_bfm.sv $ +// $Revision: #1 $ +// $Date: 2017/07/30 $ +// $Author: swbranch $ +//----------------------------------------------------------------------------- +// =head1 NAME +// altera_avalon_st_sink_bfm +// =head1 SYNOPSIS +// Bus Functional Model (BFM) for a Avalon Streaming Sink +//----------------------------------------------------------------------------- +// =head1 DESCRIPTION +// This is a Bus Functional Model (BFM) for a Avalon Streaming Sink. +// The behavior of each clock cycle of the ST protocol on the interface +// is governed by a transaction. Received bus cycles are captured as +// transactions and pushed into a response queue. Clients query received +// transactions by popping them off the queue one by one and extract +// information using the public API methods provided. Back pressure to +// a driving source is also applied using the API method set_ready. +//----------------------------------------------------------------------------- + +`timescale 1ps / 1ps + +module altera_avalon_st_sink_bfm( + clk, + reset, + + sink_data, + sink_channel, + sink_valid, + sink_startofpacket, + sink_endofpacket, + sink_error, + sink_empty, + sink_ready + ); + + // =head1 PARAMETERS + parameter ST_SYMBOL_W = 8; // Data symbol width in bits + parameter ST_NUMSYMBOLS = 4; // Number of symbols per word + parameter ST_CHANNEL_W = 0; // Channel width in bits + parameter ST_ERROR_W = 0; // Error width in bits + parameter ST_EMPTY_W = 0; // Empty width in bits + + parameter ST_READY_LATENCY = 0; // Number of cycles latency after ready (0 or 1 only) + parameter ST_MAX_CHANNELS = 1; // Maximum number of channels + + parameter USE_PACKET = 0; // Use packet pins on interface + parameter USE_CHANNEL = 0; // Use channel pins on interface + parameter USE_ERROR = 0; // Use error pin on interface + parameter USE_READY = 1; // Use ready pin on interface + parameter USE_VALID = 1; // Use valid pin on interface + parameter USE_EMPTY = 0; // Use empty pin on interface + + parameter ST_BEATSPERCYCLE = 1; // Max number of packets per cycle + parameter VHDL_ID = 0; // VHDL BFM ID number + + localparam ST_DATA_W = ST_SYMBOL_W * ST_NUMSYMBOLS; + localparam ST_MDATA_W = ST_BEATSPERCYCLE * ST_DATA_W; + localparam ST_MCHANNEL_W = ST_BEATSPERCYCLE * ST_CHANNEL_W; + localparam ST_MERROR_W = ST_BEATSPERCYCLE * ST_ERROR_W; + localparam ST_MEMPTY_W = ST_BEATSPERCYCLE * ST_EMPTY_W; + + // =head1 PINS + // =head2 Clock Interface + input clk; + input reset; + + // =head2 Avalon Streaming Source Interface + input [lindex(ST_MDATA_W): 0] sink_data; + input [lindex(ST_MCHANNEL_W): 0] sink_channel; + input [ST_BEATSPERCYCLE-1: 0] sink_valid; + input [ST_BEATSPERCYCLE-1: 0] sink_startofpacket; + input [ST_BEATSPERCYCLE-1: 0] sink_endofpacket; + input [lindex(ST_MERROR_W): 0] sink_error; + input [lindex(ST_MEMPTY_W): 0] sink_empty; + output sink_ready; + + // =cut + + function integer 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::*; + + logic sink_ready; + + //-------------------------------------------------------------------------- + // Private Types and Variables + //-------------------------------------------------------------------------- + + typedef logic [lindex(ST_DATA_W) :0] STData_t; + typedef logic [lindex(ST_CHANNEL_W) :0] STChannel_t; + typedef logic [lindex(ST_EMPTY_W) :0] STEmpty_t; + typedef logic [lindex(ST_ERROR_W) :0] STError_t; + + typedef logic [lindex(ST_MDATA_W) :0] STMData_t; + typedef logic [lindex(ST_MCHANNEL_W) :0] STMChannel_t; + typedef logic [lindex(ST_MEMPTY_W) :0] STMEmpty_t; + typedef logic [lindex(ST_MERROR_W) :0] STMError_t; + typedef logic [ST_BEATSPERCYCLE-1 :0] STBeats_t; + + typedef struct packed + { + bit [31:0] idles; + logic startofpacket; + logic endofpacket; + STChannel_t channel; + STData_t data; + STError_t error; + STEmpty_t empty; + } Transaction_t; + + Transaction_t current_transaction[ST_BEATSPERCYCLE]; + Transaction_t query_transaction; + + Transaction_t transaction_queue[$]; + + string message = "*uninitialized*"; + logic ready = 0; + int idle_ctr = 0; + + STBeats_t sink_valid_qualified; + logic sink_ready_qualified; + + localparam MAX_READY_DELAY = 8; + logic [MAX_READY_DELAY-1:0] sink_ready_delayed; + + + //-------------------------------------------------------------------------- + // =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 + // which instantiates and controls and queries state in this BFM 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 + //-------------------------------------------------------------------------- + + event signal_fatal_error; // public + // Signal that a fatal error has occurred. Terminates simulation. + + event signal_transaction_received; //public + // Signal that a transaction has been received and queued. + + event signal_sink_ready_assert; // public + // Signal that sink_ready is asserted thereby turning off back pressure. + + event signal_sink_ready_deassert; // public + // Signal that sink_ready is deasserted thereby turning on back pressure. + + function automatic string get_version(); // public + // Return BFM version string. For example, version 9.1 sp1 is "9.1sp1" + string ret_version = "__ACDS_VERSION_SHORT__"; + return ret_version; + endfunction + + task automatic init(); // public + // Drive interface to idle state. + $sformat(message, "%m: called init"); + print(VERBOSITY_DEBUG, message); + + drive_interface_idle(); + endtask + + task automatic set_ready( // public + bit state + ); + // Set the value of the interface ready signal. To assert back + // pressure, the state argument is set to 0 i.e. not ready. + // The parameter USE_READY must be set to 1 to enable this signal. + + if (USE_READY > 0) begin + $sformat(message, "%m: called set_ready"); + print(VERBOSITY_DEBUG, message); + + sink_ready <= state; + + if (state == 1'b1) + ->signal_sink_ready_assert; + else + ->signal_sink_ready_deassert; + end else begin + $sformat(message, "%m: Ignore set_ready() when USE_READY == 0"); + print(VERBOSITY_WARNING, message); + sink_ready <= 0; + end + endtask + + function automatic void pop_transaction(); // public + // Pop the transaction descriptor from the queue so that it can be + // queried with the get_transaction methods by the test bench. + if (reset) begin + $sformat(message, "%m: Illegal command while reset asserted"); + print(VERBOSITY_ERROR, message); + ->signal_fatal_error; + end + + query_transaction = transaction_queue.pop_back(); + + $sformat(message, "%m: called pop_transaction"); + print(VERBOSITY_DEBUG, message); + $sformat(message, "%m: Data: %x", query_transaction.data); + print(VERBOSITY_DEBUG, message); + $sformat(message, "%m: Channel: %0d", query_transaction.channel); + print(VERBOSITY_DEBUG, message); + $sformat(message, "%m: SOP: %0d EOP: %0d", + query_transaction.startofpacket, + query_transaction.endofpacket); + print(VERBOSITY_DEBUG, message); + endfunction + + function automatic bit[31:0] get_transaction_idles(); // public + // Return the number of idle cycles in the transaction + $sformat(message, "%m: called get_transaction_idles"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.idles; + endfunction + + function automatic logic [ST_DATA_W-1:0] get_transaction_data(); // public + // Return the data in the transaction + $sformat(message, "%m: called get_transaction_data"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.data; + endfunction + + function automatic logic [ST_CHANNEL_W-1:0] get_transaction_channel(); // public + // Return the channel identifier in the transaction + $sformat(message, "%m: called get_transaction_channel"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.channel; + endfunction + + function automatic logic get_transaction_sop(); // public + // Return the start of packet status in the transaction + $sformat(message, "%m: called get_transaction_sop"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.startofpacket; + endfunction + + function automatic logic get_transaction_eop(); // public + // Return the end of packet status in the transaction + $sformat(message, "%m: called get_transaction_eop"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.endofpacket; + endfunction + + function automatic logic [ST_ERROR_W-1:0] get_transaction_error(); // public + // Return the error status in the transaction + $sformat(message, "%m: called get_transaction_error"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.error; + endfunction + + function automatic logic [ST_EMPTY_W-1:0] get_transaction_empty(); // public + // Return the number of empty symbols in the transaction + $sformat(message, "%m: called get_transaction_empty"); + print(VERBOSITY_DEBUG, message); + + return query_transaction.empty; + endfunction + + function automatic int get_transaction_queue_size(); // public + // Return the length of the queue holding received transactions + $sformat(message, "%m: called get_transaction_queue_size"); + print(VERBOSITY_DEBUG, message); + + // Return the number of transactions in the internal queues. + return transaction_queue.size(); + endfunction + + // =cut + + //-------------------------------------------------------------------------- + // Private Methods + //-------------------------------------------------------------------------- + function int __floor( + int arg + ); + // returns the arg if it is greater than 0, else returns 0 + return (arg > 0) ? arg : 0; + endfunction + + task automatic drive_interface_idle(); + set_ready(0); + endtask + + function automatic void __hello(); + // Introduction Message to console + $sformat(message, "%m: - Hello from altera_avalon_st_sink_bfm."); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - $Revision: #1 $"); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - $Date: 2017/07/30 $"); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_SYMBOL_W = %0d", + ST_SYMBOL_W); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_NUMSYMBOLS = %0d", + ST_NUMSYMBOLS); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_CHANNEL_W = %0d", + ST_CHANNEL_W); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_ERROR_W = %0d", + ST_ERROR_W); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_EMPTY_W = %0d", + ST_EMPTY_W); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_READY_LATENCY = %0d", + ST_READY_LATENCY); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_MAX_CHANNELS = %0d", + ST_MAX_CHANNELS); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_BEATSPERCYCLE = %0d", + ST_BEATSPERCYCLE); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - USE_PACKET = %0d", + USE_PACKET); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - USE_CHANNEL = %0d", + USE_CHANNEL); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - USE_ERROR = %0d", + USE_ERROR); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - USE_READY = %0d", + USE_READY); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - USE_VALID = %0d", + USE_VALID); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - USE_EMPTY = %0d", + USE_EMPTY); + print(VERBOSITY_INFO, message); + print_divider(VERBOSITY_INFO); + endfunction + + //-------------------------------------------------------------------------- + initial begin + __hello(); + end + + //-------------------------------------------------------------------------- + // Local Machinery + //-------------------------------------------------------------------------- + always @(signal_fatal_error) abort_simulation(); + + // delay chain for sink_ready back pressure output to account for latency + always @(posedge clk or posedge reset) begin + if (reset) begin + sink_ready_delayed <= 0; + end else begin + sink_ready_delayed <= {sink_ready_delayed[6:0], sink_ready}; + end + end + + assign sink_ready_qualified = (USE_READY == 0)? 1'b1 : + (ST_READY_LATENCY == 0)? sink_ready : + sink_ready_delayed[__floor(ST_READY_LATENCY-1)]; + + assign sink_valid_qualified = (USE_VALID == 0)? 1'b1 : sink_valid; + + always @(posedge clk or posedge reset) begin + if (reset) begin + transaction_queue = {}; + query_transaction = 0; + for (int i=0; i 0; clog2 = clog2 + 1) + i = i >> 1; + + return clog2; + endfunction + + function automatic int max( + bit [31:0] one, + bit [31:0] two + ); + if(one > two) + return one; + else + return two; + endfunction + + function automatic int lindex( + bit [31:0] width + ); + // 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 + lindex = (width > 0) ? (width-1) : 0; + endfunction + + typedef enum int { + LOW = 0, + HIGH = 1, + RANDOM = 2, + UNKNOWN = 3 + } IdleOutputValue_t; + +endpackage + +`endif + Index: syn/ast_sink/altera_avalon_st_sink_bfm_171/sim/verbosity_pkg.sv =================================================================== --- syn/ast_sink/altera_avalon_st_sink_bfm_171/sim/verbosity_pkg.sv (nonexistent) +++ syn/ast_sink/altera_avalon_st_sink_bfm_171/sim/verbosity_pkg.sv (revision 35) @@ -0,0 +1,193 @@ +// (C) 2001-2017 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 from 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 FPGA IP 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/17.1std/ip/sopc/components/verification/lib/verbosity_pkg.sv#1 $ +// $Revision: #1 $ +// $Date: 2017/07/30 $ +//----------------------------------------------------------------------------- +// =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 + Index: syn/ast_sink.qsys =================================================================== --- syn/ast_sink.qsys (nonexistent) +++ syn/ast_sink.qsys (revision 35) @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: syn/ast_source/altera_avalon_st_source_bfm_171/sim/altera_avalon_st_source_bfm.sv =================================================================== --- syn/ast_source/altera_avalon_st_source_bfm_171/sim/altera_avalon_st_source_bfm.sv (nonexistent) +++ syn/ast_source/altera_avalon_st_source_bfm_171/sim/altera_avalon_st_source_bfm.sv (revision 35) @@ -0,0 +1,908 @@ +// (C) 2001-2017 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 from 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 FPGA IP 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/17.1std/ip/sopc/components/verification/altera_avalon_st_source_bfm/altera_avalon_st_source_bfm.sv $ +// $Revision: #1 $ +// $Date: 2017/07/30 $ +// $Author: swbranch $ +//----------------------------------------------------------------------------- +// =head1 NAME +// altera_avalon_st_source_bfm +// =head1 SYNOPSIS +// Bus Functional Model (BFM) for a Avalon Streaming Source +//----------------------------------------------------------------------------- +// =head1 DESCRIPTION +// This is a Bus Functional Model (BFM) for a Avalon Streaming Source. +// The behavior of each clock cycle of the ST protocol on the interface +// is governed by a transaction. Transactions are constructed using the +// the public API methods provided and are then pushed into a dispatch +// queue, either one at a time or as entire sequences. Response transactions +// are popped out of a separate response queue and inform the client of +// statistics such as back pressure latency. +//----------------------------------------------------------------------------- +`timescale 1ps / 1ps + +module altera_avalon_st_source_bfm ( + clk, + reset, + + src_data, + src_channel, + src_valid, + src_startofpacket, + src_endofpacket, + src_error, + src_empty, + src_ready + ); + + // =head1 PARAMETERS + parameter ST_SYMBOL_W = 8; // Data symbol width in bits + parameter ST_NUMSYMBOLS = 4; // Number of symbols per word + parameter ST_CHANNEL_W = 0; // Channel width in bits + parameter ST_ERROR_W = 0; // Error width in bits + parameter ST_EMPTY_W = 0; // Empty width in bits + + parameter ST_READY_LATENCY = 0; // Number of cycles latency after ready + parameter ST_MAX_CHANNELS = 1; // Maximum number of channels + + parameter USE_PACKET = 0; // Use packet pins on interface + parameter USE_CHANNEL = 0; // Use channel pins on interface + parameter USE_ERROR = 0; // Use error pin on interface + parameter USE_READY = 1; // Use ready pin on interface + parameter USE_VALID = 1; // Use valid pin on interface + parameter USE_EMPTY = 0; // Use empty pin on interface + + parameter ST_BEATSPERCYCLE = 1; // Max number of packets per cycle + parameter VHDL_ID = 0; // VHDL BFM ID number + + localparam ST_DATA_W = ST_SYMBOL_W * ST_NUMSYMBOLS; + localparam ST_MDATA_W = ST_BEATSPERCYCLE * ST_DATA_W; + localparam ST_MCHANNEL_W = ST_BEATSPERCYCLE * ST_CHANNEL_W; + localparam ST_MERROR_W = ST_BEATSPERCYCLE * ST_ERROR_W; + localparam ST_MEMPTY_W = ST_BEATSPERCYCLE * ST_EMPTY_W; + + // =head1 PINS + // =head2 Clock Interface + input clk; + input reset; + + // =head2 Avalon Streaming Source Interface + output [lindex(ST_MDATA_W): 0] src_data; + output [lindex(ST_MCHANNEL_W): 0] src_channel; + output [ST_BEATSPERCYCLE-1: 0] src_valid; + output [ST_BEATSPERCYCLE-1: 0] src_startofpacket; + output [ST_BEATSPERCYCLE-1: 0] src_endofpacket; + output [lindex(ST_MERROR_W): 0] src_error; + output [lindex(ST_MEMPTY_W): 0] src_empty; + input src_ready; + + // =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_utilities_pkg::*; + + typedef logic [lindex(ST_DATA_W) :0] STData_t; + typedef logic [lindex(ST_CHANNEL_W) :0] STChannel_t; + typedef logic [lindex(ST_EMPTY_W) :0] STEmpty_t; + typedef logic [lindex(ST_ERROR_W) :0] STError_t; + typedef logic [ST_BEATSPERCYCLE-1 :0] STBeats_t; + + logic [ST_BEATSPERCYCLE-1 :0] src_valid; + logic [lindex(ST_MDATA_W) :0] src_data; + logic [lindex(ST_MCHANNEL_W) :0] src_channel; + logic [lindex(ST_MERROR_W) :0] src_error; + logic [lindex(ST_MEMPTY_W) :0] src_empty; + logic [ST_BEATSPERCYCLE-1 :0] src_startofpacket; + logic [ST_BEATSPERCYCLE-1 :0] src_endofpacket; + + logic [ST_BEATSPERCYCLE-1 :0] src_valid_temp; + logic [lindex(ST_MDATA_W) :0] src_data_temp, src_data_slices; + logic [lindex(ST_MCHANNEL_W) :0] src_channel_temp, src_channel_slices; + logic [lindex(ST_MERROR_W) :0] src_error_temp, src_error_slices; + logic [lindex(ST_MEMPTY_W) :0] src_empty_temp, src_empty_slices; + logic [ST_BEATSPERCYCLE-1 :0] src_startofpacket_temp; + logic [ST_BEATSPERCYCLE-1 :0] src_endofpacket_temp; + + //-------------------------------------------------------------------------- + // Private Types and Variables + //-------------------------------------------------------------------------- + typedef struct packed + { + bit [31:0] idles; + logic startofpacket; + logic endofpacket; + STChannel_t channel; + STData_t data; + STError_t error; + STEmpty_t empty; + bit valid; + } Transaction_t; + + typedef struct packed + { + int latency; + int count; + } Response_t; + + Transaction_t new_transaction; + Transaction_t current_transaction[ST_BEATSPERCYCLE]; + Transaction_t transaction_queue[$]; + + Response_t current_response; + Response_t new_response; + Response_t response_queue[$]; + + int response_timeout = 100; + string message = ""; + + int idle_ctr = 0; + bit idle_state = 0; + int ready_latency_ctr = 0; + bit transaction_pending = 0; + int transaction_queue_size = 0; + int transaction_ctr = 0; + int max_transaction_queue_size = 256; + int min_transaction_queue_size = 2; + + bit start = 0; + bit complete = 0; + + logic src_ready_qualified; + logic src_is_now_ready; + logic load_transaction = 0; + STBeats_t src_valid_local; + + IdleOutputValue_t idle_output_config = UNKNOWN; + + localparam MAX_READY_DELAY = 8; + logic [MAX_READY_DELAY-1:0] src_ready_delayed; + + //-------------------------------------------------------------------------- + // Private Methods + //-------------------------------------------------------------------------- + function int __floor( + int arg + ); + // returns the arg if it is greater than 0, else returns 0 + return (arg > 0) ? arg : 0; + endfunction + + task __drive_temp_interface_idle(); + case (idle_output_config) + LOW: begin + src_valid_temp <= 0; + src_startofpacket_temp <= '0; + src_endofpacket_temp <= '0; + src_channel_temp <= '0; + src_data_temp <= '0; + src_error_temp <= '0; + src_empty_temp <= '0; + end + HIGH: begin + src_valid_temp <= 0; + src_startofpacket_temp <= '1; + src_endofpacket_temp <= '1; + src_channel_temp <= '1; + src_data_temp <= '1; + src_error_temp <= '1; + src_empty_temp <= '1; + end + RANDOM: begin + src_valid_temp <= 0; + src_startofpacket_temp <= $random; + src_endofpacket_temp <= $random; + src_channel_temp <= $random; + src_data_temp <= $random; + src_error_temp <= $random; + src_empty_temp <= $random; + end + UNKNOWN: begin + src_valid_temp <= 0; + src_startofpacket_temp <= 'x; + src_endofpacket_temp <= 'x; + src_channel_temp <= 'x; + src_data_temp <= 'x; + src_error_temp <= 'x; + src_empty_temp <= 'x; + end + default: begin + src_valid_temp <= 0; + src_startofpacket_temp <= 'x; + src_endofpacket_temp <= 'x; + src_channel_temp <= 'x; + src_data_temp <= 'x; + src_error_temp <= 'x; + src_empty_temp <= 'x; + end + endcase + endtask + + task __drive_interface_idle(); + case (idle_output_config) + LOW: begin + src_valid = '0; + src_startofpacket = '0; + src_endofpacket = '0; + src_data = '0; + src_channel = '0; + src_error = '0; + src_empty = '0; + end + HIGH: begin + src_valid = '0; + src_startofpacket = '1; + src_endofpacket = '1; + src_data = '1; + src_channel = '1; + src_error = '1; + src_empty = '1; + end + RANDOM: begin + src_valid = '0; + src_startofpacket = $random; + src_endofpacket = $random; + src_data = $random; + src_channel = $random; + src_error = $random; + src_empty = $random; + end + UNKNOWN: begin + src_valid = '0; + src_startofpacket = 'x; + src_endofpacket = 'x; + src_data = 'x; + src_channel = 'x; + src_error = 'x; + src_empty = 'x; + end + default: begin + src_valid = '0; + src_startofpacket = 'x; + src_endofpacket = 'x; + src_data = 'x; + src_channel = 'x; + src_error = 'x; + src_empty = 'x; + end + endcase + endtask + + function automatic void __hello(); + // Introduction Message to console + $sformat(message, "%m: - Hello from altera_avalon_st_source_bfm."); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - $Revision: #1 $"); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - $Date: 2017/07/30 $"); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_SYMBOL_W = %0d", + ST_SYMBOL_W); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_NUMSYMBOLS = %0d", + ST_NUMSYMBOLS); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_CHANNEL_W = %0d", + ST_CHANNEL_W); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_ERROR_W = %0d", + ST_ERROR_W); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_EMPTY_W = %0d", + ST_EMPTY_W); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_READY_LATENCY = %0d", + ST_READY_LATENCY); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_MAX_CHANNELS = %0d", + ST_MAX_CHANNELS); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - ST_BEATSPERCYCLE = %0d", + ST_BEATSPERCYCLE); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - USE_PACKET = %0d", + USE_PACKET); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - USE_CHANNEL = %0d", + USE_CHANNEL); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - USE_ERROR = %0d", + USE_ERROR); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - USE_READY = %0d", + USE_READY); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - USE_VALID = %0d", + USE_VALID); + print(VERBOSITY_INFO, message); + $sformat(message, "%m: - USE_EMPTY = %0d", + USE_EMPTY); + print(VERBOSITY_INFO, message); + print_divider(VERBOSITY_INFO); + endfunction + + //-------------------------------------------------------------------------- + // =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 + // which instantiates and controls and queries state in this BFM 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 local + // 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 + //-------------------------------------------------------------------------- + event signal_fatal_error; // public + // Signal that a fatal error has occurred. Terminates simulation. + + event signal_response_done; // public + // Signal + + event signal_src_ready; // public + // Signal the assertion of the src_ready port. + + event signal_src_not_ready; // public + // Signal the deassertion of the src_ready port implying sink backpressure + + event signal_src_transaction_complete; // public + // Signal that all pending transactions have completed + + event signal_src_transaction_almost_complete; // public + // Signal that BFM is driving the last pending transaction + + event signal_src_driving_transaction; // public + // Signal that the source is driving the transaction onto the bus + + event signal_max_transaction_queue_size; // public + // This event signals that the pending transaction queue size + // threshold has been exceeded + + event signal_min_transaction_queue_size; // public + // This event signals that the pending transaction queue size + // is below the minimum threshold + + function automatic string get_version(); // public + // Return BFM version string. For example, version 9.1 sp1 is "9.1sp1" + string ret_version = "17.1"; + return ret_version; + endfunction + + function automatic void set_idle_state_output_configuration( // public + // Set the configuration of output signal value during interface idle + IdleOutputValue_t output_config + ); + $sformat(message, "%m: method called"); + print(VERBOSITY_DEBUG, message); + + idle_output_config = output_config; + endfunction + + function automatic IdleOutputValue_t get_idle_state_output_configuration(); + // Get the configuration of output signal value during interface idle + $sformat(message, "%m: method called"); + print(VERBOSITY_DEBUG, message); + + return idle_output_config; + endfunction + + function automatic bit get_src_transaction_complete(); // public + // Return the transaction complete status + $sformat(message, "%m: called get_src_transaction_complete"); + print(VERBOSITY_DEBUG, message); + return complete; + endfunction + + function automatic logic get_src_ready(); // public + // Return the value of the src_ready port. + $sformat(message, "%m: called get_src_ready"); + print(VERBOSITY_DEBUG, message); + return src_ready; + endfunction + + function automatic void set_response_timeout( // public + int cycles = 100 + ); + // Set the number of cycles that may elapse during backpressure before + // the time out error is asserted. Disable the timeout by setting + // the cycles argument to zero. + response_timeout = cycles; + $sformat(message, "%m: called set_response_timeout"); + print(VERBOSITY_DEBUG, message); + + $sformat(message, "%m: Response timeout set to %0d cycles", response_timeout); + print(VERBOSITY_INFO, message); + endfunction + + task automatic init(); // public + // Drive interface to idle state. + $sformat(message, "%m: called init"); + print(VERBOSITY_DEBUG, message); + __drive_temp_interface_idle(); + endtask + + function automatic void push_transaction(); // public + // Push a new transaction into the local transaction queue. + // The BFM will drive the appropriate signals on the ST bus + // according to the transaction field values. + Transaction_t idle_transaction; + + $sformat(message, "%m: called push_transaction"); + print(VERBOSITY_DEBUG, message); + + if (reset) begin + $sformat(message, "%m: Illegal command while reset asserted"); + print(VERBOSITY_ERROR, message); + ->signal_fatal_error; + end + + // Idle cycles, defined as preceding the actual transaction are + // converted to an equal number of dummy transactions with the + // valid field set to 0. These are pushed into the queue before + // the actual transaction. + + if (USE_VALID == 1) begin + idle_transaction.idles = 0; + idle_transaction.valid = 1'b0; + for (int i=0; i 0) begin + $sformat(message, "%m: called set_transaction_idles - %h", + idle_cycles); + print(VERBOSITY_DEBUG, message); + new_transaction.idles = idle_cycles; + end else begin + $sformat(message, "%m: Ignored. Idles set to 0 when USE_VALID == 0"); + print(VERBOSITY_WARNING, message); + new_transaction.idles = 0; + end + endfunction + + function automatic void set_transaction_sop( // public + bit sop + ); + // Set the transaction start of packet value + $sformat(message, "%m: called set_transaction_sop - %b", sop); + print(VERBOSITY_DEBUG, message); + new_transaction.startofpacket = sop; + endfunction + + function automatic void set_transaction_eop( // public + bit eop + ); + // Set the transaction end of packet value + $sformat(message, "%m: called set_transaction_eop - %b", eop); + print(VERBOSITY_DEBUG, message); + new_transaction.endofpacket = eop; + endfunction + + function automatic void set_transaction_error( // public + bit [ST_ERROR_W-1:0] error + ); + // Set the transaction error value + $sformat(message, "%m: called set_transaction_error - %h", error); + print(VERBOSITY_DEBUG, message); + new_transaction.error = error; + endfunction + + function automatic void set_transaction_empty( // public + bit [ST_EMPTY_W-1:0] empty + ); + // Set the transaction empty value + $sformat(message, "%m: called set_transaction_empty - %h", empty); + print(VERBOSITY_DEBUG, message); + new_transaction.empty = empty; + endfunction + + function automatic void pop_response(); // public + // Pop the response transaction from the queue before querying contents + string message; + + $sformat(message, "%m: called pop_response - queue depth %0d", + response_queue.size()); + print(VERBOSITY_DEBUG, message); + + if (response_queue.size() == 0) begin + $sformat(message, "%m: Illegal command: response queue is empty"); + print(VERBOSITY_ERROR, message); + ->signal_fatal_error; + end + + current_response = response_queue.pop_front(); + endfunction + + function automatic int get_response_latency(); // public + // Return the response latency due to back pressure for a + // transaction. The value is in terms of clock cycles. + $sformat(message, "%m: called get_response_latency - %0d", + current_response.latency); + print(VERBOSITY_DEBUG, message); + return current_response.latency; + endfunction + + function automatic void set_max_transaction_queue_size( // public + int size + ); + // Set the pending transaction maximum queue size threshold. + // The public event signal_max_transaction_queue_size + // will fire when the threshold is exceeded. + max_transaction_queue_size = size; + endfunction + + function automatic void set_min_transaction_queue_size( // public + int size + ); + // Set the pending transaction minimum queue size threshold. + // The public event signal_min_transaction_queue_size + // will fire when the queue level is below this threshold. + min_transaction_queue_size = size; + endfunction + + //=cut + + initial begin + __hello(); + end + + always @(posedge clk) begin + if (transaction_queue.size() > max_transaction_queue_size) begin + ->signal_max_transaction_queue_size; + end else if (transaction_queue.size() < min_transaction_queue_size) begin + ->signal_min_transaction_queue_size; + end + end + + always @(signal_fatal_error) abort_simulation(); + + + // The ST_BEATSPERCYCLE parameter complicates the driving of transactions + // somewhat as not all beats in a given cycle need to be valid. + // The following scenarios are possible: + // Transactions with no idle cycles: + // 1 There are an integral multiple of ST_BEATSPERCYCLE transactions + // in the pending transaction queue: + // All transactions fit neatly into an integral number of cycles + // with all beats valid and no resulting bubbles. + // 2 There are a non integral multiple of ST_BEATSPERCYCLE transactions + // in the pending transaction queue: + // The final pending transaction(s) in the queue need to be driven + // out with unused beats being marked as invalid i.e. there are one + // or more bubbles (invalid beats) at the end of the transaction + // sequence. + // A transaction with idle cycles defined is decomposed into a sequence of + // transactions. First there is a sequence of non valid, empty transaction + // beats which define the idle cycles or bubbles. And finally, there is + // one valid transaction beat. + + // delay chain for src_ready back pressure input to account for latency + always @(posedge clk or posedge reset) begin + if (reset) begin + src_ready_delayed <= 0; + end else begin + src_ready_delayed <= {src_ready_delayed[6:0], src_ready}; + end + end + + assign src_ready_qualified = (USE_READY == 0)? 1'b1 : + (ST_READY_LATENCY == 0)? src_ready : + src_ready_delayed[__floor(ST_READY_LATENCY-1)]; + + assign src_is_now_ready = (USE_READY == 0)? 1'b1 : + (ST_READY_LATENCY <= 1)? src_ready : + src_ready_delayed[__floor(ST_READY_LATENCY-2)]; + + always @(*) begin + src_valid_local = src_valid_temp; + + if (USE_VALID > 0) begin + if (USE_READY == 0 || ST_READY_LATENCY == 0) begin + src_valid = src_valid_temp; + src_startofpacket = src_startofpacket_temp; + src_endofpacket = src_endofpacket_temp; + src_data = src_data_temp; + src_channel = src_channel_temp; + src_error = src_error_temp; + src_empty = src_empty_temp; + end else begin + if (src_ready_qualified) begin + src_valid = src_valid_temp; + src_startofpacket = src_startofpacket_temp; + src_endofpacket = src_endofpacket_temp; + src_data = src_data_temp; + src_channel = src_channel_temp; + src_error = src_error_temp; + src_empty = src_empty_temp; + end else begin + __drive_interface_idle(); + end + end + end else begin + src_valid = 0; + src_startofpacket = src_startofpacket_temp; + src_endofpacket = src_endofpacket_temp; + src_data = src_data_temp; + src_channel = src_channel_temp; + src_error = src_error_temp; + src_empty = src_empty_temp; + end + + end + + bit pending; + int response_transaction_ctr; + + always @(posedge clk or posedge reset) begin + if (reset) begin + ready_latency_ctr <= 0; + complete <= 0; + response_transaction_ctr = 0; + new_response = 0; + current_response = 0; + response_queue = {}; + end else begin + if (src_ready_qualified && ((src_valid != 0) || (USE_VALID == 0))) begin + ready_latency_ctr <= 0; + + if (transaction_pending) begin + new_response.count = response_transaction_ctr++; + new_response.latency = ready_latency_ctr; + response_queue.push_back(new_response); + ->signal_response_done; + end + + end else begin + if (transaction_pending && ((src_valid != 0) || (USE_VALID == 0))) + ready_latency_ctr <= ready_latency_ctr + 1; + end + + if ((get_transaction_queue_size() == 0) && src_ready_qualified && + (USE_READY == 0 || src_valid != 0)) begin + complete <= 1; + ->signal_src_transaction_complete; + end else if (complete && + ((get_transaction_queue_size() > 0) || transaction_pending)) begin + complete <= 0; + end + + if ((response_timeout != 0) && (ready_latency_ctr > response_timeout)) begin + $sformat(message, "%m: Response Timeout"); + print(VERBOSITY_FAILURE, message); + ->signal_fatal_error; + end + + end + end + + always @(posedge clk or posedge reset) begin + if (reset) begin + idle_ctr <= 0; + transaction_pending = 0; // keep blocking + + __drive_temp_interface_idle(); + + new_transaction = 0; + transaction_queue = {}; + for (int i=0; i 0 && src_ready_qualified == 1) begin + transaction_pending = 0; + end + + if (~transaction_pending && get_transaction_queue_size() > 0) begin + transaction_pending = 1; + load_transaction = 1; + + // initialize all beats to be invalid + for (int i=0; isignal_src_driving_transaction; + load_transaction = 0; + end else if (ST_READY_LATENCY > 0 && src_is_now_ready == 1) begin + ->signal_src_driving_transaction; + load_transaction = 0; + end + end + end + end + join_none + end else begin + idle_ctr = idle_ctr - 1; + end + end + + end + end + + always@(signal_src_driving_transaction) begin + if (get_transaction_queue_size() == 0) + -> signal_src_transaction_almost_complete; + end + + always @(posedge src_ready_qualified or negedge src_ready_qualified) begin + if (src_ready_qualified) + ->signal_src_ready; + else + ->signal_src_not_ready; + end +// synthesis translate_on + +endmodule + +// =head1 SEE ALSO +// avalon_st_sink_bfm +// =cut + + + + + + + + Index: syn/ast_source/altera_avalon_st_source_bfm_171/sim/avalon_utilities_pkg.sv =================================================================== --- syn/ast_source/altera_avalon_st_source_bfm_171/sim/avalon_utilities_pkg.sv (nonexistent) +++ syn/ast_source/altera_avalon_st_source_bfm_171/sim/avalon_utilities_pkg.sv (revision 35) @@ -0,0 +1,80 @@ +// (C) 2001-2017 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 from 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 FPGA IP 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/17.1std/ip/sopc/components/verification/lib/avalon_utilities_pkg.sv#1 $ +// $Revision: #1 $ +// $Date: 2017/07/30 $ +//----------------------------------------------------------------------------- +// =head1 NAME +// avalon_utilities_pkg +// =head1 SYNOPSIS +// Package for shared types and functions +//----------------------------------------------------------------------------- +// =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 types and functions. +// =cut +`timescale 1ns / 1ns + +`ifndef _AVALON_UTILITIES_PKG_ +`define _AVALON_UTILITIES_PKG_ + +package avalon_utilities_pkg; + + function automatic int clog2( + bit [31:0] Depth + ); + int i= Depth; + for(clog2 = 0; i > 0; clog2 = clog2 + 1) + i = i >> 1; + + return clog2; + endfunction + + function automatic int max( + bit [31:0] one, + bit [31:0] two + ); + if(one > two) + return one; + else + return two; + endfunction + + function automatic int lindex( + bit [31:0] width + ); + // 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 + lindex = (width > 0) ? (width-1) : 0; + endfunction + + typedef enum int { + LOW = 0, + HIGH = 1, + RANDOM = 2, + UNKNOWN = 3 + } IdleOutputValue_t; + +endpackage + +`endif + Index: syn/ast_source/altera_avalon_st_source_bfm_171/sim/verbosity_pkg.sv =================================================================== --- syn/ast_source/altera_avalon_st_source_bfm_171/sim/verbosity_pkg.sv (nonexistent) +++ syn/ast_source/altera_avalon_st_source_bfm_171/sim/verbosity_pkg.sv (revision 35) @@ -0,0 +1,193 @@ +// (C) 2001-2017 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 from 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 FPGA IP 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/17.1std/ip/sopc/components/verification/lib/verbosity_pkg.sv#1 $ +// $Revision: #1 $ +// $Date: 2017/07/30 $ +//----------------------------------------------------------------------------- +// =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 + Index: syn/ast_source.qsys =================================================================== --- syn/ast_source.qsys (nonexistent) +++ syn/ast_source.qsys (revision 35) @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

powered by: WebSVN 2.1.0

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