Tejbal Prasad, Shalini Damani
Freescale Semiconductor India Pvt Ltd.
In a System-on Chip(SoC),a general interrupt process works as follows:
- Interrupt is triggered by a certain system event or interrupt source.
- Interrupt is detected by system’s peripheral module, which then asserts its interrupt output pin and set its interrupt status register at the same time.
- Interrupt is captured by the embedded processor and an interrupt routine is executed to process the interrupt
- After processing the interrupt, interrupt status is cleared by writing related interrupt registers within the peripheral module. And the module is ready for another interrupt.
- Additionally in ISR (Interrupt Service Routine), any register related to that interrupt status is checked for the correct behavior.
In a standalone IP verification environment, usually the practice is to clear the status as soon as they are set. This paper proposes a method to mimic the actual behavior of the embedded processor for interrupt handling in standalone IP verification environment. Use of UVM components done to make a reusable, parameterizable and real time interrupt handler for UVM testbench. The method proposed in this paper describes an automated interrupt handler logic which runs parallel to entire environment.
In this method, simulation-based verification is used to verify the standalone IP. In simulation-based verification, the DUT is verified by comparing the result of the design with the golden model through simulation. This approach helps to randomize the testcases to achieve the required coverage numbers. The interrupt handler is completely automated as it waits for the interrupt event. After receiving interrupt, it executes ISR and clears the status registers after few cycles. The immediate clearing of interrupt status in DUT works fine for the normal scenarios when the interrupts come once a while. But, in some cases, for example, if interrupt assertion is periodic or if the interrupt status is required to be set for a particular number of clock cycles for multiple clock domain designs, instant clearing of the interrupt status is not satisfactory as it doesn’t help in finding bugs which may appear in a SOC. Therefore, this paper proposes a robust interrupt handler which can be configured for specific cases.
The technique proposed is also parametrizable as the number of interrupts can be changed through a parameter. It makes parameterized classes while inheriting the features of inbuilt UVM classes. In addition, it not only handles those statuses which generate interrupts with the help of interrupt enables, but also helps to check for those statuses which are implemented with W1C/W0C functionality in DUT. So, the entire W1C/W0C functionality for a DUT can be verified using this interrupt handler. This Interrupt handler can be reused by configuring the interrupt interface. The delay in clearing the interrupt status helps to mimic the SOC behavior, thereby making it a real time interrupt handler. This delay can be changed to give priority to some interrupts over other.
The interrupt handler (Interrupt environment) is placed in the testbench structure as shown in figure1 below:
The figure below, shows the implementation and hierarchy of uvm_components used for creating the interrupt handler. The transaction level communication interfaces provided by UVM have been used to automate the process.
Interrupt Sequencer is extended from uvm_sequencer, which controls the items that are provided to the Register Interface Driver for execution. An interrupt sequence is made (extended from uvm_seqs) which waits for the interrupt event and this sequence is run on the interrupt sequencer continuously. Code 1 shows implementation of interrupt sequencer. Here, NUM_OF_INT is the parameter which can be passed a different value. The interrupt sequencer has a TLM (Transaction Level Model) peek port (highlighted in code 1) which peeks for the interrupt from interrupt monitor. Whenever it receives an interrupt from the monitor, the sequence running on the sequencer waits for a random delay and then provides the driver with the transaction item to perform ISR operation as well as clearing the status.
Interrupt monitor is used for collecting the interrupt events from the DUT. Here, a collect_interrupt_transaction task is called, which collects the interrupt events. This task is spawn into threads which are equal to the number of interrupt events to be checked. Every time only one interrupt event is processed. In case when multiple interrupt events are detected simultaneously, semaphore key is get which ensures only one interrupt event is passed to the queue at a time.
In UVM, uvm_sequence_item is used for communicating between two UVM components. Interrupt transaction is extended from this class. Code 3 shows its implementation.
Interrupt sequence inherits all the properties of uvm_seqs and is run on the interrupt sequencer. A blocking peek port is used to pass the interrupt transaction from monitor to sequencer. As highlighted in the code 4, peek method is called which is implemented in monitor. In a way, this sequencer waits till it receives an interrupt event. Depending on the interrupt transaction, sequencer decides which ISR to execute and after a random number of clock cycles initiate the Register Interface driver to process the interrupt event. Additionally in ISR, it can also check for correctness of any register related to that interrupt event through Register Access Layer (RAL) predict and mirror methods which is shown in next section, ISR Functional Check.
ISR Functional Check:
In general, along with the interrupt status register, user is also interested to check content of other relevant registers. For example, in an ADC (analog to digital convertor module), if End of Conversion interrupt comes along with EOC status, user would like to check ADC data register. This can easily be implemented in this environment, which will ease the sequence generation. Prediction of ADC data register value will be done in scoreboard and checking can be done in ISR routine along with check_w1c_bit_functionality. As shown in the code snippet below, after check_w1c_bit_functionality function call, mirror method is called to check the ADC data which was predicted in scoreboard using predict method.
Inside scoreboard, user can set the expected value through:
Inside interrupt sequence, the following code can be added after W1C check:
Use of UVM RAL feature enables user to automate this flow. So this way, sequence creation becomes easy, prediction part is taken care in scoreboard and ISR becomes stable.
Additionally, assertions have been put on interrupt pins to ensure correct behavior of interrupt status and interrupt enables as shown in Code5:
Figure 3 shows how interrupt handler works. Here, waveform shows how interrupt status is set and is cleared between marker 1 and marker 2 for interrupt_status.The corresponding register interface transaction is also shown with address, rdata(read_data), wdata(write_data), module_en and rwb(read/write enable).
In figure 4, W1C functionality is explained for interrupt_status between marker 3 and marker4.Here, address is 14 and module_en is high. Read/write enable rwb =0 for read and rwb =1 for write. The status register is read,W0C is performed, status register is read again, it should return the same status. Then, W1C is performed and the status is read again to see whether status was cleared or not. In figure 4, after interrupt_status goes to zero, rdata in next cycle for address 14 returns interrupt_status as zero.
1) In case of standby, incorrect isolations can be caught. For example, if a status is dependent on a signal which gets isolated in standby to 1, then as soon as standby is removed, DUT will clear the status and this will be caught as interrupt handler will give an error “W1C status not set”.
2) Instead of W1C, W0C clearing the status or vice-versa.
3) Dependency of one status bit on another, thereby clearing of one affects other.
1) Parameterizability: The above logic is configurable for any number of interrupts as the classes used are parameter controlled, parameter being the number of interrupt events.
2) Reusable: It can be simply plugged into any standalone IP verification TB by passing the interrupt interface for that design.
3) Delay can be any random number giving user the flexibility or it can be made a function of interrupts.
4) The interrupt handler runs parallel to entire environment; therefore, user need not worry about checking of interrupt status.
5) It also enables user to check correctness of any data register value related to an interrupt event.
6) If there are other bits with W1C functionality which may not be contributing to interrupt can be handled through this interrupt environment.
1) SystemVerilog Language reference manual 3.1
2) UVM User Guide version 1.1
3) UVM Class reference manual 1.1