A few weeks ago I attended the “10 Years of IEEE 1800™ SystemVerilog Celebration” lunch at an IEEE Standard Association symposium. One of the Verilog/SystemVerilog world’s luminaries sat next to me, and he started talking to other luminaries about how his son, as part of a general engineering degree, was using SystemVerilog.
I had to ask: “With more of a software background, what’s his reaction to SystemVerilog? It must seem like a godawful mess.”
He said, “He used those same words.”
Several months ago, I wondered whether SystemVerilog was the most complex computer language yet invented, and I found this page on StackOverflow. The number of keywords may not be the best metric of language complexity, but it is simple and easy to calculate. According to this answer, COBOL (the Common Business-Oriented Language invented in 1959) has 357. SystemVerilog has 323. C#, Microsoft’s answer to C++ and JAVA, is a distant third with 102. If this answer is complete, nothing competes with COBOL and SystemVerilog.
I didn’t even realize COBOL is still very much used, but in financial software, it is. Learn a little bit about it from Wikipedia, and you see that it is crammed full of miscellaneous features, such as report writing features. In the Criticism section of the Wikipedia page for COBOL, there is this line: “No academic computer scientists participated in the design of COBOL; all of those on the committee came from commerce or government.” All this sounds familiar, doesn’t it?
I understand how SystemVerilog came to be, as I was working on Mentor ModelSim/Questa at the time when we beat Synopsys VCS to the first commercial SystemVerilog release. It was Synopsys’ bid to replace “e“, and ModelSim’s bid to re-brand itself as a verification tool. Cadence followed. SystemVerilog is really a number of completely different languages in one.
Now working on the front-end of the toolset of a mid-tier EDA company, one of the few left these days, I have a different take on SystemVerilog. First, we mostly care about the synthesizable or design subset of the language. It’s not even clear what that is, and it keeps changing as the synthesis tools get updated, and I think may even be significantly different between ASICs and FPGAs (though I don’t as yet have any solid evidence for that observation.) While we are eternally grateful for the existence of Verific parser platforms as the bedrock of our front-end, we do our own netlist elaboration or construction later in the flow. That means we have to contend with the combinatoric complexities of the language: the many different ways in which features may be combined.
Having been previously aware of the test bench part of SystemVerilog, the design side of the language continues to surprise me. Do we really need elaborate regular-expression matching in case statements? Did you know that a use model of storing pre-compiled library elements on disk, which everyone knows is the traditional ModelSim compile model, is actually enshrined in the standard “for clarification purposes”? And what about interfaces? They don’t allow you to do anything you fundamentally couldn’t do before, but they do make the code more confusing by guaranteeing that you can no longer look at a module by itself and know what its I/O is. Now you have to look in four places: the module definition, the module instantiation, the interface definition, and the interface instantiation.
I have to spend a few moments on interfaces, as they came up during a hallway discussion at the IEEE symposium. An interface is a so-called “wire bundle”, an encapsulation of interconnect. Optionally, it may have modports, which can make some of the wires or variables inaccessible, or restrict them to read or write access. You can put modports in a generate statement, creating a sort of macro expansion of them. I defy anyone to point to anything in the LRM that describes how to use modports inside generates. Declare them, yes; use them, not really. In versions we had from last year, one simulator just generated a lot of errors, another said modports inside generates were not supported (the right answer, I think), and another bravely tried to implement them — except that I never could figure out how to connect them. Verific has perhaps the best answer, which is using a so-called generic interface reference, in other words, an interface connection that is bizarrely completely un-typed, allowing any kind of interface to be connected, as long as the names elaborate correctly. As language design, this is weird.
When I brought up interfaces, the hallway discussion covered more-or-less the following points. Isn’t an interface just a struct? They aren’t really useful. Virtual interfaces are useful. Interfaces would be useful if you could derive from them like a class. Does anyone really use interfaces? Bear in mind these are people who have served on the committee. I had to point out that the most popular synthesis tool partially supports them. We have at least two customers using them extensively. I was gratified that one of the SystemVerilog luminaries agreed that the LRM was “specification by example,” and he told of a very recent customer phone call discussing an error in the interfaces chapter.
You as a user can choose what to use in SystemVerilog; we as a vendor cannot. In some cases, for example the unique/priority keywords on ifs and cases, for which I implemented Ascent IIV formal checks last year, the language helps by standardizing something previously proprietary. In other cases, where the language offers new features for creating structure, it merely adds to the combinatoric complexity of building a design correctly. If there is innovation to be had in EDA, I have the feeling that won’t be where it lies. It will lie, perhaps, in something like the X-optimism and X-pessimism features of Real Intent Ascent XV — but the complexities of the front-end act as a tax on that effort.