Accellera published the Early Adopter release of its Portable Stimulus standard mid-June 2017. The aim of the Accellera portable stimulus standard and the tools that support its two languages is to make it possible to express the intent of tests just once but have the ability to assemble them into test suites that can be used by many different personnel staffing a project, from hardware designers through to embedded software engineers, and which can be deployed in many different environments across different levels of integration.
Although one of the aims of the Unified Verification Methodology (UVM) was to enable test reuse, it faces challenges outside of the conventional hardware verification environment. For engineers who are not verification, the UVM framework can be difficult to deploy and imposes considerable development effort if the application is, say, intended for directed tests on a unit module.
A second issue with UVM is its reliance on SystemVerilog as the language used to create checkers and testbenches. This has made it difficult to reuse the stimulus code at the system level – an environment where tests are generally executed with the aid of one or more embedded processors that sit inside the design. In these situations portions of the test need to be generated in the form of or machine instructions or compilable C code that may call operating systems services.
Aims of portable stimulus
The hope of those involved with the Portable Stimulus standard is that it will promote an increase in the level of verification productivity across the entire SoC design cycle, leveraging the many test components that are created as the project progresses and making them available to system-level testbenches in a form that lends itself to extensive automation.
The Accellera committee stresses portable stimulus should not be misunderstood as a way of forcing people to use the same level of abstraction and that it is not meant to replace all testing activities.
The committee expects, however, portable stimulus to help drive two key trends. One is to make coverage-oriented test creation a mainstream activity. The other is the increased use of formal analysis at multiple levels of verification, with the process of verification potentially further augmented by machine-learning techniques.
One possible future direction for Portable Stimulus, as seen with UVM, is the creation of verification IP based on the portable-stimulus languages intended to exercise modules that implement standard protocols and provide a degree of compliance testing.
Stimulus for IP
An example of a portable stimulus use-case that will be commonly encountered in the verification of an IP core is in testing the various registers that make up the core’s control interface. During the test there is a series of register writes and reads. Expressed in one of the standard’s languages a compliant tool will interpret the register accesses and create test sequences that could be in the form of RAL sequences for a UVM environment or, for SoC-level simulation, a C code module that generates a series of memory-mapped register accesses. Both techniques could be employed in the same simulation. For example, not all of the cores exercised in the test may be instantiated at the system level, requiring the use of UVM drivers to perform the tests. The compliant tool would need to synchronize transactions. It may also perform environment-dependent tuning. For example, the tool may run more or deeper random sequences on a silicon prototype compared to when the same set of core tests are run in simulation or emulation.
Tests run from processors within the simulation or silicon environment may be generated in different forms. For example, a more complete device-under-test (DUT) may run the tests from processors that have a full operating system in place and so operate with linker-managed memory and service calls. Another environment may create C code intended for bare-metal execution with memory mapping handled by the portable-stimulus tool itself. The tool may need to perform its own loop unrolling in order to ensure correct behavior for the tests and not leave those decisions to the C compiler.
Actions in portable stimulus
The core of the portable-stimulus standard lies in the action: this is the way in which the language expresses behavior. Actions are modular – assembled into larger compound actions through activity graphs – and are able to interact with other actions. Simple actions may be reused many times over by assembly into multiple compound actions. This is on top of the reuse allowed by selective synthesis by portable-stimulus tools.
Actions have inputs and outputs that define how data flows through them. The activity graphs that bring actions together define how each of them is scheduled relative to each other. Flow objects and resources are used to constrain actions. These constraints are used by the test-generation tools to create realistic scenarios and use-cases.
Flow objects include streams and buffers. With streams, the producing and consuming objects need to run in parallel so that they can react to changes in data appropriately. The buffer object has its own storage so that producer and consumer are decoupled, with the buffer filling and emptying at different times. Constraints can be used to determine how transfers are made. For example, the data may need to be word-aligned.
Actions that are not linked by dataflows run sequentially in program order by default. But, if grouped under the
parallel keyword, the actions will be run in parallel by the tool. Grouped under the
select statement, the tool can choose any one of the actions for executions to support test randomization at the scenario or use-case level. Actions can also be grouped into if-else, do-while, repeat, and foreach blocks. Finally, the
schedule block allows execution in any order that is legal for the constraints on each of the actions.
The resources that need to be modeled are created as user-defined types, in effect a specialized form of C
struct. Actions can claim a resource for the duration of their execution and they may lock it to exclude other actions from accessing the resource during that time. Or they may share the resource, with the effect that no other action can exclusively lock it until all the actions that share it are finished. Both resources and constraints can be inherited from a base action.
In the standard, a
component is a type namespace that provides for the reusable grouping of actions, pools of resources and configuration parameters. An example of a component is a UART that incorporates input and output actions with the constraint that only one can be used at a time and that an access locks it from use by other actions within the test scenario.
Based on the constraints and data flows, tools can infer much of the behavior they need to generate from comparatively simple statements. For example, in the case of a UART module, the invocation of the read-out action for a loopback test is all that needs to be defined in the test. The tool uses the component specification to determine what contingent actions need to be executed for the test to run.
The Accellera committee has defined two languages for creating portable stimulus. One is a custom domain-specific language (DSL) that uses the keywords described above in a structure not dissimilar to that of Python. The other is a class library for C++ that allows the use of the same keywords in a context more familiar to software developers – a similar approach to that used for SystemC.
One aspect of the Portable Stimulus standard that is different to prior Accellera standards is that there will be no reference implementation. The committee opted for this because it expects there to be a wide range of tools that support the two languages and also because of the concern of reference implementations choking off development of novel technologies and tools because users tend to rely on the free reference version, something that became an issue with SystemC.
Examples in this guide were derived from Accellera’s webinar series on Portable Stimulus.