APB Interface

Understand the DUT Interface

This module would cover the APB System RTL which will be verified by the testbench designed in the further modules. The design under test (or the DUT) is an APB Master RTL which implements the APB protocol to send out transactions to the slave. The design has certain properties which are defined below but essentially the goal of the system is to offload data processing to the slave and then read it back. As a result, the design sends a bunch of write transactions to the slave where the write data represents the data which the slave needs to process and then reads it back. The transactions can take arbitrary amount of time to be sent by master.

Before we look into the interface requirements, here's a quick look into the APB protocol: The APB is part of the AMBA 3 protocol family. It provides a low-cost interface that is optimized for minimal power consumption and reduced interface complexity. APB protcol typically consists of the following interface signals:

  • psel : Any valid transfer on the protocol starts by asserting the psel signal
  • penable : The penable signal must be asserted a cycle after the psel signal is asserted
  • paddr : This represent the address of the transfer to the slave
  • pwrite : Differentiates between a write and a read request
  • pwdata : Represents the write data in case of a write transfer. Ignored for read transfers
  • prdata : The read data from the slave
  • pready : Indicates the slave has accepted the request

Just like any other valid/ready based interface, the psel, penable and other payload signals remain asserted and stable until the pready signal is asserted.

OK, now that we understand how the APB protocol is supposed to work, let's take a look at the interface requirements for our design under test.

Interface Requirements

  • Out of reset, the master must send exactly 16 write transfers before reading from the slave
  • The write transfer must start from address 0 with the address increasing by 1 after every successful transfer
  • The read request can only be sent once the 16 write transfers are successfully completed
  • There are no restrictions on the write data (pwdata) signal and it can take any value
  • The APB master is allowed to do back-to-back transfers as long as those are meet the protocol requirements
  • The APB master can restart the write transfers after the 16 reads are successfully completed

Interface Definition

  • clk - The free running clock
  • reset_n - The asynchronous active low reset signal
  • apb_psel_o - The APB psel output from the master
  • apb_penable_o - The APB penable output from the master
  • apb_paddr_o - The 16-bit address output from the master
  • apb_pwrite_o - The pwrite output
  • apb_pwdata_o - 32-bit write data output from the master
  • apb_pready_i - The incoming pready signal from the slave
  • apb_prdata_i - The incoming 32-bit prdata (read data) from the slave

Testbench Requirements

OK, we now understand the design under the test but what are we supposed to verify. For firsts, the testbench should be able to verify all of the listed interface requirements stated above. As an example, the testbench should check that the design indeed performs the 16 write transfers before the read transfer is made. It should also check that the address starts from 0 and is incremented after every successful transfer. Apart from the above the testbench should also verify that the APB master RTL meets the APB protocol requirements. This implies that all of the protocol requirements mentioned in the specifications must be checked.

This would be the goal for this testbench and apart from checking for the output the testbench would also be responsible for generating the input signals. For this design the input signals are pretty straightforward, since the testbench only needs to drive the apb_pready_i and the apb_prdata_i input signals. As far as the design is concerned both of these could be randomly driven by the testbench since there aren't any specific requirements for these signals. The only care which needs to be taken is that a valid APB transfer (i.e. when all apb_psel_o, apb_penable_o and apb_pready_i are asserted) the testbench captures it as a valid APB transfer. Right, so the testbench would have the following requirements then:

  • Randomly assert the apb_pready_i and apb_prdata_i signals
  • Implement components to check that the master performs exactly 16 writes before the reads can start
  • Add checks which guarantees that the address for the first transfer starts from 0 and then increments by 1
  • Add checks to ensure the APB protocol requirements are met

In the next few modules we would build different class based testbench components to implement all of the above requirements.

Coding Exercise

In the last module, we learnt about the various testbench components and in this coding exercise we would starting implementing those one-by-one. The first thing we need is a way for our testbench to communicate with the design under test. This is done by implementing the interface to the design. An interface is a named bundle of nets or variables but can also include parameters, functions and tasks. As we will see later it can also include verification components like a clocking block but more on that later. The interface without any verification constructs is indeed synthesisable and be used for RTL Design however we would be using it for the verification testbench as a mechanism to get our dynamic class based components access to the RTL input and output ports without having us to have multiple signals being passed down. Infact, the interface construct in SystemVerilog was specifically created to encapsulate the communication between blocks. By encapsulating the communication between blocks, the interface construct also facilitates design re-use. A significant proportion of a Verilog design often consists of port lists and port connection lists, which are just repetitions of names. The ability to replace a group of names by a single name can significantly reduce the size of a description and improve its maintainability.

The included video gives a detailed explaination for this module. Do watch the video to get a better understanding of the RTL and the testbench requirements. As always, you could reach out to me via email or discord if you have any further doubts and I'd be happy to help!

In the next module we would develop our first class based component -- the transaction object!

Loading the interactive workspace...