94
4 Verification and Testing
As long as the synchronous design operates well below the speed limits of the process technology, it approaches an ideal synchronous design. The parts that are more
difficult to simulate are the interfaces to any internal analogue parts and interfacing
to the outside world. Mixed-signal simulations are used for this purpose; where in the
analogue-parts are either modelled in a simplified manner, from only a behavioural
perspective, or the full analogue schematic is modelled.
To drive a digital simulation, a testbench code is created, which encapsulates the
design-part to be tested. Its purpose is to direct the overall testing effort, as well as to
provide stimuli to the device under test, and to verify automatically the correctness
of its response. It is essential to have tests that verify the complete operation of a
design, including all corner cases, to minimize the risk of discovering issues after
production. Code/test coverage tracking helps in this regard, where the tool collects
information on which statements have been executed in the code, which branches
have been taken, which states that have been covered or transitioned between, and
which bits in a register have been toggled. Code that cannot be covered by exercising
the inputs is likely to be dead code and might need to be removed. Exceptions would
be, for instance, SEU hardening code like TMR, which is triggered by impinging
particles.
Code coverage only verifies the correctness of what has been implemented and
can be generally considered a quantitative measure of the design code, but it does not
necessarily verify that all the specified functionality has been implemented or tested.
The design intent from the specifications must, in addition, be formulated as testable
statements that can direct the testing to verify that all features have been covered,
generally referred to as functional driven verification.
To detect illegal transactions and signalling in the code, the design uses assertions,
which are small pieces of simulation code inserted in the design code that reports
when certain conditions occur. The benefit of including assertions is that they report
both when testing a module standalone and when it is tested together with other
modules as part of a bigger hierarchy. With assertions, interfaces between modules
can more easily be verified when testing a bigger hierarchy, and the origin of the
error is easier to pinpoint without the need to trace an error from a top-level output
back to its point of origin.
The testbenches in this design use a combination of directed testing, where the
specific design intent and specifications are verified, and random testing, where the
input stimulus is randomized to exercise the bulk of the code coverage metrics.
Testing the complete behaviour of a sub-module from the topmost level of the design
hierarchy is often complicated by both the limited set of input controls available from
the top level and the increased simulation time that is required to test the larger amount
of code. Due to this, it is generally preferable to test the sub-module in isolation as
well. However, since testing in isolation might not capture all the intricacies of the
inter-module communications in the design, it is still important to try to verify as
much as possible from the top level, particularly since the top-level testbench is
used for verification of the post place and route code including timing verification.
For the v2 design, the top-level testing was primarily done using functional directed
testing, but more randomized tests where added for v3 as issues were discovered
4 Verification and Testing
As long as the synchronous design operates well below the speed limits of the process technology, it approaches an ideal synchronous design. The parts that are more
difficult to simulate are the interfaces to any internal analogue parts and interfacing
to the outside world. Mixed-signal simulations are used for this purpose; where in the
analogue-parts are either modelled in a simplified manner, from only a behavioural
perspective, or the full analogue schematic is modelled.
To drive a digital simulation, a testbench code is created, which encapsulates the
design-part to be tested. Its purpose is to direct the overall testing effort, as well as to
provide stimuli to the device under test, and to verify automatically the correctness
of its response. It is essential to have tests that verify the complete operation of a
design, including all corner cases, to minimize the risk of discovering issues after
production. Code/test coverage tracking helps in this regard, where the tool collects
information on which statements have been executed in the code, which branches
have been taken, which states that have been covered or transitioned between, and
which bits in a register have been toggled. Code that cannot be covered by exercising
the inputs is likely to be dead code and might need to be removed. Exceptions would
be, for instance, SEU hardening code like TMR, which is triggered by impinging
particles.
Code coverage only verifies the correctness of what has been implemented and
can be generally considered a quantitative measure of the design code, but it does not
necessarily verify that all the specified functionality has been implemented or tested.
The design intent from the specifications must, in addition, be formulated as testable
statements that can direct the testing to verify that all features have been covered,
generally referred to as functional driven verification.
To detect illegal transactions and signalling in the code, the design uses assertions,
which are small pieces of simulation code inserted in the design code that reports
when certain conditions occur. The benefit of including assertions is that they report
both when testing a module standalone and when it is tested together with other
modules as part of a bigger hierarchy. With assertions, interfaces between modules
can more easily be verified when testing a bigger hierarchy, and the origin of the
error is easier to pinpoint without the need to trace an error from a top-level output
back to its point of origin.
The testbenches in this design use a combination of directed testing, where the
specific design intent and specifications are verified, and random testing, where the
input stimulus is randomized to exercise the bulk of the code coverage metrics.
Testing the complete behaviour of a sub-module from the topmost level of the design
hierarchy is often complicated by both the limited set of input controls available from
the top level and the increased simulation time that is required to test the larger amount
of code. Due to this, it is generally preferable to test the sub-module in isolation as
well. However, since testing in isolation might not capture all the intricacies of the
inter-module communications in the design, it is still important to try to verify as
much as possible from the top level, particularly since the top-level testbench is
used for verification of the post place and route code including timing verification.
For the v2 design, the top-level testing was primarily done using functional directed
testing, but more randomized tests where added for v3 as issues were discovered
