10. BFM driver and receiver components should always be separated from extractors, checkers and monitors so they can be used at the module level, but excluded at the subsystem or chip level when various RTL modules are interconnected.
11. Keep data extraction functionality separate from DUT checker functionality. It is very common to initially design these two functions at the same time in the same unit. Also keep checker and monitor functionality in separate files as well. It is not uncommon for monitors to have dependencies on the checker and for the checker to have dependencies on the extractors, but not the other way around. This rule is especially important when multiple checkers (or multiple TCMs of the same checker) use the same data extractor or when the project requires that checkers will always be used, but monitors will be selectable.
12. Consider cycle-accurate checkers carefully. Sometimes it is necessary for the checker to maintain a cycle-accurate mirror register or internal state in order to accurately predict proper operation. While it is acceptable to monitor internal signals to help keep track of required states (and to possibly verify them as well), a checker should never force external or internal signal values. Leave the forcing of signals to the BFM components. Remember that cycle accurate checkers will have a very tight linkage to the RTL module, which implies that any change in timing due to a RTL change will require a corresponding e code change.
13. Consider reset handling early. There are some techniques that try to handle resets by killing threads and methods when resets are asserted, and then starting them when reset is de-asserted -- but not all resets are created equal. Sometimes a module will have a global and a local reset, or a requirement that certain opera tions must be stopped cleanly in case of a reset condition. These cases must be handled uniquely. Also consider that some signals that can act like a reset but are really not (such as special emulation or test modes) and require special handling.
14. BFMs (stimulus drivers) should be able to create and drive random stimulus as well as specific directed stimulus. The directed stimulus should also allow the test writer to purposively cause errors and faults in order to verify DUT handling. However, the default constraints on the random stimulus should only produce valid data accesses. This will also allow for some BFMs to drive specific cycles while other instances drive random cycles in the same simulation.
15. Consider creating a separate TCM in any BFM that drives RTL signals. This TCM can be used as a synchronizer to drive signals at a specified delay time that is not coincident with a clock edge. The BFM logic can drive the internal variables as needed throughout the code, and then the synchronize r TCM can sample these internal variables and drive the signal ports in one convenient place.
16. When modifying/supporting features, careful consideration needs to be given to portions that may be added/subtracted in different designs. For instance, if a bus checker handles four types of accesses, consider the possibility that someday a fifth will be added. User defined types and case statements for these types normally produce effective self-documenting and easy-to-modify coding styles.
17. Keep all project specific code and functions out of the core code to be reused. Instead use a common but separate file for all constraints and configurable code fragments for unique project modifications. This aspect-oriented approach allows for easy identification and maintenance of all modifications without affecting the standard base code.
Error handling/reporting techniques
18. Whenever possible, report protocol errors as clearly as possible with either the exact numbered specification ru le id or create your own numbered rule set.
19. Reserve reporting DUT errors for actual erroneous DUT behavior. Consider using a DUT warning for accesses that are technically illegal but handled correctly by the DUT module. For instance: a logged warning equals bad stimulus, which may or may not have been created on purpose.
20. Use Specman's built in error reporting feature whenever possible. This feature will report the any user message as well as the exact file and line of code, plus it will allow you to define and customize handling of different classes of errors. For example, you could define: 1 class of errors that are fatal, a 2nd class that are DUT errors, and a 3rd class that are test sequence warnings. Of course, you can also configure how the simulator will handle the error, such as: Fatals stop the test immediately, Errors get counted but the test is not stopped, and Warnings get counted separately but the test is not stopped. The test passing criteria could be number of errors must equ al 0.
21. Avoid having long multi-cycle expect statements that report a single generic error whenever a complicated sequence does not occur as expected. These make it difficult for non-experts to ascertain the exact cause/step of the error.
Testbench architecture techniques
22. Sometimes it may be advantageous to build an e testbench structure that parallels the corresponding RTL structure. With each level of e, you're assigning and appending its RTL instance path name to the HDL_PATH structure. This makes entire subsystem reuse (both RTL and e components) very easy to handle.
23. When trying to verify parameterizable RTL, use Specman to read in generics or parameters and then self configure the E testbenches and tests to appropriate configurations. This may involve the components or testbenches actually "building" signal string names themselves based on the detected configuration.
Import file techniques
24. When importing e files, always try to use a consistent pathname convention. There are at least two different conventions that could be used and the decision on which to use should be based on your intended project file directory structure. If reusable modules will be kept in some standard dir or library (preferred), then it would be better to always use full pathname syntax for all import statements. If reusable modules are kept (as snapshot copies or links) in each individual project directory, then it would be better to use relative pathname syntax for all import statements. Either way, a consistent convention will ensure reusability without import statement modification.
25. Try to have each reusable e file import all required files itself instead of relying on some previous file to import all files as a group. This will help illustrate actual file dependencies as well as allow Specman to handle any cyclic dependencies. It will also help each file to stand alone in the case of a partial-reuse situation.
5.0 Conclusions and Summary
As ve rification reuse opportunities continue to grow, and schedules continue to shrink, more and more engineers will need to both create reusable-friendly code and reuse other code as well. Inevitably, it will become the normal and expected way to verify all ASIC designs. Just as the tools and languages have evolved into allowing this to happen, specific reuse techniques will also evolve to make it able to happen more efficiently.
This discussion, and others on the same subject, can provide a solid foundation -- but the real improvements (and productivity gains) will be the result of well designed verification code and components that have had reusability techniques implemented initially.
Peter Spyra works as a verification consulting engineer for Integre Technologies in Rochester, N.Y. His recent project work includes multi-processor SOC verification for a major foundry.