A typical SOC design consists of one or more processors that communicates with multiple internal peripheral units. SOCs communicate with external peripheral devices through external bus ports. An example of a typical SOC design is shown in the following figure. The example (called PULPino ) is a simple SOC which contains a single RISC-V based core. This core uses AXI interconnects to communicate with internal high-speed controllers and through the APB to external peripherals. There are 4 external peripherals shown in the figure below:
In order to verify the above SOC, a number of test scenarios need to be constructed. For the purposes of this exercise, we will assume that individual components of the SOC are fully verified for functionality and working fine. Hence the focus of SOC verification is mainly communications across the components both internal and external. For example, one test scenario would involve reading something from the I2C peripheral port and storing it in internal “Data RAM”. This scenario is developed in “C” code using C-based API functions provided by the SOC developer. An example of a test that reads from I2C and stores the data into an allocated buffer (readByteBuffer) is shown below.
In order for the I2C peripheral to provide data for the above test we attach UVM VIPs to each of the peripheral ports. The UVM VIPs are capable of generating external traffic (into the SOC) and also responding to the traffic from the SOC core. An UVM Environment is constructed for the testbench as shown in next section.
The behavior contains two portions (a) Software part – which is the compiled “C” code running on the CPU and (b) hardware part – the UVM sequences running on the VIPs. Test coordination becomes critical especially because these two parts have no knowledge of the existence of the other part. The “C” code has no idea about a VIP sequence running in the same environment and the VIP sequences have no idea (or cannot control) the execution of the “C” code. Moreover, since the test case involves execution of SystemVerilog  code in the VIP, we have to use a commercial SystemVerilog simulator for simulating the SOC test. The master controller for the test is the System Verilog test that needs to figure out when to shut down the simulation.
The recommended way of ending an UVM simulation is using the Objection Mechanism. UVM provides an API called “raise_objection ()”. Any UVM component can call this API to inform the simulator that it is currently performing an important operation and the UVM scheduler should not jump out of the run_phase. After completing its important activities, the UVM component will call “drop_objection ()” which then allows the simulator to move on from the run_phase of UVM.
Although the UVM objection mechanism is powerful to end the test, the main questions remain (a) which UVM component will raise objections? (b) when will the objection be raised? (c) How will the component know when to drop the objection?
We review two methods that can be used for ending a test
In this method, a particular end-of-test message is incorporated into every “C” test after all the activities of the test are completed. This end-of-test message is targeted towards a particular peripheral port in the design. The VIP attached to this peripheral has the additional responsibility of raising the objection at the beginning of the test and dropping the objection when the end-of-test message is received. The only drawback with this method is coming up with a custom VIP that will perform the above function, in addition to responding to its normal role.
In this method we assume that every SOC has a GPIO port to connect custom peripherals to the SOC. This GPIO port can be used to trigger the end-of-test scenario. Here, a particular GPIO pin is toggled when the SOC test reaches the end. A custom VIP listening on the GPIO ports will have the additional responsibility of raising the objection at the beginning of the test, and dropping it when the appropriate end-of-test signal toggle is observed.
Both these methods were implemented successfully on the PULPino SOC. The GPIO VIP was a custom VIP that was enhanced with this functionality. The message passing method was implemented on the UART port of the SOC. The custom UART slave VIP took care of end of the test when the message was received.
If you need additional information about this article or setup a similar environment for your SOC please contact us “firstname.lastname@example.org”.