The AMBA 4 specification for the connection and management of functional blocks in a system-on-chip (SoC) now features Advanced eXtensible Interface (AXI) coherency extensions (ACE) in support of multi-core computing. The ACE specification enables system-level cache coherency across clusters of multi-core processors. The verification of such a system poses significant challenges. When planning the functional verification of such a system, we need to have an effective testing strategy to ensure not only that all aspects of the protocol are tested, but also that bugs are caught with the least effort. In other words, we need to have a hierarchical testing strategy where we progress from simple sequences to more complex sequences. The aim is to catch as many issues with the simpler sequences so that as we move to the more complex sequences where the problem space is much larger, we have fewer bugs to deal with. In this series, we will propose such a hierarchical verification strategy. Each post in this series will describe:
Here’s where you can find more information on Verification IP for AMBA 4 AXI.
Hierarchical Testing for ACE
What should we test at each level of hierarchy from an ACE point of view? These could be:
The ACE protocol uses many different types of transactions. Each of these transactions can be initiated by a master with the corresponding cacheline in many different states (hereafter referred to as initial cache line state). For each of these states there are legal responses which are allowed. The problem space becomes further complicated with the final cache line state (after a transaction ends) being determined by various configuration options. We need to make sure that all the response types for each initial cache line state are tested. At this level of testing we ensure that the system works correctly and coherently for each transaction type.
The specification gives several rules to be observed by the interconnect when two masters access the same/overlapping address. At this level of testing we exercise sequences to ensure that all accesses to overlapping addresses follow these rules
In this post, we will elaborate on the first aspect of a hierarchical verification.
Integration and Connectivity Testing
The key verification requirements for integration and connectivity testing have already been mentioned earlier. Verification IPs typically provide ready to use sequences for generating relevant traffic. A set of such sequences or sequence library which ships with the VIP can be used as a starting point for meeting the users’ requirements. This enables users to conveniently use them in the appropriate simulation phase and by modifying the required parameters relevant for their DUT. Thus, even for integration testing, users can leverage some of the basic sequences that ship with the VIP. Let’s look at the kind of sequences which can be used for this purpose. Given that we would want to look at all the valid paths, we should have a set of sequences which would initiate WriteNoSnoop and ReadNoSnoop transaction from the ACE/ACE_LITE master specified with an attribute, say port_id , which can be a random port or a specific port configured by the user. The ‘port_id’ would be an attribute which can be configured to control the port from which you want to initiate transactions. These sequences should then be run on all the masters in the system.
Here’s an example. The following snippet shows how the port_id attribute can be configured:
uvm_config_db#(int unsigned)::set(this, “env.axi_system_env.sequencer.svt_axi_ace_master_readnosnoop_sequence”, “port_id”, 1);
The default value of this attribute can be randomized to a valid value based on the number of masters in the system.
We also need to make sure that a master accesses all the slaves in the system that it is allowed to so that all the paths are tested. For this we need to constrain the addresses based on the system address map so that we can be sure that all the paths are covered. This can be done by defining custom constraints.
This is how we can create custom constraint on a transaction initiatied from the master side:
class cust_svt_axi_master_transaction extends svt_axi_master_transaction;
rand int slave_port_id = 0;
constraint valid_slave_port_id {
slave_port_id inside {[0:`SVT_AXI_MAX_NUM_SLAVES-1]};
//` SVT_AXI_MAX_NUM_SLAVES defines the maximum no. of slaves in the system environment
}
constraint cust_addr_ranges_constraint {
// Accesses from master 0:
if (port_cfg.port_id == 0) {
// Accesses to slave 0
if (slave_port_id == 0) {
addr inside {[0:32’hff]}
}
else if (slave_port_id == 1) {
addr inside {[32’h10000:32’h100ff]};
}
// Accesses from master 1 }
else if (port_cfg.port_id == 1) { }
}
endclass
Key Verification Points and Potential Issues in Integration Testing
System Connectivity
SoCs have hundreds of signals to be connected and quite often some of these signals are not connected properly. If not connected, the VIP will observe ‘X’ on these signals and will report an error indicating the same. For example this error probably indicates that the ARCACHE signal is not connected between the interconnect’s master port and the slave[2] VIP:
ace_system_env.slave[2].monitor [register_fail] CHECK [effect=ERROR]: Executed and FAILED – ENABLED AMBA CHECK: signal_valid_arsnoop_when_arvalid_high_check (ACE_LITE/ver 2.0), Description: Monitor Check for X or Z on ARCACHE when ARVALID is high
Transaction routing
The interconnect must route transactions properly based on the system address map. There should be appropriate methods to specify the system address map of the VIP. If the interconnect routes a transaction incorrectly, the system monitor can flag the appropriate ‘transaction routing check’.
Data integrity
A key aspect of the testing at this level is ensuring data integrity. The data in write transactions must be written into the slave correctly. Similarly, data fetched from a slave must be returned to the master correctly. The system monitor should perform these checks by comparing data in memory and the transaction after a transaction completes (at the master that initiated the transaction). The system monitor should have the required infrastructure to do these checks across ports of varying data widths. In order that the data integrity check works correctly, the sequence that runs on a slave VIP must update the Slave memory instance in the corresponding agent. If the slave VIP is configured in passive mode, the system monitor should maintain a memory mirror and update it based on activity on the bus. If data is not written/read correctly, the system monitor should flag the data Integrity checks.
In this post, we have described the testing strategy and the key aspects of integration and connectivity testing. In the next post, we will talk about coherent transaction testing where we enter the interesting and challenging world of cache coherency.
Here’s where you can find more information on Verification IP for AMBA 4 AXI.
Authored by Ray Varghese