blob: 23e40b89d6ea663ca6f5234389bf02c64796c6f4 [file] [log] [blame] [edit]
/******************************************************************************
* (C) Copyright 2015 AMIQ Consulting
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* MODULE: amiq_apb_if.sv
* PROJECT: svaunit
* Description: AMBA APB interface
*******************************************************************************/
`ifndef AMIQ_APB_IF_SV
`define AMIQ_APB_IF_SV
`ifndef AMIQ_APB_MAX_DATA_WIDTH
//maximum data width
`define AMIQ_APB_MAX_DATA_WIDTH 32
`endif
`ifndef AMIQ_APB_MAX_ADDR_WIDTH
//maximum address width
`define AMIQ_APB_MAX_ADDR_WIDTH 32
`endif
//PPROT width
`define AMIQ_APB_PROT_WIDTH 3
`ifndef AMIQ_APB_MAX_STROBE_WIDTH
//maximum strobe width
`define AMIQ_APB_MAX_STROBE_WIDTH 4
`endif
`ifndef AMIQ_APB_MAX_SEL_WIDTH
//maximum sel width
`define AMIQ_APB_MAX_SEL_WIDTH 16
`endif
//AMBA APB interface
interface amiq_apb_if#(ready_low_max_time = 100) (input clk);
import uvm_pkg::*;
`include "uvm_macros.svh"
//reset signal
logic reset_n;
//Select signal
logic[`AMIQ_APB_MAX_SEL_WIDTH-1:0] sel;
//Address bus
logic[`AMIQ_APB_MAX_ADDR_WIDTH-1:0] addr;
//Direction signal
logic write;
//Write data bus
logic[`AMIQ_APB_MAX_DATA_WIDTH-1:0] wdata;
//Protection bus
logic[`AMIQ_APB_PROT_WIDTH-1:0] prot;
//Enable signal
logic enable;
//Write strobe bus
logic[`AMIQ_APB_MAX_STROBE_WIDTH:0] strb;
//Ready signal
logic ready;
//Read data bus
logic[`AMIQ_APB_MAX_DATA_WIDTH-1:0] rdata;
//Error signal
logic slverr;
//Switch which indicates that the agent uses error signal ( 1 - on; 0 - off)
bit has_error_signal = 1;
//-------------------------------------------------------------------------------------------
//--- SWITCHES TO ENABLE CHECKS
//--- They are initialized with 1 at start of simulation
//-------------------------------------------------------------------------------------------
//Switch to enable maximum number of clock cycles during when a signal can be kept low ( 1 - on; 0 - off)
bit en_ready_low_max_time = 1;
//Switch to enable reset checks ( 1 - on; 0 - off)
bit en_rst_checks = 1;
//Switch to enable X/Z checks ( 1 - on; 0 - off)
bit en_x_z_checks = 1;
//Switch to enable protocol checks ( 1 - on; 0 - off)
bit en_protocol_checks = 1;
//-------------------------------------------------------------------------------------------
//--- X/Z CHECKS
//--- Switch on/off by toggling en_x_z_checks field
//-------------------------------------------------------------------------------------------
//Property definition for sel signal valid values
property amiq_apb_sel_valid_values_p;
@(posedge clk) disable iff(!reset_n || !en_x_z_checks)
$isunknown(sel) == 0;
endproperty
//Check that sel signal is not x nor z
AMIQ_APB_ILLEGAL_SEL_VALUE_ERR: assert property (amiq_apb_sel_valid_values_p) else
`uvm_error("AMIQ_APB_ILLEGAL_SEL_VALUE_ERR",
$sformatf("[%0t] Found illegal sel value, %0b. sel should not be x nor z.",
$time, sel))
//Cover the amiq_apb_sel_valid_values_p property
AMIQ_APB_ILLEGAL_SEL_VALUE_CVR: cover property (amiq_apb_sel_valid_values_p);
//Property definition for addr signal valid values
property amiq_apb_addr_valid_values_p;
@(posedge clk) disable iff(!reset_n || !en_x_z_checks)
$isunknown(addr) == 0;
endproperty
//Check that addr signal is not x nor z
AMIQ_APB_ILLEGAL_ADDR_VALUE_ERR: assert property (amiq_apb_addr_valid_values_p) else
`uvm_error("AMIQ_APB_ILLEGAL_ADDR_VALUE_ERR",
$sformatf("[%0t] Found illegal addr value, %0b. addr should not be x nor z.",
$time, addr))
//Cover the amiq_apb_addr_valid_values_p property
AMIQ_APB_ILLEGAL_ADDR_VALUE_CVR: cover property (amiq_apb_addr_valid_values_p);
//Property definition for write signal valid values
property amiq_apb_write_valid_values_p;
@(posedge clk) disable iff(!reset_n || !en_x_z_checks)
$isunknown(write) == 0;
endproperty
//Check that write signal is not x nor z
AMIQ_APB_ILLEGAL_WRITE_VALUE_ERR: assert property (amiq_apb_write_valid_values_p) else
`uvm_error("AMIQ_APB_ILLEGAL_WRITE_VALUE_ERR",
$sformatf("[%0t] Found illegal write value, %0b. write should not be x nor z.",
$time, write))
//Cover the amiq_apb_write_valid_values_p property
AMIQ_APB_ILLEGAL_WRITE_VALUE_CVR: cover property (amiq_apb_write_valid_values_p);
//Property definition for prot signal valid values
property amiq_apb_prot_valid_values_p;
@(posedge clk) disable iff(!reset_n || !en_x_z_checks)
$isunknown(prot) == 0;
endproperty
//Check that prot signal is not x nor z
AMIQ_APB_ILLEGAL_PROT_VALUE_ERR: assert property (amiq_apb_prot_valid_values_p) else
`uvm_error("AMIQ_APB_ILLEGAL_PROT_VALUE_ERR",
$sformatf("[%0t] Found illegal prot value, %0b. prot should not be x nor z.",
$time, prot))
//Cover the amiq_apb_prot_valid_values_p property
AMIQ_APB_ILLEGAL_PROT_VALUE_CVR: cover property (amiq_apb_prot_valid_values_p);
//Property definition for enable signal valid values
property amiq_apb_enable_valid_values_p;
@(posedge clk) disable iff(!reset_n || !en_x_z_checks)
$isunknown(enable) == 0;
endproperty
//Check that enable signal is not x nor z
AMIQ_APB_ILLEGAL_ENABLE_VALUE_ERR: assert property (amiq_apb_enable_valid_values_p) else
`uvm_error("AMIQ_APB_ILLEGAL_ENABLE_VALUE_ERR",
$sformatf("[%0t] Found illegal enable value, %0b. enable should not be x nor z.",
$time, enable))
//Cover the amiq_apb_enable_valid_values_p property
AMIQ_APB_ILLEGAL_ENABLE_VALUE_CVR: cover property (amiq_apb_enable_valid_values_p);
//Property definition for strb signal valid values
property amiq_apb_strb_valid_values_p;
@(posedge clk) disable iff(!reset_n || !en_x_z_checks)
$isunknown(strb) == 0;
endproperty
//Check that strb signal is not x nor z
AMIQ_APB_ILLEGAL_STRB_VALUE_ERR: assert property (amiq_apb_strb_valid_values_p) else
`uvm_error("AMIQ_APB_ILLEGAL_STRB_VALUE_ERR",
$sformatf("[%0t] Found illegal strb value, %0b. strb should not be x nor z.",
$time, strb))
//Cover the amiq_apb_strb_valid_values_p property
AMIQ_APB_ILLEGAL_STRB_VALUE_CVR: cover property (amiq_apb_strb_valid_values_p);
//Property definition for ready signal valid values
property amiq_apb_ready_valid_values_p;
@(posedge clk) disable iff(!reset_n || !en_x_z_checks)
$isunknown(ready) == 0;
endproperty
//Check that ready signal is not x nor z
AMIQ_APB_ILLEGAL_READY_VALUE_ERR: assert property (amiq_apb_ready_valid_values_p) else
`uvm_error("AMIQ_APB_ILLEGAL_READY_VALUE_ERR",
$sformatf("[%0t] Found illegal ready value, %0b. ready should not be x nor z.",
$time, ready))
//Cover the amiq_apb_ready_valid_values_p property
AMIQ_APB_ILLEGAL_READY_VALUE_CVR: cover property (amiq_apb_ready_valid_values_p);
//Property definition for slverr signal valid values
property amiq_apb_slverr_valid_values_p;
@(posedge clk) disable iff(!reset_n || !en_x_z_checks)
$isunknown(slverr) == 0;
endproperty
//Check that slverr signal is not x nor z
AMIQ_APB_ILLEGAL_SLVERR_VALUE_ERR: assert property (amiq_apb_slverr_valid_values_p) else
`uvm_error("AMIQ_APB_ILLEGAL_SLVERR_VALUE_ERR",
$sformatf("[%0t] Found illegal slverr value, %0b. slverr should not be x nor z.",
$time, slverr))
//Cover the amiq_apb_slverr_valid_values_p property
AMIQ_APB_ILLEGAL_SLVERR_VALUE_CVR: cover property (amiq_apb_slverr_valid_values_p);
//-------------------------------------------------------------------------------------------
//--- POST RESET CHECKS
//--- Switch on/off by toggling en_rst_checks field
//-------------------------------------------------------------------------------------------
//Property definition for sel signal valid value post reset
property amiq_apb_sel_post_reset_p;
@(posedge clk) disable iff(!en_rst_checks)
$rose(reset_n) |-> $past(sel) == 0;
endproperty
//Check that after reset sel is LOW
AMIQ_APB_ILLEGAL_SEL_VALUE_POST_RESET_ERR: assert property (amiq_apb_sel_post_reset_p) else
`uvm_error("AMIQ_APB_ILLEGAL_SEL_VALUE_POST_RESET_ERR",
$sformatf("[%0t] Found illegal sel value, %0b after reset.",
$time, sel))
//Cover the amiq_apb_sel_post_reset_p property
AMIQ_APB_ILLEGAL_SEL_VALUE_POST_RESET_CVR: cover property (amiq_apb_sel_post_reset_p);
//Property definition for enable signal valid value post reset
property amiq_apb_enable_post_reset_p;
@(posedge clk) disable iff(!en_rst_checks)
$rose(reset_n) |-> $past(enable) == 0;
endproperty
//Check that after reset enable is LOW
AMIQ_APB_ILLEGAL_ENABLE_VALUE_POST_RESET_ERR: assert property (amiq_apb_enable_post_reset_p) else
`uvm_error("AMIQ_APB_ILLEGAL_ENABLE_VALUE_POST_RESET_ERR",
$sformatf("[%0t] Found illegal enable value, %0b after reset.",
$time, enable))
//Cover the amiq_apb_enable_post_reset_p property
AMIQ_APB_ILLEGAL_ENABLE_VALUE_POST_RESET_CVR: cover property (amiq_apb_enable_post_reset_p);
//Property definition for slverr signal valid value post reset
property amiq_apb_slverr_post_reset_p;
@(posedge clk) disable iff(!en_rst_checks)
$rose(reset_n) |-> $past(slverr) == 0;
endproperty
//Check that after reset slverr is LOW
AMIQ_APB_ILLEGAL_SLVERR_VALUE_POST_RESET_ERR: assert property (amiq_apb_slverr_post_reset_p) else
`uvm_error("AMIQ_APB_ILLEGAL_SLVERR_VALUE_POST_RESET_ERR",
$sformatf("[%0t] Found illegal slverr value, %0b after reset.",
$time, slverr))
//Cover the amiq_apb_slverr_post_reset_p property
AMIQ_APB_ILLEGAL_SLVERR_VALUE_POST_RESET_CVR: cover property (amiq_apb_slverr_post_reset_p);
//-------------------------------------------------------------------------------------------
//--- PROTOCOL CHECKS
//--- Switch on/off by toggling en_protocol_checks field
//-------------------------------------------------------------------------------------------
//{{{ Specific checks for sel signal
//Property definition for sel signal valid value when enable is asserted
property amiq_apb_sel_validity_during_transfer_phases_p;
@(posedge enable) disable iff(!reset_n || !en_protocol_checks) (|sel);
endproperty
//Check that sel is HIGH when enable is asserted
AMIQ_APB_ILLEGAL_SEL_TRANSITION_TR_PHASES_ERR: assert property (amiq_apb_sel_validity_during_transfer_phases_p) else
`uvm_error("AMIQ_APB_ILLEGAL_SEL_TRANSITION_TR_PHASES_ERR",
$sformatf("[%0t] sel must be stable during setup-access transitions.",
$time))
//Cover the amiq_apb_sel_validity_during_transfer_phases_p property
AMIQ_APB_ILLEGAL_SEL_TRANSITION_TR_PHASES_CVR: cover property (amiq_apb_sel_validity_during_transfer_phases_p);
//Property definition for sel signal valid value
property amiq_apb_sel_legal_values_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks) $onehot0(sel);
endproperty
//Check that sel has legal values
AMIQ_APB_ILLEGAL_SEL_LEGAL_VALUES_ERR: assert property (amiq_apb_sel_legal_values_p) else
`uvm_error("AMIQ_APB_ILLEGAL_SEL_LEGAL_VALUES_ERR",
$sformatf("[%0t] sel has not legal value.",
$time))
//Cover the amiq_apb_sel_legal_values_p property
AMIQ_APB_ILLEGAL_SEL_LEGAL_VALUES_CVR: cover property (amiq_apb_sel_legal_values_p);
//Property definition for sel signal stability during a transfer
property amiq_apb_sel_stability_during_transfer_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
enable |-> $stable(sel);
endproperty
//Check that sel is stable (HIGH) during a transfer
AMIQ_APB_ILLEGAL_SEL_TRANSITION_DURING_TRANSFER_ERR: assert property (amiq_apb_sel_stability_during_transfer_p) else
`uvm_error("AMIQ_APB_ILLEGAL_SEL_TRANSITION_DURING_TRANSFER_ERR",
$sformatf("[%0t] sel must be stable during a transfer.",
$time))
//Cover the amiq_apb_sel_stability_during_transfer_p property
AMIQ_APB_ILLEGAL_SEL_TRANSITION_DURING_TRANSFER_CVR: cover property (amiq_apb_sel_stability_during_transfer_p);
//Property definition for the minimum number of clock cycles during which sel signal must be asserted in a transfer
property amiq_apb_sel_minimum_time_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
$rose(|sel) |-> not(##1 $fell(|sel));
endproperty
//Check that sel is asserted at least two clock cycles during a transfer
AMIQ_APB_ILLEGAL_SEL_MINIMUM_TIME_ERR: assert property(amiq_apb_sel_minimum_time_p) else
`uvm_error("AMIQ_APB_ILLEGAL_SEL_MINIMUM_TIME_ERR",
$sformatf("[%0t] sel must be asserted at least two clock cycles.",
$time))
//Cover the amiq_apb_sel_minimum_time_p property
AMIQ_APB_ILLEGAL_SEL_MINIMUM_TIME_CVR: cover property(amiq_apb_sel_minimum_time_p);
//Property definition for enable fall event towards sel fall event
property amiq_apb_enable_fall_towards_sel_fall_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
$fell(|sel) |-> (($past(enable) == 1) && (enable === 0));
endproperty
//Check that when sel is falling, enable is also falling
AMIQ_APB_ILLEGAL_ENABLE_FALL_TOWARDS_SEL_FALL_ERR: assert property(amiq_apb_enable_fall_towards_sel_fall_p) else
`uvm_error("AMIQ_APB_ILLEGAL_ENABLE_FALL_TOWARDS_SEL_FALL_ERR",
$sformatf("[%0t] sel and enable must fell in the same time.",
$time))
//Cover the amiq_apb_enable_fall_towards_sel_fall_p property
AMIQ_APB_ILLEGAL_ENABLE_FALL_TOWARDS_SEL_FALL_CVR: cover property(amiq_apb_enable_fall_towards_sel_fall_p);
//}}}
//{{{ Specific checks for addr signal
//Property definition for addr stability during a transfer
property amiq_apb_addr_stability_during_transfer_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
(|sel) and enable |-> ($stable(addr) and ##[1: $] $fell(enable));
endproperty
//Check that addr is stable during a transfer
AMIQ_APB_ILLEGAL_ADDR_TRANSITION_DURING_TRANSFER_ERR: assert property (amiq_apb_addr_stability_during_transfer_p)
else
`uvm_error("AMIQ_APB_ILLEGAL_ADDR_TRANSITION_DURING_TRANSFER_ERR",
$sformatf("[%0t] addr must be stable during a transfer.",
$time))
//Cover the amiq_apb_addr_stability_during_transfer_p property
AMIQ_APB_ILLEGAL_ADDR_TRANSITION_DURING_TRANSFER_CVR: cover property (amiq_apb_addr_stability_during_transfer_p);
//}}}
//{{{ Specific checks for write signal
//Property definition for write stability during a transfer
property amiq_apb_write_stability_during_transfer_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
(|sel) and enable |-> ($stable(write) and ##[1: $] $fell(enable));
endproperty
//Check that write is stable during a transfer
AMIQ_APB_ILLEGAL_WRITE_TRANSITION_DURING_TRANSFER_ERR: assert property (amiq_apb_write_stability_during_transfer_p)
else
`uvm_error("AMIQ_APB_ILLEGAL_WRITE_TRANSITION_DURING_TRANSFER_ERR",
$sformatf("[%0t] write must be stable during a transfer.",
$time))
//Cover the amiq_apb_write_stability_during_transfer_p property
AMIQ_APB_ILLEGAL_WRITE_TRANSITION_DURING_TRANSFER_CVR: cover property (amiq_apb_write_stability_during_transfer_p);
//}}}
//{{{ Specific checks for wdata signal
//Property definition for wdata stability during a transfer
property amiq_apb_wdata_stability_during_transfer_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
(|sel) and enable and write |-> ($stable(wdata) and ##[1: $] $fell(enable));
endproperty
//Check that wdata is stable during a write transfer
AMIQ_APB_ILLEGAL_WDATA_TRANSITION_DURING_TRANSFER_ERR: assert property (amiq_apb_wdata_stability_during_transfer_p)
else
`uvm_error("AMIQ_APB_ILLEGAL_WDATA_TRANSITION_DURING_TRANSFER_ERR",
$sformatf("[%0t] wdata must be stable during a transfer.",
$time))
//Cover the amiq_apb_wdata_stability_during_transfer_p property
AMIQ_APB_ILLEGAL_WDATA_TRANSITION_DURING_TRANSFER_CVR: cover property (amiq_apb_wdata_stability_during_transfer_p);
//}}}
//{{{ Specific checks for prot signal
//Property definition for prot stability during a transfer
property amiq_apb_prot_stability_during_transfer_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
(|sel) and enable |-> ($stable(prot) and ##[1: $] $fell(enable));
endproperty
//Check that prot is stable during a transfer
AMIQ_APB_ILLEGAL_PROT_TRANSITION_DURING_TRANSFER_ERR: assert property (amiq_apb_prot_stability_during_transfer_p)
else
`uvm_error("AMIQ_APB_ILLEGAL_PROT_TRANSITION_DURING_TRANSFER_ERR",
$sformatf("[%0t] prot must be stable during a transfer.",
$time))
//Cover the amiq_apb_prot_stability_during_transfer_p property
AMIQ_APB_ILLEGAL_PROT_TRANSITION_DURING_TRANSFER_CVR: cover property (amiq_apb_prot_stability_during_transfer_p);
//}}}
//{{{ Specific checks for enable signal
//Property definition for enable assertion towards a transfer
property amiq_apb_enable_assertion_time_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
(|sel) and !enable |=> (enable);
endproperty
//Check that at the beginning of a transfer, enable is asserted at the next clock cycle
AMIQ_APB_ILLEGAL_ENABLE_ASSERTION_TIME_ERR: assert property (amiq_apb_enable_assertion_time_p) else
`uvm_error("AMIQ_APB_ILLEGAL_ENABLE_ASSERTION_TIME_ERR",
$sformatf("[%0t] enable must be asserted one clock cycle after a transfer starts.",
$time))
//Cover the amiq_apb_enable_assertion_time_p property
AMIQ_APB_ILLEGAL_ENABLE_ASSERTION_TIME_CVR: cover property (amiq_apb_enable_assertion_time_p);
//Property definition for enable stability during ready changes
property amiq_apb_enable_stability_during_ready_changes_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
!ready and enable |=> enable;
endproperty
//Check that enable is stable during ready changes (when ready is asserted during a transfer, after a LOW period)
AMIQ_APB_ILLEGAL_ENABLE_TRANSITION_DURING_READY_CHANGES_ERR: assert property (
amiq_apb_enable_stability_during_ready_changes_p) else
`uvm_error("AMIQ_APB_ILLEGAL_ENABLE_TRANSITION_DURING_READY_CHANGES_ERR",
$sformatf("[%0t] enable must be stable during ready changes.",
$time))
//Cover the amiq_apb_enable_stability_during_ready_changes_p property
AMIQ_APB_ILLEGAL_ENABLE_TRANSITION_DURING_READY_CHANGES_CVR: cover property (
amiq_apb_enable_stability_during_ready_changes_p);
//Property definition for enable valid value between transfers
property amiq_apb_enable_value_between_transfers_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
!(|sel) |-> !enable;
endproperty
//Check that between two transfers enable is kept LOW
AMIQ_APB_ILLEGAL_ENABLE_VALUE_BETWEEN_TRANSFERS_ERR: assert property(amiq_apb_enable_value_between_transfers_p) else
`uvm_error("AMIQ_APB_ILLEGAL_ENABLE_VALUE_BETWEEN_TRANSFERS_ERR",
$sformatf("[%0t] enable must be LOW between two transfers.",
$time))
//Cover the amiq_apb_enable_value_between_transfers_p property
AMIQ_APB_ILLEGAL_ENABLE_VALUE_BETWEEN_TRANSFERS_CVR: cover property(amiq_apb_enable_value_between_transfers_p);
//Property definition for enable de-assertion time during access phase
property amiq_apb_enable_deassertion_time_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
(|sel) and ready and enable |=> !enable;
endproperty
//Check that enable is de-asserted one clock cycle after the assertion of ready during access phase
AMIQ_APB_ILLEGAL_ENABLE_DEASSERTION_TIME_ERR: assert property(amiq_apb_enable_deassertion_time_p) else
`uvm_error("AMIQ_APB_ILLEGAL_ENABLE_DEASSERTION_TIME_ERR",
$sformatf("[%0t] enable must be de-asserted one clock cycle after the assertion of ready during access phase.",
$time))
//Cover the amiq_apb_enable_deassertion_time_p property
AMIQ_APB_ILLEGAL_ENABLE_DEASSERTION_TIME_CVR: cover property(amiq_apb_enable_deassertion_time_p);
//}}}
//{{{ Specific checks for strb signal
//Property definition for strb stability during a transfer
property amiq_apb_strb_stability_during_transfer_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
(|sel) and enable |-> ($stable(strb) and ##[1: $] $fell(enable));
endproperty
//Check that strb is stable during a transfer
AMIQ_APB_ILLEGAL_STRB_TRANSITION_DURING_TRANSFER_ERR: assert property (amiq_apb_strb_stability_during_transfer_p)
else
`uvm_error("AMIQ_APB_ILLEGAL_STRB_TRANSITION_DURING_TRANSFER_ERR",
$sformatf("[%0t] strb must be stable during a transfer.",
$time))
//Cover the amiq_apb_strb_stability_during_transfer_p property
AMIQ_APB_ILLEGAL_STRB_TRANSITION_DURING_TRANSFER_CVR: cover property (amiq_apb_strb_stability_during_transfer_p);
//Property definition for valid strb value during a read transfer
property amiq_apb_strb_value_read_transfer_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks)
(|sel) and enable and !write |-> ($sampled(strb) === 0);
endproperty
//Check that strb is 0 during read transfer
AMIQ_APB_ILLEGAL_STRB_VALUE_READ_TRANSFER_ERR: assert property (amiq_apb_strb_value_read_transfer_p) else
`uvm_error("AMIQ_APB_ILLEGAL_STRB_VALUE_READ_TRANSFER_ERR",
$sformatf("[%0t] strb must be 0 during read transfer.",
$time))
//Cover the amiq_apb_strb_value_read_transfer_p property
AMIQ_APB_ILLEGAL_STRB_VALUE_READ_TRANSFER_CVR: cover property (amiq_apb_strb_value_read_transfer_p);
//}}}
//{{{ Specific checks for ready signal
//Property definition for the maximum number of clock cycles during which ready signal must be kept LOW
property amiq_apb_ready_low_maximum_time_p;
@(posedge clk) disable iff(!reset_n || !en_ready_low_max_time || !en_protocol_checks)
(|sel) and $rose(enable) and !ready |-> ##[1: ready_low_max_time] ready;
endproperty
//Check that ready is not kept LOW more than a maximum number of clock cycles
AMIQ_APB_ILLEGAL_READY_MAXIMUM_LOW_TIME_ERR: assert property (amiq_apb_ready_low_maximum_time_p) else
`uvm_error("AMIQ_APB_ILLEGAL_READY_MAXIMUM_LOW_TIME_ERR",
$sformatf("[%0t] ready must be kept LOW at most maximum %d clock cycles.",
$time, ready_low_max_time))
//Cover the amiq_apb_ready_low_maximum_time_p property
AMIQ_APB_ILLEGAL_READY_MAXIMUM_LOW_TIME_CVR: cover property (amiq_apb_ready_low_maximum_time_p);
//}}}
//{{{ Specific checks for rdata signal
//Property definition for rdata stability during a transfer
property amiq_apb_rdata_stability_during_transfer_p;
@(clk) disable iff(!reset_n || !en_protocol_checks)
(!write) and (|sel) and enable and ready and ((has_error_signal and !slverr) or !has_error_signal) and $changed
(rdata) |-> $rose(clk);
endproperty
//Check that rdata is stable during the last clock cycle
AMIQ_APB_ILLEGAL_RDATA_TRANSITION_DURING_TRANSFER_ERR: assert property (amiq_apb_rdata_stability_during_transfer_p)
else
`uvm_error("AMIQ_APB_ILLEGAL_RDATA_TRANSITION_DURING_TRANSFER_ERR",
$sformatf("[%0t] rdata must be stable during the last clock cycle.",
$time))
//Cover the amiq_apb_rdata_stability_during_transfer_p property
AMIQ_APB_ILLEGAL_RDATA_TRANSITION_DURING_TRANSFER_CVR: cover property (amiq_apb_rdata_stability_during_transfer_p);
//}}}
//{{{ Specific checks for slverr signal
//Property definition for valid slverr value when one of sel, enable, ready signal is de-asserted
property amiq_apb_slverr_value_condition_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks || !has_error_signal)
!(|sel) or !enable or !ready |-> !slverr;
endproperty
//Check that slverr is LOW when one of sel, enable or ready is LOW
AMIQ_APB_ILLEGAL_SLVERR_VALUE_CONDITION_ERR: assert property (amiq_apb_slverr_value_condition_p) else
`uvm_error("AMIQ_APB_ILLEGAL_SLVERR_VALUE_CONDITION_ERR",
$sformatf("[%0t] slverr must be LOW when one of sel, enable or ready is LOW.",
$time))
//Cover the amiq_apb_slverr_value_condition_p property
AMIQ_APB_ILLEGAL_SLVERR_VALUE_CONDITION_CVR: cover property (amiq_apb_slverr_value_condition_p);
//Property definition for the time span between the assertion of slverr signal and the de-assertion of slverr signal
property amiq_apb_slverr_assertion_time_p;
@(posedge clk) disable iff(!reset_n || !en_protocol_checks || !has_error_signal)
$past(slverr) == 0 and $rose(slverr) |=> $fell(slverr);
endproperty
//Check that slverr is asserted one clock cycle
AMIQ_APB_ILLEGAL_SLVERR_ASSERTION_TIME_ERR: assert property(amiq_apb_slverr_assertion_time_p) else
`uvm_error("AMIQ_APB_ILLEGAL_SLVERR_ASSERTION_TIME_ERR",
$sformatf("[%0t] slverr must be HIGH only one clock cycle.",
$time))
//Cover the amiq_apb_slverr_assertion_time_p property
AMIQ_APB_ILLEGAL_SLVERR_ASSERTION_TIME_CVR: cover property(amiq_apb_slverr_assertion_time_p);
//}}}
endinterface
`endif