We’ve all been there before. We get handed a design that someone else did, most likely someone that’s no longer around, no longer accessible. Into our laps it falls, warts and all. Only, it’s hard to tell which behaviors in the design are warts and which are wants. It might have been C code (possibly the most broadly available means of obscuring intent ever devised), it might have been a PERL script (ok, also obscure, but attempted only by the cognoscenti), perhaps RTL, an Excel spreadsheet, or whatever. Bottom line, we’ve all asked the question, “What the hell does this mean?”
If we’re the ones generating code of some sort that will be passed down to those who follow in our inspired wake, we have been taught that there’s a very straightforward way we are expected to express our intent for those few instances where our meaning isn’t made manifestly obvious simply through the elegance, brilliance, and clarity of the code we’ve written: comments.
Hey, stop laughing, that wasn’t a joke.
Seriously, you’re supposed to comment your code heavily. Or else your project will be severely marked down. But for those of us no longer in school, well, there’s a couple problems. First, commenting is a pain. It’s annoying. It’s distracting. It keeps us from moving on to the next part of the project. And, frankly, it’s insulting. I mean, if you’re not smart enough to figure out what’s going on in my code, then maybe you should be doing something else.
And yet many of us knuckle under, cowed by the memory of nuns bruising those same knuckles as punishment for too few comments in our delicate formative years. And we write comments as we write code. Which means, we write some code and then we write a comment. And we’re done with it. With the comment that is. We’re not done with the code, and we make mod after mod as we discover that we’re not as good at coding with our eyes blindfolded as we thought. Meanwhile, the stalwart comment remains staunchly loyal to the original code that’s long since passed from this earth. It describes not what the new code does, but what some other mythical code once did. And therefore bears no remaining relevance to the problem at hand.
It may be useful for software archeologists to go back in and recreate the thought process of primitive man by tracing the comments, measuring the distance between the comment and the actual code, much as DNA distance is measured, and interpolating various missing links. But for the poor schlub that actually has to do something with the code later on, it’s of little value.
And there’s one more nuance: most such comments don’t necessarily describe the intended behavior; they describe what the code does. They explain why some innocuous-looking code does something completely different than what it looks like due to magical side effects that are inaccessible to mere mortals. The bigger picture is typically reserved for those “preamble” comment sections at the start of a file. You know, those ones that take a couple dozen paragraphs to lay out the intent and all of the corners and the history and all of that? What, you don’t write those?
OK, so let’s toss in one more limitation of comments: they’re useful only to humans. In fact, only to those humans who happen to have a facility in the language in which the comment was written. It’s impossible, even with today’s advances in natural language processing, for a computer to divine anything of interest from comments. So even with the best, clearest, most up-to-date comments, a person has to get in there to make sense of what’s going on.
For the RTL world, Jasper is trying to change that and provide a new way of capturing design intent and making it more broadly useful as the design gets passed down and passed around. They refer to it as “behavioral indexing,” and they tout its usefulness for current design verification as well as for design re-use down the line.
The idea is to identify and label key behaviors in a way that is machine-usable and that can be mathematically applied to the design to draw conclusions about how it works. As you might suspect, assertions and formal techniques play a role here. The methodology is pretty straightforward, in particular as applied to a design in progress. As you’re designing, you have some behavior in mind, and you write some code that you expect will cause that behavior (and no unintended behavior). You can then take that RTL – whether the design is complete or partial – and view the behavior you created as a waveform. Once the waveform is up, you can annotate the waveform to indicate cause/effect relationships and isolate those aspects that represent essential components of the design intent.
This annotation yields two results: some automatically-created assertions that capture a mathematical articulation of the behavior and a natural language description of what’s going on – just like a comment. Not only are you documenting in a more formal way what you’ve done, but you’re also confirming for yourself that the code you wrote does what you intended – thus eliminating bugs that others might have to track down later.
These behaviors are then indexed to the RTL and stored in a database. You can now “query” the database to see what happens in a variety of circumstances. The examples that Jasper illustrates are of the nature, “What happens if…?” This provides a means of exploring design corners and letting the underlying formal analysis techniques operate, thanks to the assertions created in the annotation process, giving you visibility into circumstances that might be harder to explore using such tools as simulation. These queries aren’t exactly the natural language questions you might pose to Jeeves, but they do open a new way to interrogate the design.
If you’re the poor dude who’s inheriting someone else’s crusty old design, you can go through the same process, only now you’re figuring out someone else’s intent. There’s no magic here that allows you to communicate with the ancestors for the answers, but the visualization and annotation process can make it easier to discern – and then note for posterity – what’s going on.
One of the other areas where Jasper sees this as being useful is for design re-use. When you pull an old design into a new one, it’s unlikely you’re going to use it exactly “as-is” unless it’s black-box IP that can’t be changed. You’re most likely going to make changes here and there to stitch it into the new context. So as you alter the design, all bets are off as to whether or not you’ve messed up some subtle important element of the intended behavior. If, on the other hand, the design has been previously indexed, you can make use of the assertions to see if any changes you made ended up undermining important aspects of the design. Any such problems can be fixed early on.
So does this relieve us of the burden of doing good design documentation? No, not really. It’s still a good idea to explain what’s going on in the code. And indexing the design still takes some work; it doesn’t happen completely invisibly, without intervention. But the promise is that you will actually benefit from the process yourself by allowing early validation of key behaviors, and that your annotations will be kept up to date when you change code, since the tool will be able to flag when older assertions no longer reflect the underlying code.