Author: Craig Maiman – Principal RTL Design Consultant
Welcome to the RTL Design Success series — Part 6 of 9
5.10 Bus Functional Models
A Bus Functional Model imitates an interface that interacts with your block. It doesn’t necessarily do all the functions behind the interface, but just enough to act like the real block would act in interfacing with your block. For instance, a BFM of another custom block that your block interfaces to, likely has just enough functionality to fake that interface.
If your block interfaces to vendor IP, you should investigate whether a behavioral model is available which you could instantiate into your testbench.
Note that the stimulus into your design may itself have to be a BFM in the sense that there may be a protocol involved (e.g., a standard interface with a handshake).
5.11 Debugging Techniques
For simple testbenches looking through waves should be fine for debugging, but for long-running randomized testbenches it can be very difficult to wade through so much output.
An alternative I’ve used is to instrument my code to help narrow down the issue. This could be done any number of ways, but an example would be to put print statements in state machines and/or conditional statements so, instead of looking at waves, you can use a text editor to look through the text output to see what might be going wrong.
Doing that can at least narrow down where and when the issue might be happening and allow you to bring up the waves and quickly focus on the problem area.
Also, both VHDL and SystemVerilog have assertion commands that you can Imbed in your code to check for illegal states and protocol violations.
The testbench itself can output very useful debugging information. An example of this is in Section 7 above.
RTL Recommendations
6.1 Follow a Consistent Language and Style
I suggest you code in a consistent and readable style of one language version. I’ve looked at too much code that is a mix of language versions and unreadable – don’t be that person. Code using SystemVerilog constructs such as always_comb, always_ff, logic, etc. Don’t mix in older style Verilog constructs such as always, wire, reg, etc.
Here’s a good SystemVerilog style guide to consider. Also to be considered as overriding any of your preferences for coding style is what your development team or company specifies as the official coding style.
6.2 Comment Your RTL
The next thing I’d recommend is just as important as the style and that is commenting. You need to consider that either you or someone will someday look at your code and need to understand how it works. Again, I’ve seen way too much code that has almost no commenting.
Every complex process should have a header comment describing everything about that process. The more information you include, the better.
Comment every line that is not simple and make sure it describes the function and reasoning behind that line. Don’t just restate what the expression is, explain it.
I can’t tell you how many times I’ve looked at my own code a few months after I’ve written it and had no idea of the thinking behind the code. It may be obvious when you are writing it, but trust me, it won’t necessarily be so obvious later. This is even more important if someone else will eventually have to look at and understand your code. When writing the comments assume the reader has no understanding. I’ve been in this exact situation of having to debug someone else’s code with no comments and it’s no fun.
Also, make sure that the comments get updated if the function changes (also put your initials if multiple people are or have edited the code).