As you may recall, in addition to penning this column, I actually have a full-time job. This mostly involves writing "stuff" for high-tech clients (technical whitepapers, magazine articles, collateral and web-site content, ... the list goes on). I know that most engineers find the act of writing prose to be mind-numbingly boring, but I really enjoy it (go figure).
One big advantage associated with this writing is that I get to work with loads of different folks in a wide variety of companies, and they're all usually working on really cool technology. Even better, I often get to play with this technology long before it hits the streets. For example, two weeks ago as I pen these words, Novas Software Inc. announced their new behavior-based debugging system - Verdi - but I've been helping out with Verdi's tutorial and reference manuals and playing with the software since late 2001, so I'm well ahead of the curve on this one.
Despite a few limitations in its first release, Verdi is simply amazing. As far as I'm concerned it's Verification-TNG (the next generation). Verdi has more features and capabilities than I can wrap my brain around, but the coolest one is its ability to understand and extract the design's behavior from the source code and simulation results, and to then present a temporal view of this behavior in the form of register and statement flow graph views.
These unique views help you to understand unfamiliar portions of the design (say third-party-IP) much faster, to extract and display cause-and-effect relationships, to explore design behavior ("where did this value come from ... what will happen if I change this value ..."), and to more quickly detect, isolate, and resolve and problems. I'll explain this in more detail below, but first ...
Way back in the mists of time...
Sometime after the Jurassic period, when I was young and foolish and thought life was all jam donuts with lashings of whipped cream, integration between tools was somewhat less than optimal. In those days or yore, I was working with GenRad's HILO (later System HILO) simulation suite, which had amazingly sophisticated logic, dynamic timing, and fault simulation capabilities for the time. This predated Verilog and VHDL, of course, so I used a simple text editor to create simulation models in the GenRad Hardware Description Language (GHDL). Similarly, I also used a text editor to create testbenches using GenRad's Waveform Description Language (WDL).
As a side note, WDL had the ability to differentiate between assigning a stimulus value ("IN_A = 0") and specifying an expected response ("OUT_Y == 1"). Any strobe commands in the waveform caused the simulator to automatically compare the actual circuit responses with the expected responses and report any errors. I always thought that this was a really cool way to do things, and wish something similar had been implemented in today's HDLs, but we digress ....
As time moved on, graphical entry mechanisms like schematic capture systems arrived on the scene. And instead of using a text editor to view your simulation results as seemingly endless tables of 0s and 1s, graphical waveform displays appeared to delight and amuse us. In those seemingly far-off times, the integration between tools was ... well, non-existent really. So the type of integration presented by the suite of tools in Verdi brings a little tear to my eye.
Verdi's traditional views
Let's start off with the traditional views with which we are all familiar. Verdi provides all of the usual suspects, including source-code views, automatically generated schematic/logic diagram views, automatically extracted graphical state diagrams, and a waveform display with enough capabilities to make a grown man weep.
The level of integration between these various views is simply astounding. All you have to do is drag a block instance name from the source code view's hierarchy browser and drop it in the waveform display to immediately see all of that block's I/O signals. Similarly, double-clicking on a signal in the waveform view will locate and highlight its driver (at that simulation time) in the source code window.
You can drag-and-drop a signal from the source code view into a schematic view to generate a sub-schematic showing this signal's drivers and loads; you can drag-and-drop signals from schematics into the source code and waveform views; and the list goes on.
One really cool feature is Verdi's Active Annotation technology. When this is enabled, signal values are displayed in the source code, schematic, and state diagram views. Changing a simulation time in one of the views (say by clicking on a trace in the waveform display) automatically updates the annotated values in all of the views.
A portion of the source code window without Active Annotation...
...and with Active Annotation turned on.
Verdi's temporal views
The traditional views discussed above and the level of integration between them is amazingly cool. If I had had tools like this twenty years ago I would have been a hero in my own lunchtime (actually, I'd have been a man whose computer was totally underpowered for the task, but that's another story).
These days, however, we tend to take superb graphic views and high levels of integration for granted and expect them by default. For example, @Designer from @HDL also offers extremely powerful graphical debugging and design analysis capabilities in the form of source code views, an advanced simulation waveform viewer, logic cone views (similar to Verdi's schematic/logic diagram views), and so forth. Furthermore, @Designer also provides great integration across tools and includes high-end features like value annotation in the source code and logic cone views, etc.
So what makes Verdi stand proud in the crowd? Well, consider a small portion of a circuit - say the arithmetic/logic unit (ALU) from a simple microprocessor:
In this illustration, AluBuf is a register attached to the output of the ALU, ACC is the accumulator, TMP is a temporary register, and CWR represents the control word register. Let's assume that the testbench is expecting a hexadecimal value of $03 to be loaded into AluBuf at time 826 ns, but that it actually "sees" a value of $aa. How are we going to track down the source of this erroneous value?
We could use the source code, waveform, and schematic views to monitor the various signals feeding into and coming out of the ALU and to trace them back through time, but it's always difficult keeping track as to which signals are actively contributing to the final value at any particular time. Furthermore, in the case of something like the control word register, some of the bits may be acting in a control mode (specifying the instruction to be performed, for example), while others may be providing data (the carry-in signal to the ALU, for example).
This is where Verdi's unique temporal views come into play. You can select a node in the source code of waveform views (say AluBuf at time 826), and instruct Verdi to generate a register flow graph view that reflects the temporal activity of the circuit as shown below. Note that the previous diagram was just something I "threw" together - I cut things down for the sake of simplicity, so the following screenshot doesn't really map onto my diagram per se.
The key point here is that when Verdi originally compiles the source code, it uses internal synthesis and formal verification-type technologies to create a behavior database (BDB). Later, while generating a register flow graph, Verdi uses this behavior database and the simulation results to determine what the circuit is doing and how it's doing it. In the above example, I selected AluBuf at time 826 (shown in the upper right-hand corner) as the signal of interest. The horizontal dotted yellow line to the left of AluBuf represents the block of combinatorial logic linking four fan-in registers ACC, IDR, IXR, and PC (loaded at at time 800) to AluBuf, and the gray line linking these registers to CWR (loaded at time 775) indicates that CDW is also a fan-in-register, but is loaded at a different time.
The fact that the IXR and PC registers are gray at time 800 indicate that these are not actively contributing to the value in AluBuf at time 826 (a simple command can be used to disable the display of any non-active registers if required). By comparison, the pink "D" and "C" annotations on the other registers indicate that they are actively contributing data or control values, respectively (note that CWR has both "D" and "C" annotations at time 775, indicating that it is acting in both capacities).
The cunning thing is that you may see multiple instances of the same registers, because a register like ACC may contribute to an erroneous value in multiple ways at different times due to the feedback inherent in this sort of circuit. For example, ACC could have been loaded with a value that was subsequently incremented and then added to some other value, ultimately resulting in the erroneous value loaded into the AluBuf register.
Design exploration capabilities
In addition to register flow graph views as discussed above, you can also open statement flow graph views, which display the individual statements forming the combinatorial logic between register stages (these statement flow graph views also indicate which signals are contributing control and/or data).
Both the register and statement flow graph views are tremendously useful when it comes to understanding what a design is doing, but wait, there's more. These views also provide powerful design exploration capabilities. For example, you can load a new value into an "upstream" node and instruct Verdi to determine what the effects will be as this value propagates through the design and to display these effects in the flow graph views.
Alternatively, you can designate one or more "upstream" nodes as symbols and designate a "downstream" node as a target. Once you've specified a value you would like to achieve in the target node, Verdi will use its ability to assign values to the symbol nodes to determine which combinations of symbols will achieve the desired value. These exploration capabilities effectively allow you to perform local simulations "on-the-fly" and see the results almost instantaneously. Once you've decided exactly what you want to do, you can modify your original source code and/or testbench and re-simulate your design.
As far as I can tell, the capabilities offered by Verdi's flow graph views are unique at this time. @Designer from @HDL does provide a feature called an Expression Tree Viewer, which is somewhat similar to Verdi's statement flow graph (but not the register flow graph). To the best of my knowledge, however, this doesn't reflect which signals are contributing control or data, and it doesn't offer any design exploration capabilities. (I'll be going to DAC at the beginning of June, and will doubtless be beaten up by the folks at @HDL if I'm wrong [grin]).
As for any EDA tool, there are of course limitations to Verdi's capabilities. The new behavioral analysis and flow graph views work with synthesizable RTL only (they don't handle behavioral code or delay-dependent logic). The design exploration is limited to the local circuit being analyzed, which means that the effects of outputs from the local circuit that "wrap around" and feed back in again will be ignored. Also, using Verdi to determine which combinations of symbols will achieve the desired value in a target register is limited to a relatively small number of cycles and symbols. As for any formal technique, if you try to solve for too many variables or go back too far in time, evaluations can start to consume huge amounts of computational resources and/or way too much memory.
On the other hand, we're talking about the very first release of Verdi. I'm anticipating that most, if not all, of the above problems will be addressed as time moves on and its algorithms become more sophisticated. Even with its existing limitations, I see Verdi's flow graph views as being tremendously useful and a real productivity enhancer. These new techniques for understanding and exploring designs will go a long way to keeping debug times in check as designs continue to increase in complexity, all of which has to be worth an official "Cool Beans!" from me. Until next time, have a good one!
Clive (Max) Maxfield is president of Techbites Interactive, a marketing consultancy firm specializing in high-tech. Author of Bebop to the Boolean Boogie (An Unconventional Guide to Electronics) and co-author of EDA: Where Electronics Begins, Max was once referred to as a "semiconductor design expert" by someone famous who wasn't prompted, coerced, or remunerated in any way.