Hello and welcome to lecture number two. Here we'll see what is an assertion and what are the benefits. So assertion is simply a check. Some people may also call it a checker. But assertion is simply a check against the spec of your design. And you want to make sure that you have an assertion that tells you if the spec is violated.
So let's take a very simple example which will be much easier to grasp the concepts with, let's say a frame is DS are dead meaning it goes high. It's an active low signal that the last data phase is asserted meaning it goes low within two clocks. So here's clock number one, when the frame is detected to go high. Here's the first clock after which LDP is detected to go low, or it may go low after the second clock, either in it case, if it goes law to the first clock or the second clock that the assertion is supposed to pass. If not, if it doesn't assert within the two clocks, the assertion should fail. So I repeated the diagram here again.
Now let's see the first question that may come to someone's mind. You say, hey, I've been using very low for such a long time. Why can't I just use very long? Okay, this is how we write the code for this particular chair. There are many ways to write it, this is the preferred way that I would write it. Basically, you will have to fork off to procedural blocks within a fork join.
And when I throw up the block complaints, you will have to disable the entire begin END block. Now without going into too much detail of how exactly this code works, I just want to highlight that this is slightly complicated. code, there's a very good chance that if you don't put this condition correct negative LDP, or repeat to positives clogs, and if you prematurely disable the LDP check, there's a good chance you may get a false failure. And you don't want that. So there is a good chance that you will end up spending more time debugging your checker or your Verilog assertion compared to the design itself. Now let's look at how the systematic assertion code would look like.
And we are going to have plenty of detail. So for now, just accept it the way it is. So what we do is add pauses of clock, these are the clock at pauses of clock. If dollar rose frame that was frame rises goes from zero to one, that within the next two clocks one or two, that ellaby should fall. As you can see, this is very intuitive. very readable and very easy to develop, then you assert the property, and then you cover the property.
And again, we'll see what all these things mean. But the point I want to make sure is if I read this assertion, I know what I'm trying to check, you find it this very low code. Honestly, take me some time to figure out what is it that I'm even trying to do here. So assertions shorten time to develop this, that is a major benefit of very low assertions. Now let's see how does it help shorten the time to debug? Let's say this is your typical design, your higher flop state elements, then you have logic here, within which you have five flows, state machines and counters, and new up and well this isn't it's not good, so there's a good chance you have bugs everywhere.
You Apply the stimulus. You look at the response. And what do you normally do? Okay, the test fails. So you start debugging you keep going back, keep going back till you finally figure out that the FIFO overflow condition had violated. And finally, you will fix it, but it takes you a long time to simply go through this.
And that's what I mean by saying that. Basically, what we normally do is we do a blackbox verification, which is fine. But the observability is also black box, you don't know where things went wrong. Now, let's say you embed or you apply assertion around the Pfeiffer's around the state machine and around the counter. What that means is let's say you have this check or assertion which says, If I fall is full, you won't write anymore. If I for is empty, you won't read anymore.
So you write all these different kinds of assertions. around the state machines, for example, state machine, check code with a state three must go to state two and not vice versa. For example, state two cannot go to state three. So you have this assertions embedded. And now the test phase, when the test fails, one of these assertion is going to fire. And right away, you'll know Oh, it was a five volt flow condition that failed.
So you don't have your back trace like you normally do. So what that I call is blackbox verification with white box observability. So bottom line is it improves observability and thereby it reduces time to deliver. Now, how does it help you to determine if you have covered all the conditions that you were supposed to test? Even their system Verilog assertions come into picture so far? Example, we can cover FIFO state machines and counters just like the previous design and we can cover inputs, intra module intra block interfaces and chip IO interfaces.
What it does is at the temporal level for example, we say that five for overflow or five for four means you should not write. So, what we can do is cover that condition, meaning we will know that we did exercise a FIFO full condition and the assertion failed or did not fail these temporal domain conditions and we will see a lot more on that are essential to make sure that your test bench have indeed exercised the condition where you made sure the FIFO was full without such cover, you will not know For example, let's say an assertion fails, or an assertion never fires. fivefold meaning you should not write that assertion never fires. So you may think, Oh wow, my logic is good. Whenever there is a five of all i never write, not true. What if you never actually exercise the condition five for full?
Session has no clue. Nobody will tell you whether you even exercise that condition or not. So, basically, an objective measure to knowing how have you verified everything is done by the cover statement. There are many other advantages. For example, there's not a single design that is I can think of a single o'clock facade or multiple clock assertions help you with that, specifically, the CDC logic, clock domain crossing logic. The other thing with the assertions is that they can be parameterised So for example, I created a library with different kinds of assertions, but they are parameterize I won't hard code them just like a task or a function.
For that matter, you will write a an assertion for a 16 bit bus interface and then parameterize it so that the formal and actually you can change it to 32 bit bus interface. And very important point I want to mention here is the cleaner separation of RTL and dv logic. If I'm in management, I would never want to see any chord in the RTL design other than the code that is going to be synthesizable. So embedding assertions within RTL is very, you know, you'll end up with a spaghetti code. So what this SVG language allows you to do is you keep your assertions outside of RTL, and then you quote unquote, bind your RTL Designed with your assertions. And the other important advantage here is that this so called bind and bind is a keyword.
By the way, it works for both Verilog and VHDL. So you can have your entire RTL in VHDL. For that matter. You can write your assertions in very log. And then you can bind the Verilog assertions, system Verilog assertions with VHDL. This is a very powerful feature of the language.
Another thing you should note that assertions are always on. What that means is, let's say an assertion fires and then you actually fix it. You think you have fixed it, but the assertion is still active, just because you fix it. The assertion doesn't. assertion doesn't care. It's still active.
There's a good chance some other tests test number 100 Miss Steele, fire it and you will read realize your face was not good. All the assertions are always active. That means the more test you add, the more assertions may or may not fire until the end of the day, including you go from directed to constrained random random. assertions will fire if there's a bug. And also note that in recent days, the assertion synthesis has taken off, what that means is you write the assertions, they can be synthesizable they can be converted into gates. And then you can use this assertion which is quote unquote now part of the design if you can put that assertion into the acceleration box or the emulation box, and this is amazing because then, whenever an assertion fires within the emulation box, for example, you can write two different debug register and then you can for example, Andre scan it out, or ATPG scan out, and then you will know exactly where the design fail right now.
When you do emulation or acceleration, it is pure blackbox emulation we'll run into seconds for example, it will take you two hours to debug if something fails. But with synthesizable assertions, it is much much more easier and productive to work with emulation or exploration boxes. more advantages, the language allows global severity levels. So you can have a uniform error reporting structure. You can globally turn on or off assertions you don't have to have control over individual assertions. Just like you must be familiar with dump on dump off.
For example, doing you said Don't forget all the assertions. Once the reset is over, turn on all of them. The another advantage and you may or may not be familiar with static formal verification is that a formal verification is such that it will for a given cone of logic it fill up like all possible combinations of the input in both combinatorial as well as temporal domain. This is different from writing your own test which is exhaustive and what the assertions language allows you to do is it tells you that okay out of the 20 inputs assume that certain inputs will always be for example, one or zero. This is very useful for a static formal verification tool. Because when other problems with static formal verification is that that is something called a logic cone explosion problem.
There are 20 inputs, each one can be in any condition and in temporal domain they can each vary within the 10 to 20 clocks, there are so many combinations and for a formal to to verify all the combinations it may give up or it may take forever. So, the assertions language allows you with a construct called assume to reduce the scope of that going of logic and that way, your success of verifying a given for example, FIFO 's are prime candidates for formal verification. There are so many conditions exists around FIFO you write a test bench and there's a good chance you may miss verifying a particular given condition. Formal verification allows you to do that. And the next advantage is obviously, like I just said in this one language, you can assert You can cover for functional coverage and you can assume for either constrained random verification or for static formal verification this this one is to show what I just basically described.
So, you have the systematic assertions and within the assertions you have assumptions assume the key word we just saw this assume and the assertions go into apply to your duty and during formal you can go through the formal verification and there are new tools that also allow you to use static functional plus simulation. What that means is, again back to those 20 inputs, they are there are so many combinations. So, the hybrid does is it simulates a process or endpoint and knows the input values are some of the input values of those inputs and says okay, no need to Exercise these five inputs are 10 inputs. So there's hybrid and so basically assertions are applied on the formal side and assertions are also applied on obviously the simulation side, which is the simulation side is what we are going to discuss in this course. And then between these two you will exhaustively verify a given piece of logic or given sub block or the chip itself and then you will know whether the property passed or failed as a methodology guidelines on ABV So, things have changed recently where the agreement or disagreement on who should add the assertions is slowly thinning of it.
But I just want to make sure that the design engineers say hey, writing assertions is a verification engineers job you know they are verifying that design verification guy says oh Wait a minute, I don't have the knowledge of your microarchitecture. I don't have the knowledge of your interlock interfaces. So you need to write some assertions in that direction. So what's the answer? The answer is both of the design and verification engineers need to add the assertions, let me give some example. So design engineer will have to write micro architectural level decisions and assumptions, which are not visible to dB engineers.
Okay. One of the rule that I can impart on you, that you can take with yourself to your project meeting is that there are a lot of assumptions that design engineers make. If you assume that the request you're saying to the other block will always get an act into clogs. That's an assumption. So convert that assumption into an assertion. It will go a long way you will know right away if that particular spec is violated.
And keep doing so during your design process and don't write all the RTL and then say okay now let me add the assertions. So orders the DV design verification engineer does the design verification engineer, it basically says at a macro level because the DB engineer doesn't really need to know or should know for that matter micro architectural level detail. So, for example, the DB engineer would say once the packet has been processed for alpha layer, that it will indeed show up in the DMA queue so that it can be transmitted out on the voice queue. For example, the DMA engine doesn't care exactly what kind of Pfeiffer's the packets are being stored in and how the alpha layer processes it. This is a spec that sort should be met. For example, a machine check exception indeed sets the PC to exception handler address programmed in the exception register.
That's While you care, you don't care how the address is being you know, moved around to get to the PC. So this level of assertions are always added by the DB engineers. And DB engineers are also responsible for writing IO logic after a simple, very simple assertion, and believe me, this will go a long way if you apply after every set is d asserted, meaning Hey, let's go none of the signals should ever go to X. Right, this simple assertion for your project after the scores and you'll see the benefits right away, or for example, if the processor is invade mode, and no instructions are pending, that it must assert a sleep request to memory subsystem within 10 clocks. Or another example on critical interrupt the external clock and control logic must assert CPU wakeup within 10 clocks, we don't get a V meaning the design verification engineer doesn't care.
Exactly how the logic is implemented, but this is what should happen. So that's what the DB engineer does. And that's what the eyeball section shows what the design engineer does. Let's look at a case study. Let's let's look at a PCI. This is the parallel blah, bus, which is a predecessor of PCI Express.
And here's a simple protocol, you know the address and data bus, you have the command and byte enable bus, you have the initiator ready, you have the target ready and you have device select. And frame is what starts the whole bus. You I don't want you to go through this whole protocol because that's really not important at this time. What is important is given this particular protocol, what is it that the verification team will add? What kind of assertions they will write? So they will basically say right assertions like this for example, and this is the name of the assertion that I have come up with you should always give a meaningful name current assertion on the falling edge of frame ad and CB cannot be a no or when both Iranian t radio are asserted ad and CB commanded by byte enable cannot be unknown or when a frame can be DSL, this is a good one only if I ready is d asserted, and T ready can be asserted only if device elect is assertive, and so on and so forth.
So, these are what I call macro level or high level assertions that the verification team needs to write. What is the design team do so, the design team internal to the microarchitecture. There is for example, PCI state machine if it's in the address CBE state, the first clock edge when frame is found asserted asserted whenever frame is a Start at the PCs admission must be the address in each state that is their internal state machine assertion, which the DV engineer doesn't know or the PC state machine is in data transfer state only when both IRA D and T ready are asserted internal to the Alhaji they will not they should not start transferring data unless and until both IRA D and D ready are asserted and so on and so forth. So, do visit this slides again to see how or where a DVR engineer comes into picture and where a design engineer comes into picture.
So the next question is, okay, what type of assertions should we add? What what what is it just interface or what is it? RTL assertions, meaning what is your design intent? This is where again intra module design engineers come into picture. And what does RTL assertion mean? illegal state transition state cannot go from two to three.
It can only go from three to two deadlocks. We know deadlocks, you know, the state machines just locks dead. It just doesn't move. Live locks. Do you know what a live lock is? Live lock is when two state machines keep bouncing between two states.
They still are the simulation clock is still moving forward. It's like in a corridor there are two people one goes left, the other goes left to let the other one pass and the first guy goes right the other one goes right. So they are both moving. But they are not able to cross the path. That's a lifelong and similarly you have five boys one heart etc. Module interface assertions, inter module protocol verification illegal Combination a cannot be one if rec is zero steady state requirements when slave asserts right cue full master cannot assert right request.
So RTL assertions module interface assertions. The third one is functionality assertions, a preset transaction that results in a target retry will indeed end up in the retry queue. This is a dv engineers job where macro level or high level directly related to the spec, your writing assertion saying this must happen. And then, of course, the IO interface assertions. And here I just want to point out that there are a lot of commercially available standard bus assertions VIPs VIP sense for verification IP that can be used comprehensively to check for designs adherence to the standard protocols such as PCI ix PCIe x i is B, A and B etc. And finally, this is the one type of assertions that many engineers Miss.
Performance implication assertions I come from my background is pretty much from the processor design and the cache subsystem design. If I do not make sure during my design that the cache latency for read is less than supposed to be two blocks, but I don't make sure till halfway through the design, I'm in big trouble, because you cannot fix this particular type of a problem without major architectural changes. If you write a simple assertion, which says that hey latency I must get my data back within two clocks. Then it will go a long way because during the initial debug of the design, you will catch it similarly, for Network processor packet processing latency. If you don't have the correct latency for a wide kind of an SOC when the packets voice packets come in and you convert them to voice the voice will be broken because the latency is too high not acceptable.
So performance implication assertions is something many people miss and I would like you to make a note of it. Okay, how should we add assertions? Most important rule is do not duplicate RTL. If a is equal to b plus c do not write an assertion B says that a implies that v plus c equal to equal to a, it has no meaning because you're simply duplicating the RTL if RTL as a mistake. Well your assertion has a mistake. So the important thing is to capture the intent.
Intent can also be read as specification. For example, a write that follows a read To the same address in the request pipe will always be allowed to finish before read or after it depending on your specs. That is the intent of the design. Again, and I as I said before, and I cannot emphasize this more add assertions throughout the design process, do not wait and do not add them as an afterthought. If an assertion did not catch a failure, let's say you ran a test, and that has failed and none of the assertions fired. And then finally you go this wonderful blackbox observability debug process, go back and back and back and finally find where the bug is.
You should note that if I had put an assertion there, I would not have to go through this trouble. So this is another way to know how to add assertions that assertions. Sometimes you may miss If If the test fails and does not get an assertion doesn't fire, then you need to add new assertions. And like I said before, you know create libraries have common generic properties parameterize with formal arguments so that you can reuse them from project to project. That is also from XLR organization that is an open verification library. And you can actually use this directly it's available is free.
And the good news is this open verification library was initially written in very long with very long, cumbersome code that some really good engineers debug and made sure works. But now they have taken the same quote unquote checker or very low check and converted that into an SV language. So please go to They excellent Argh, download the OBL library. And right there, you'll see a lot of examples of how you can write in SVG assertion. It'll be a great boon to your productivity. Okay, I think we have covered the benefits and how to add the assertions and so on and so forth.
This these are the guidelines that you will need during your project execution. Please use them please revisit this lecture. Thank you so much, and I'll see you in the next lecture. Thank you.