Wednesday, May 22, 2013

Pre-processor directives in RTL. A Good Thing?

This post is specific to Verilog - I am certain everybody has seen something like the following code snippet:

`define DATA_WIDTH 16

module foobar (data);
  input [`DATA_WIDTH-1:0] data;

...

The question that will be explored in this missive is whether or not this coding style is a Good Thing.

At the outset, allow me to tell you my position on the matter - in my opinion, using pre-processor directives (`define) for signal widths is an extremely bad idea and should never be done, with no exceptions.  

I am certain this will appear counter-intuitive to pretty much everybody who writes modules in Verilog. In fact, I get plenty of rather angry reactions when I put forward this view. So let's explore the reasons why this coding style is a Bad Thing, shall we?

Reason 1: Code readability suffers. Usually people put all the `defines in one file, which is then `included in other RTL files. When you do a code review, unless you want to switch back and forth between the module file and the included file or you have exemplary memory, you'll find it annoying to read code snippets that assign some slice to some other slice such as:

  fooreg[`FOO:`BAR] <= barreg[`XYZ:`PQR];

What could have been as simple as

  fooreg[7:0] <= barreg[15:8];

is now something that requires quite some back-and-forth to review. You, the designer, may have no problem, but the reviewer definitely will. Imagine trying to review thousands of such lines - the fatigue alone could cause errors to slip through.

Reason 2: The wrong directive is used when multiple directives have the same value. If used incorrectly, inadvertent mistakes will arise when one directive is given a new value but the other isn't.

  `define ADATA_WIDTH 16
  `define BDATA_WIDTH 16

  input [`BDATA_WIDTH-1:0] adata; // `ADATA_WIDTH should have been
                                     used instead


will work fine until BDATA_WIDTH is re-defined for a new version of the chip, but ADATA_WIDTH stays the same. This is when things will fail subtly in simulations, and it will be monstrously hard to track down the error to an incorrectly used directive. This is simply because `define is a pre-processor directive - which means the simulator doesn't know anything about it - the Verilog pre-processor has already performed a string replacement.

Reason 3: The directive is defined but not used everywhere. Suppose DATA_WIDTH is defined and does exist, but somehow someone missed using it:

  `define DATA_WIDTH 16

  data[15:0] <= some_value[31:16];

Should DATA_WIDTH be redefined in the future, it will have absolutely no effect on the code - but everyone will expect it to. This will lead to subtle, difficult to track down bugs.

Reason 4: IP integration may have issues with multiply defined names. If you are integrating a third party IP block into your ASIC, you may well find that some directive in the IP conflicts with yours. Sadly, everybody likes using names like "DATA_WIDTH".

The nature of Verilog pre-processor directives is that the last defined value is what is held. Thus if you had:

  `define DATA_WIDTH 16
  `define DATA_WIDTH 32

the final value of DATA_WIDTH is going to be 32.

Suppose you had the first directive in a file called "a.v" and the second in "b.v"; then the file reading order will determine what the value of DATA_WIDTH is for that simulation run.

Thus, "verilog a.v b.v" will give different results from "verilog b.v a.v". Naturally, this situation is only compounded when an ASIC integrates multiple IPs from multiple vendors with multiple files containing directives.

You may argue that names could always be made distinct; but if you are integrating code from independent IP vendors this is not always going to be possible a priori. Thus you will have an additional time consuming step in your process, without which there is the possibility of chaos.

Further, making names unique will require you to add prefixes that identify which IP or module the name came from, making names even longer and less readable - such as `FOOCHIP_XIP_PCIE_WR_DATA_WIDTH. See Reason 1 - either the names are short but cryptic, or descriptive but long. Either way, code readability will suffer.

Reason 5: Multi-chip simulations may have issues with multiply defined names. I know, people always tell me - how often does this situation happen? I say you should be doing multi-chip sims as often as possible.

I can't recall how many times I've been told in the lab: "But this problem wasn't there in the previous version of the chip!" and I've setup a multi-chip sim with the old and the new versions of the chip and figured out the issue.

You can see how hard it would have been to do this if I had to worry about unique `defines - it would have slowed me down tremendously, either causing a schedule slip or untold stress, but most likely both.

Reason 6: `include file path portability suffers. Usually all `defines are collected together in a file which is then `included in other files.

This causes portability issues with the RTL database: you'd have to create locally modified copies of the RTL if you wanted to change the paths which goes against the grain of proper revision control.

To explain: if you have

  `include "/fsname/topdirname/chipname/somedir/foo.vh"

and you wanted to move over the design to a different filesystem, this path might not be valid. If you edited your local RTL to point to the correct directory, then it differs from what's in the revision control system - meaning it is an uncontrolled copy and might not represent the actual silicon.

Alternately, if you did:

  `include "../../somedir/foo.vh"

then you must implicitly assume that the directory where you run tests has a fixed and unchanging relationship with the directory in which the `included file resides. This may not always be true.

Once again, if you wanted to port your RTL to a different system where the directory structure is different, you'd have to modify RTL files, creating local file copies distinct from the revision control repository files.

Besides these reasons, there are other minor annoyances - such as when you have missing `defines, or when new `defines are created as expressions of other `defines, making it difficult to spot errors.

My take on this is that it is better to not use `defines in RTL, period; because they create more problems than they solve - and they create the worst type of problems - the ones that cause loss of productivity and momentum.

I do know that it will make RTL designers very uncomfortable to not use constant expressions and use hard coded numbers instead. There is always some loss of flexibility this way.

Far be it from me to take that flexibility away, however. What I mean to say is, there is a better way of doing things - (no, not parameters, which are definitely better) - but as usual, I'll leave it for a future missive.

Also, there is a real use for `defines - something that actually will enhance the design process and productivity, and we'll tackle that in a future post as well.

The point of this post is far too important to clutter up with other things - Don't use `defines or `includes in your RTL.

Saturday, May 4, 2013

What if you discovered a timing violation today, and tapeout were tomorrow?

Your humble author sometimes goes out looking for jobs - after all one has to have an income - such are the vagaries of life. In order to get a job, one has to go through a "process", endearingly called an interview. In reality, an interview is like a mating dance. The employer wants employees, and the employee wants an employer. Nothing productive can happen without either. It's much like mating is a necessary condition of existence - so is hiring.

So one has to go through the ritual, and dutifully, I went into one of those dances called a "telephonic screen" - something that sounds oddly like something you'd do on a 1-900 line. I suppose one has to develop a thick skin to go through with it and try to take it seriously.

So here is this author, trying to suppress either the urge to laugh or to scream, when he gets asked the question eponymous to the title of this post: "What if you discovered a timing violation today, and tapeout were tomorrow?"

Rather sadly but predictably enough, this didn't go well. I told the interviewer that in my entire career of eighteen years in electronics, this has happened not once. Not once. I do not expect it to happen ever. If it does, there are holes so big in my ASIC that you could fly A380s through them.

The point is simple but merits a detailed explanation, so great is its significance. You are trying to build an ASIC. It doesn't get built in three days, unless you think that writing RTL for a synchronous FIFO to be implemented in an FPGA constitutes ASIC design. It takes months.

In those months, you strategically plan every aspect of how the building process is going to unfold.  You do trial netlists  - you synthesize and do post-synthesis timing with plenty of margin every night. With a cron job. You track the RTL development and the timing results meticulously, reviewing violations carefully. You redo blocks where timing seems tight. If you have to meet a 1 ns clock, you synthesize for 600 ps. You try to meet 600 ps everywhere, not by playing synthesis tricks, but by having light and fast architectures.

The months roll on and you monitor the RTL carefully - and make it harder and harder for your people to change things as you come close to your RTL freeze deadlines. That way, your synthesis and simulations converge towards something that can go to tapeout.

Needless to say, your efforts of tracking tight paths in your design are to ensure that you won't be "discovering" new failing paths on the day before tapeout. Unless something is fundamentally broken somewhere.

Let's now work backwards from the day of the tapeout and try this analysis again.

So tapeout is tomorrow, and today you discovered a timing violation. What changed from yesterday? Why wasn't this timing violation discovered yesterday? Did RTL change yesterday? Did somebody mess up timing constraints and were those fixed yesterday and now this shows up failing paths? Were those constraints not reviewed thoroughly early on?

It is self evident that for you to not have known about this yesterday, you did not do your job properly. This is your error, even if it one of omission - something was lacking in your process - you weren't running a tight enough ship for something this gross to occur on the day before tapeout.

This may seem like a long and convoluted analysis, but it unflinchingly points to the culprit - an ill conceived process. Regrettably such is the state at a rather well known networking company. So without sugar coating it, I let the interviewer have it.

But even though it implies a whole lot, the question is still valid, and deserves an answer. What would I do if this happened. Hmm, lets see.

First, I'd take the rest of the day off, go home and sleep. If my process is so broken, then I don't have a choice but to delay tapeout for a month or three while I get a real good handle on things this time. Tapeout ain't gonna happen tomorrow, baby.

Second, I'd do a thorough failure analysis and do whatever it takes so it never happens again. 

Yes, that's right. I don't make umpteen-point plans. Fix what's broken and fix it well so it stays fixed.

I guess the interviewer was trying to find out the steps one would do if a timing violation were discovered after RTL freeze, like ECOs and the like. I could have gone that way, but the question was specific with the timeline. Tapeout tomorrow. Violation found today. This demanded a different answer, and perhaps the interviewer got more than he bargained for.

Needless to say, I didn't get the job. Makes one wonder - how does Moore's law continue to apply?

Sunday, January 20, 2013

Why?

If you think about it, there is really only one question worth the effort - and that is "Why?". As in, for instance, "Why is this blog, ostensibly about electronics - the zen and the art of it, specifically, talking about things like productivity and Dunning-Kruger?"

Well, the short answer is - "Wax on, wax off!"

And now for the long answer.

One of the points of this blog is to explore insights - insights that help understand better. If you think about it carefully, you will realize that every time you really mastered something, it was because of some insight - some tiny but invaluable piece of the puzzle - that caused a change in the state of your understanding of the subject.

This is almost like a state change in digital electronics - you went from a zero to a one in a very short time, and all that was needed was a triggering event. One hopes that this blog will provide you with triggering events which, zen-like, will take you to a deeper fundamental understanding of not only engineering, but how it all interconnects.

Alright, to kick off, here's an insight - look around you. Everything man-made thing you see in the physical world was was made by an engineer. In fact, one must put forward that the mere act of creating something is the very definition of engineering.

In the broadest sense of the term, even creating art - such as a painting - is also an act of engineering. The technical aspects - paint, brushes, canvas, the mixing of paints, the adhesion to the substrate - all these are obviously an application of a science and thus are engineering, but this is not what one means. The true act of engineering is the first spark of imagination in the mind of the creator when he conceives the picture. Think of everything else as "implementation details".

This is the "art" in the title of this blog. There is a little spark of an idea, a few key insights and voila! a new engineering masterpiece has the potential of being born. So who is capable of such high art in engineering? Surely such geniuses must be one in a billion or about six in the entire population?

Not at all.

One postulates that engineering is really a state of the mind, and not really a process or whatever else it is that one learns in engineering colleges. To use the informal language of the current time, it's like the zone that your mind must be in before you can learn the hows and whys. It's about the zone. And one strongly believes that anybody can be an engineer (hat tip to Chef Gusteau from the movie "Ratatouille" - "Anyone can cook!") - given the right nudges in the right directions.

The raison d'ĂȘtre of this blog is to get you into that zone. To do this one must take the "wax on, wax off" approach (hat tip Mr. Miyagi from the movie "The Karate Kid"). That is, one must talk and think about and discuss topics that seem at best peripheral, and at worst perhaps not even connected to electronics and engineering. After all, you can learn how to bias a bipolar junction transistor from any textbook - what is missing is all the peripheral stuff. The "why should I do that in the first place?" type discussion, or even better - "I want to do this, so should I bias the BJT like that?" and best of all, the "should I even use a BJT?" discussion. That's the missing element.

You can't make those choices until you have thought through the peripheral aspects of the device - something that no formal institution has the time, resources or inclination to teach. Thus we reach the sorry state of affairs wherein someone with an engineering degree is still too inexperienced to be put in a position of responsibility. He needs to be groomed, possibly by working with others more experienced than him, perhaps by fixing broken things, perhaps by advanced degrees - to be able to  use his knowledge to actually create something.

That almost sounds like being initiated into an art form - and it is understandable for even the smartest engineers to feel disheartened that they do not (yet) belong to that set of high artists. Despite this feeling, the truth is that people who create great things - the high artists - are no different than anyone else. 

As a matter of fact, you'd be surprised - well not so surprised if you've worked any length of time in the industry - that many astonishing creative achievements were made by people with little formal education. Some people may think that this is innate ability, or that this is luck, or that there is some intangible factor involved in all of this - but that isn't so. These people may not have had formal education, but they did not lack knowledge. They knew what they wanted to create - and they then went about acquiring enough knowledge to either create it - or to communicate clearly enough to others who had more specific and detailed knowledge.

In a manner of speaking they were already in the "zone", and while they may have lacked formal education, as they proved time and again, those were "implementation details" that they could acquire relatively easily and more or less on demand.

Another thing that is important to note is that often knowledge about something may not necessarily even be available - the theory of relativity is a monumental act of discovery, for instance - that did not exist in the superset of human knowledge prior to Einstein's publication. Thus it must be that the sum total of the prior knowledge of a discoverer or creator of something was of little consequence to that discovery other than to set the background. After all, knowledge that was known up until that time was available to all of Einstein's peers. What was it that Einstein had then, that allowed him to deduce his theory, but that others did not have?. What led Steve Jobs to conceptualize the iPhone but not others at Motorola or Nokia? Certainly it wasn't the availability or lack of knowledge.

Knowledge is relatively easy to acquire, especially if you know what you don't know. This was one of the conclusions of the Dunning-Kruger paper, remember? That's a key insight that one shouldn't lose sight of - know what you don't know. If you're thinking that this is a contradiction in terms - how could you possibly know what you don't - then you are beginning to see why one must take the Miyagi approach.

Extending the thought further, one realizes that formal educational institutions are in the business of providing education, if not knowledge - the implementation details, at best - and it is futile to expect them to provide the metacognitive ability to imagine and create. This is true of all institutions - regardless of what they might pretend to be; the conclusion follows simply from the understanding that life is a superset of an educational syllabus, not the other way around.

If you see that as a big, gaping hole, then this blog's purpose is self explanatory - it is to bridge that gap.

So please follow along - one hopes that we'll discover something (perhaps some things) together!

P.S. Please feel free to comment. Comments are moderated, but only to ensure relevance and decorum.