 We are going to begin a new topic today and this has to do something with what we have discussed last time and we did talk about specific languages which are used to program configurable devices. Now, I would like to add that hardware description languages are not merely the input languages of FPGAs and CPLDs and so on. They have a very wide scope. However, in this course, we shall be concerned only with that use of HTL. However, just to begin, we will see the more generic nature of hardware description languages in general. Before I begin with the overall discussion, I would like to just inform everyone that I have uploaded this file as well as the subsequent one that I will be using and I have also uploaded notes on the phase shift oscillator that we had discussed yesterday during the discussion session. I notice that Professor John has done the Vienn bridge oscillator and other op-amp applications today. So, I think together all of this should constitute a sufficient background for applications of op-amps and logic circuits. The other thing I would like to say is that many of the notes that we have been uploading are actually much more advanced than what would be justified for a basic electronic course. The whole idea is that we should train the teachers at several steps beyond what is expected by the students and then you can exercise your judgment and decide what is appropriate for the basic electronic course and you are welcome to use this material in many other courses like analog, digital or a course on VLSI design and so on and you are welcome to use this resource for those other courses as well. Let us come back, however, to the use of hardware description languages and let us place this in context of its use for electronic design in general. Now, I have an audience of 1300 teachers teaching basic electronics. So, it is a rather late stage to ask you on the ninth day of this course what is electronic design, but in general whenever I ask this question I get lots of perplexed looks. Well, we know roughly what is electronic design, but how do I tell what is electronic design? It is indeed not an easy question to answer and therefore, because we are not in an interactive class, I will just go ahead and give you what my answer is. Remember this is not necessarily a text book or an encyclopedia answer, other people may have other definitions for this topic, but this is what it looks like to me. So, what do we do in electronic, what is electronic design? Well, given specifications, we want to develop a circuit by connecting known electronic devices such that the circuit meets the given specifications. So, essentially where we start is a set of specifications. For example, you might be told give me a counter which counts from 0 through 9 and then goes back to 0, a decade counter. So, you start with a set of specifications such as they are. Now, as an electronic designer, you have developed familiarity with various components, you know what D flip flops are, you know what NAND gates are etcetera. The objective design is to understand the specifications and then select among the electronic devices known to you. So, it is very important that the designer knows various electronic devices. If you do not know about the microprocessor, then you will not implement a design using a microprocessor. Therefore, your skill depends on how many kinds of devices and by devices I do not only mean single devices. Known electronic modules and you should be able to put them together such that the behavior of the circuit that you so make is the same as the specifications. For example, you might know that D flip flops work in this way. If I and then I can take all the Q inputs and generate the D inputs from them using a Kano map and then the logic equation which comes I can implement using NAND gates, NOR gates and so on. All these are known electronic devices to me and then eventually I will have a synchronous decade counter which is what the specifications gave. So, the general act of electronic design is to do this. That is to say you begin with specifications and then you use your knowledge of the working of electronic devices and you put many of these devices together such that the circuit that you put together performs like the specifications. So, that to me is electronic design. However, this has now introduced some terms which are not well defined. First is what is specification? Well, they refer to the description of the desired behavior of the circuit. The specifications should tell me what to do. They should tell not they should not tell me how to do. So, for example, the specifications should tell me that I need a counter which counts which is a decade counter. Then it is my job to decide whether I will use D flip-flops or J K flip-flops or make it synchronous or asynchronous and so on. As long as I meet the specifications that is proper electronic design. So, the specifications are not required to tell me what components I should use. That is the designers job. The specifications simply describe the behavior of the final circuit, the desired behavior that is how I expect this circuit to behave. So, that takes care of specifications of what I really mean by specifications. The next was what are known electronic devices? So, known devices are those whose behavior can be modeled by known equations or algorithms with known values for parameters. So, for example, if there is a transistor whose properties I know it is a known device. If there is a D flip-flop whose propagation delay and types and pin outs and what have you is known to me and this device is available then this is a known device. So, in other words electronic design is in fact a process of converting a behavioral description which is specification and what is the behavioral description which describes in terms of what happens when. So, for example, I may describe an 8085 saying that if this bit pattern comes then it should do that. So, if such and such input is presented this is how it should affect this system. So, this what happens when is the behavioral description and I must translate this what happens when kind of description to a structural description. Structural description means what is connected to what and how. So, you take this and connect pin number 3 of this device to pin number 5 of that device and so on that is a structural description and these two should then be equivalent that means the behavior of a circuit structurally described should be the same as this behavioral description and then I have done electronic design. So, then we understand what is electronic design what is the problem. Well, the main challenge is that modern design has become very complex. The circuits have become extremely complex and now while very complex ICs are available poor me my brain is the same. So, I cannot cope with such complexity. So, if I have some circuit and which involves let us say 50 modules to be interconnected my brain cannot tackle this problem. Therefore, I need a tool which will allow me to think of this problem not as 50 modules, but may be 5 or 10. To give you an example if I ask you to design an 8085 then you will be initially quite confused. Therefore, the first step would be to break it down into 5 or 10 modules that there is an ALU that there is an instruction decoder that there is a bus interface unit that there is a register file. Once you have broken it down to these 5 or 10 modules. Now, you can think of 8085 as some structural description which will interconnect these modules. So, the idea is that the design has to be hierarchical. I must first design 8085 as an interconnection of these modules and then I must design each module as soon as I come to an ALU. Now, that is a tractable problem I know that it must add, it must be able to subtract, it must be able to shift, it must be able to do and or and invert etcetera and I can go ahead and design it. So, ALU is not such a big challenge. Similarly, the register file is not such a big challenge I know that there is register A register B register C each one of which must be 8 D type flip flop. So, I can go ahead and design it. So, the idea is that if I go hierarchically then what appears as a very challenging requirement becomes tractable. So, I must have design tools which in fact permit me to break up a more complex design into simpler design and that is how I can conquer complexity. So, the main challenge has been that there is too much complexity in design and the way to conquer this complexity is by divide and rule that means at one time you divide a given circuit to 5 or 10 elements and then design each element. If that element itself is too complex then divide that into 5 or 10 elements and so on till you finally, have things which are tractable then you design them. So, as a result the process of design is top down that means you are given the final specifications and then you keep on breaking it into smaller and smaller modules. The process of verification that the circuit that you have designed indeed does what it should that is bottom up because now you have designed in detail this circuit and you should be able to simulate this circuit from bottom up and then finally, the simulation should show that this circuit is doing exactly what the user wanted to do. So, we have this combination of bottom up and top down design which should combine to give you a guaranteed circuit whose behavior is indeed what the user wanted us to do and most hardware description languages indeed meet this challenge they help us to meet this challenge. Now, this particular tutorial is actually very long and obviously, we do not have time to go through this what I however, I believe that it is self explanatory and if you just go through these slides which I have uploaded on Moodle also and it is being used on a view right here then you will be able to go through most of it on your own. So, what I am going to do now for the next may be 15 minutes or so is to go through only the juicy bits of this tutorial and discuss only what needs a little bit of discussion. So, I am going to skip fair parts of this which are somewhat general and which are somewhat abstract, but you can in fact read through that. So, I am not going to describe all of this stuff to you. Now, let us go to therefore, some basic HDL concepts these concepts are important let us develop these concepts and then we will be able to understand how hardware description languages work. Hardware description languages are actually the languages themselves are actually some computer programs. So, they have the limitations of a computer program on the other hand what they are attempting to do is to act like hardware and most of these concepts permit us to develop the concept which will allow us to use a computer program which helps us to design hardware and also to simulate the hardware. So, the first concept has to do with timing the design of any hardware is very sensitive to timing. If the timing is not right it may do what we want, but if it does not do it in right time then this is not a working circuit. The other problem is which is not faced by computer programs normally is that of concurrency that means different modules of this hardware are acting at the same time. In a program only one line is being executed at a time and other lines will follow. So, they are only sequential not concurrent. On the other hand in case of hardware each module is capable of reacting and therefore, it is the collection of these modules how they interact at the same instant which has to be analyzed and therefore, we require a thorough understanding of how we handle concurrency. The hardware simulation process then involves the following. You have described the hardware using some hardware description language and now these three steps which are discrete and must be well understood follow. First you must do an analysis of the description. So, you have described the hardware in a particular way. It has to be parsed it has to be seen that its grammar is correct it is not ambiguous. So, first this description is analyzed to see that it indeed is it makes sense to the HDR. The second part is elaboration because the design is done in the top down fashion that I described earlier. You might have described for example, an 8085 using a register file and an ALU. So, then first the 8085 design is elaborated as a connection of a register file and ALU a bus unit and so on. But that is not where we stop. Then I must go and elaborate this ALU as an adder as a shifter as a group of logic gates and so on and then I must elaborate the adder. So, this elaboration will continue till I have described the whole circuit in terms of the simplest possible elements whose behavior can be taken for granted. So, this elaboration is done before the simulation can begin and during this process a lot of data structures that we will see later which are important are also built up. So, while we elaborate this circuit we also build up those device structures. For example, it is important to know which digital signals can affect the behavior of this particular circuit. That means to what events is this particular circuit sensitive and that will become apparent as you elaborate because you know at that time what is being connected to what and that data structure is built up while you do elaboration. And finally, once you have done analysis and elaboration using models for the simplest devices you can proceed in time and carry out the simulation. Now, the simulation itself proceeds into distinct phases. First phase is signal update some signal has been waiting to acquire a particular value you update the value of that signal saying all right this signal was earlier 0 now make it 1. So, that is called signal update. When signals are updated you find out which signals have changed if a signal has not changed then what is connected to it need not be resimulated. But if a signal has changed then you say that an event has occurred on this signal and find out who cares if an event has occurred on this signal that is the data structure that we had created during the elaboration phase. So, now we have a list of hardware which is affected by this change then we go ahead and resimulate only those modules which are affected by this change. So, as a result of resimulation what will happen is that this resimulation will say all right earlier my output was 1, but now that my input has changed my output should become 0. So, that will place certain transactions certain orders which will go and wait in a time ordered list and when that time arrives we will do signal update again then do selective resimulation then do signal update and so on in a loop unless all the time has passed and either the time for which one we want to simulate is over or there are no events left which can cause any changes. So, the simulation process is essentially an infinite loop of this you update the signal the first update will be because of the inputs that you have provided initially all signals are unknown when you provide an input the signals have to acquire the input right. So, that is the first update this update will result in a change of value whichever signal has changed its value you now find out who is affected by it and then you go and run the simulation for only those devices or only those modules these modules will then change their output. So, they will say all right my previous output was like this, but my current output should now become this because my input has changed. So, you make a time ordered list of when those changes are to be affected and then you go linearly in time picking up one after the other updating the signals and analyzing the impact of that update. So, that is how the simulation proceeds and this is how a basic HDL is going to work. So, let us look at a few examples we do not have time to go through everything, but I think a few concepts are important and I will just take on take on only a few keeping a very close eye on the time as it goes because we are talking of timing. So, I should not spend too much time on concepts only and never use those concepts. So, let us first of all look at delays. Now, let us look at delay only from an abstract view take an example and say that delay of 30 microsecond is required. So, what is this delay I have an input and I have an output and what I am saying is that my output should be the same as the input, but after 30 microsecond that is what we mean. So, an informal way in fact, this is how it would be put in a language called VHDL. I am saying assign to output the value of input, but after 30 microsecond. So, this is our concept of delay the question is this description unambiguous. It appears to be unambiguous it appears to make sense, but it turns out that it is not always unambiguous. So, let us that is somewhat surprising let us see why it is ambiguous. So, how will we implement this delay this is one way of implementing this delay. Notice that now we have analog as well as digital operation. We have an RC circuit whose values have been so chosen that it causes a delay of about 30 microsecond and then because this value has now become analog through this integrator. I put a buffer which will convert this analog value back to digital. Essentially, this is a thresholding circuit at node x the value as you can see here is analog and this circuit does thresholding. When the analog value exceeds a particular threshold then it makes it output equal to 1 whenever it is below it keeps its output equal to 0. So, that the input is digital and so is the output. So, let us analyze this way of causing a delay. This is the obvious way that we will go and cause the delay. Now, assume that I apply an input to this delay circuit and here just for the sake of illustration we have two pulses. One is much narrower than the amount of delay. The other is much wider than the amount of delay and let us see what happens. Now, notice this diagram is not accurate it is stylized, but it illustrates what we mean. When the first pulse comes it starts integrating and therefore, we get a ramp. In reality it will be exponential curves as you know the charge discharge curve of a capacitor. However, it has gone only a little way charging up when this pulse comes down. Now, because this pulses come down this point is now connected to ground and whatever charge we have put on this capacitor whatever little charge that now starts discharging through this resistor. As a result the output now starts coming down before it has reached any considerable level. In the second case the charging continues for a long time till the pulse ends and it reaches the maximum value. Then when the pulse comes down as expected it discharged. So, essentially the slope of this charge is determined by the r c value by the time constant, but in this case because the time was very short with the same slope I was not able to reach any considerable value, but in this case because the time was long I am able to reach the top value and then I come down. So, that is what happens at this node x because I now do thresholding on this. If the value of this is below some threshold which might be here my output is 0 and when I go above that threshold my output will become 1. Now, notice that this particular blip always remains below that threshold and this narrow pulse therefore, has disappeared from the output. So, the delay is appropriate this delay might be 30 microsecond because I have chosen the r c to produce this delay. My output is a delayed version, but in this delayed version this very narrow pulse has actually vanished because of the delay. So, this is one way of delaying things. However, this is not the only way here is another thought experiment. I have an input and a black box which converts this electrical input to a light pulse. Now, I have a long optical fiber. So, this light pulse travels through this optical fiber and at the output I have some electronic circuit which takes this light and converts it back to digital. I apply the same input to this circuit and I have calculated the length of this optical fiber. So, that the delay is exactly 30 microsecond. Therefore, this is also an implementation of a 30 microsecond delay, but in this case there will be a 30 microsecond delay, but both the narrow pulse and the white pulse will arrive. So, therefore, while specifying that I want a 30 microsecond delay, I did not specify whether I want this kind of delay in which the narrow pulse vanishes or this kind of delay in which the narrow pulse remains. Therefore, if I have described the delay in the simple minded way that I had, somebody might implement it in one way, somebody else might implement it in the other way and the behavior of the resulting circuit will be different. In one case the narrow pulse vanishes, in the other case it does not. It turns out that the previous delay which makes the narrow pulse in fact vanish is the much more common way of delays in electrical circuits. Therefore, I must be aware of this and I must use terminology which makes a distinction between this kind of delay and the other kind of delay. So, this kind of delay by the way is called inertial delay in which there is inertia and if you suddenly change direction because of the inertia that pulse vanished. The other kind of delay is called transport delay which is caused by transporting of a signal say through an optical fiber. So, in short the delay in which narrower pulses vanish is called inertial delay and in which they do not is called transport delay. Now, while describing a circuit you must ideally specify which kind of delay you want and how much delay you want otherwise your specification is not complete. So, you must say that I want an inertial delay of 30 microseconds or a transport delay of 30 microseconds both must be specified. However, while designing circuit it is just too painful to keep describing it all the time. So, therefore, hardware description languages have a default if you do not specify the type or the amount of delay in that case this default value will be used. So, therefore, if you do not specify the kind of delay then the delays are taken to be inertial the RC kind of delay because that is the much more common kind of delay. And the amount of delay is taken to be 0 it is assumed that if you have not specified the amount of delay then you do not care about the delay and this and a routine 0 delay will be assumed. Now, essentially when you simulate some block what happens is that it results in an output change that means you want to assign a new value to a signal. However, real signals do not change in 0 time it takes some time to charge a capacitor to discharge a capacitor and so on. So, therefore, real capacitors must be done after a delay. So, how do we manage it in a program? So, in a program rather than changing the value of the variable right away you put it in a queue and say you also put a time value and say that this signal must be changed only when this time arrives. Such a queue is called a transaction it is almost like a business transaction in which you place an order and you are told that your laptop will arrive in one week. So, you place an order for a laptop this is the transaction you pay the money and then you are told that the laptop does not arrive in 0 time it will take a week for it to arrive. So, such a thing in commercial terms is called a transaction and that term has been adopted in VHDL and other hardware description languages. So, essentially when you resimulate you do not forcibly change the value of a variable directly you actually put it in a queue and this action is called a transaction. That means, you have determined what value must be assigned to a variable, but you do not assign that value immediately you put it in a queue and that value will be assigned when the time is right. So, this kind of updating of a variable is called a transaction. Now, if you recall we had said that if you do not specify the amount of delay in that case the amount of delay will be taken to be 0, but on the other hand here I am arguing that the delay cannot be 0. The delay must be finite the real thing is that you do not know and you do not care how much delay there is. So, you understand that there will be delay, but you are not particular about how much delay there will be and it you just want this to be some small delay and just cannot bother cannot be bothered to specify it. However, this simulation needs to know some amount of delay. So, when a 0 delay is specified what the hardware description language language does is that it assumes that it is not the 0 you know that it should not be 0 you are just being lazy and therefore, it assigns a delta delay and before presenting the results. So, it treats as if delta is a very small delay and schedules things after that delta delay. However, when it presents the results to you it takes the limit and puts the delta to 0. That means it takes the limit putting delta equal to 0 because that is what you have specified a 0 delay, but for internal use it must specify the physical system which cannot have 0 delay. Therefore, it assumes a delta delay and eventually while presenting the results takes the limit of delta going to 0. So, why go through all this song and dance of first taking a non-zero delta and then taking the limit as delta goes to 0. The answer is that hardware is very sensitive to the order in which inputs arrive. For example, if you had a flip flop with a set and a reset input if the set comes first and reset comes later it will finally be 0. On the other hand if a reset comes first and the set comes later then its value will be 1. So, the behavior of the hardware can be very sensitive to the order in which the inputs arrive and therefore, events occurring at sometime t at t plus delta and t plus 2 delta are all internally treated as if they occurred in this time sequence before and after. However, once the result has been computed then you put the value of delta equal to 0. That means results are reported as having occurred at t, but are internally time ordered as if delta were non-zero. So, you take some this is some epsilon kind of time which is internally assumed and you use this internally assumed time to do the sequencing of which input arrived first and which input arrived later and having calculated the output according to this sequence eventually put delta equal to 0. So, this is the concept of delta delay this is how we handle 0 delay. The other concept was concurrency this is something which is new and not known to a program a program executes an instruction at a time whereas, now we have to handle concurrency. So, because many things happen can happen at the same time and we can efficiently handle only one thing at a time we have to develop a special procedure. So, that we can describe concurrency. So, now time is not really the time as it passes during the run of the program. We detach ourselves from time and time is in fact a global variable in this program and it advances the time advances only when we arrive a new value to this variable. So, in real life computation is taking time and time is passing, but this simulation time is held fixed because this that variable called time has not changed. So, therefore the circuit time is different from the actual time the circuit time is tracked by a global variable. It may take you a long time to simulate a circuit, but it does not matter the time that it takes to compute the output does not matter because this time variable is held fixed at a particular time and when you are ready with the computation and this value is to be assigned at a later time only then you advance the value of the time. So, therefore things which happen simultaneously are handled actually one after the other, but you keep the time value the same and therefore these things will have the effect of being simultaneously. Because the time variable has not advanced it does not matter how long it took you to compute the effect of one thing and the other the you have computed them one after the other, but the effect will take place at the same time when the time variable is advanced and this is how we handle concurrent things. And as I had said before the simulation actually proceeds in three steps first is the syntax and other analysis that the description makes sense then elaboration in which you flatten the hierarchy and create data structures or create sensitivity list and finally carry out the simulation. Details of this are there in this lecture and again I am going to take a jump and rather than sort of tearing around showing you every single transparency in this what we will do then is to go to an example which illustrates the effect of this whole thing. So, the circuit that I have chosen is this circuit many of you would be familiar with this you know that this is the circuit which produces a glitch at the output. So, let us see whether we can correctly create that glitch as would be created by real hardware if you want to do a zero time only a logic analysis of this then you will find that whenever a is one b is zero because of this inverter and whenever a is zero b is one as a result at least one of the input is zero and therefore the output is the output is always one. Therefore, we do not expect any change at the output either a is zero or b is zero if a is one b is zero if a is zero then a is zero. So, therefore, at least one of the inputs is zero therefore, the output must be one, but because there is a delay here when a becomes one b when a becomes zero a just becomes one then b has not yet become zero. So, assume that a has this zero to one transition a has already become one, but it will take some time for b to become one and therefore, because of this become zero and therefore, for some time both will be one and the output will become zero and it is that which creates this glitch. So, this is the circuit and let us see how a hardware description language in fact will analyze this circuit. Now, first of all we must do what the elaboration part of this will do. So, for example, look at this module this what does this module do it inverts its input and its delay here is given as 8 units of time this unit of time could be anything nanoseconds microseconds 0.1 microseconds whatever you want. So, this inverter produces an output which is the inverse of a, but the inverse appears after 8 units of time. The NAND produces according to the NAND table an output of a and b however, its output appears 6 units of time later, but now let us see what the data structures will be built up during elaboration. We want when we place these units during elaboration we will also note what are the sensitive to. For example, the inverter is sensitive to a only if a changes then I must resimulate the inverter on the other hand the NAND is sensitive to a as well as to b should either of them change then a new value for this output needs to be evaluated. Therefore, the sensitivity list says that any event on a I must resimulate the inverter as well as NAND as both of them are sensitive to a and any event on b I must resimulate only the NAND and nobody is sensitive to c it is my output nobody is connected to c. So, we have only three signals here a here b here c here both the units are sensitive to a only this unit is sensitive to b and nobody is sensitive to c. Now, this input is described to the language as an initial transaction list which is the initial time ordered list what does it say it says at time equal to 0 make a equal to 0 that is this then nothing happens till a time of 20 units arrives and then this says that at time equal to 20 make a equal to 1. So, then time will become 1 at 20 then at time equal to then nothing happens and only at time equal to 50 make it back to 0 and then nothing will happen right. So, at 50 make a equal to 0. So, therefore, we have these three transactions waiting on a when we begin the input has been described essentially by putting these three transactions in the queue we have a transaction at 0 itself saying make a equal to 0 we have a transaction at time equal to 20 saying make a equal to 1 and we have a transaction at 50 saying make a equal to 0. Now, let us see how we proceed what we do is that we always advance our time variable to the next lowest value at which something needs to be done. So, what was the lowest time at which something happened that was time equal to 0 and what happened at that time a was made 0. So, we advance the time to 0 and indeed make a equal to 0. Now, these are my three variables a b and c initially their values are all unknown marked as x here what has happened at 0 a has become 0 whose value has changed value of a has changed. Therefore, we say that a has had an event if a changes who is sensitive to a well both the inverter and the NAND are sensitive to a because a has changed I must calculate new values at the outputs of the inverter as well as the NAND. So, this is my initial transaction list I have arrived at time equal to 0 and I have made a equal to 0 I have noticed that because of that a has an event and therefore, I must reevaluate both the inverter and the NAND when I evaluate the inverter what does it say it says oh my input has become 0 now what is the current time. So, you tell him the current time is 0. So, then it says please make my output equal to 1, but at time equal to 8 because the delay of this inverter is 8. So, it says that I notice that my input has become 0 and therefore, please make b 1, but at time equal to 8. So, I insert this transaction into the transaction list that at time equal to 8 please make b equal to 1 that is about the inverter, but the NAND is also sensitive to a. So, I go to Mr NAND and say sir your a just became 0 what say you now if this input has become 0 this NAND does not care what the other input is its output goes to 1. So, the NAND says please make c equal to 1 but because its delay is 6 it says what is the current time by the way. So, you say the current time is 0 when a became 0. So, he says all right if a has become 0 make my output equal to 1, but please do it at 6 units of time because that is my delay. So, therefore, the NAND says please make c 1 at time equal to 6. So, we insert this also into our time ordered list notice that this is in increasing order of time. So, we insert at 6 the request that c should be made equal to 1. Now, we have analyzed all effects of a having become 0. So, we take that out. So, we cross out this and insert these 2 in time order retaining these remain as they are and this is our new time ordered transaction list and now we are done with whatever needed to be done at t equal to 0. What is the lowest time in our time ordered list now? It is 6. So, we advance the time variable to 6 because nothing is happening in between and arrive at this action at 6. Now, this is our transaction table and what is to happen at 6? I have to make c equal to 1. So, now I assign to c the value 1 notice that the value to c was known at 0, but was not assigned immediately. It was placed in a queue and it is now being assigned at t equal to 6. So, at 6 what has happened? c which was earlier x has now become 1. Therefore, c has had an event. So, we go around saying who cares if c has changed and the answer is nobody cares if c has changed. Nobody is sensitive to c. c is just an output. So, therefore, what do we do? We simply make c equal to 1 and no reevaluation is required. Nobody is sensitive to c. So, we just make c equal to 1 and then cross out this transaction. So, in our final transaction the remaining three are left and this transaction is now crossed out because whatever it says has in fact happened. Now, what is the lowest time at which the next action is to be taken? That is 8. So, we advance the time variable and give it the value 8. So, now the time has become from 6 it has become 8. What happens at 8? At 8 we have to make b equal to 1. So, b was unknown earlier it now becomes 1. Its value has changed. So, b has had an event. So, we go around asking who cares that b value has changed. The inverter does not care. Its behavior does not depend on b. The NAND does. So, we go to b and say sir b has just become 1. So, the NAND says what is the current time? So, we inform him that the current time is 8. So, the NAND adds its delay to 8 which is 6 and says please make my output 1 at 8 plus 6 equal to 14 because a is 1, a is 0 and b has become 1. If a is 0 the fact that b equal to 1 does not have any effect, but I still place a transaction saying please make c equal to 1 at 14. Notice that c is already 1. It does not matter. I will still place this transaction. Who knows what might happen between 8 and 14? Therefore, I must keep that transaction. So, when I go to the NAND is the only thing which is sensitive to b. When I go to NAND it says please make c equal to 1 depending on its current inputs namely 0 and 1, but at 14 because current time is 8 add my delay equal to 6 to 8 and at 14 makes c equal to 1. So, we insert this instruction at time equal to 14 and take out this instruction because whatever b has been made 1 and there are no other consequences of this. So, now what is the lowest time? The lowest time is 14. So, we make the time variable equal to 14 and what happens at 14? We have to make c equal to 1 that was the transaction at 14 makes c equal to 1. So, what do we do? We assign 1 to c, but c was already 1 that means there is no event. Therefore, nobody cares that c should become 1 at 14 because it was already 1 at 14 and whatever was to happen with that has already happened. So, therefore, all we do is just remove this transaction. Now, I have only 2 transactions left 1 at 20 and 1 at 15. So, I advance the time variable to 20 and what is waiting to occur at 20 that a should become 1 this is in fact this transaction. Notice that I am building up the output waveform on the right hand side of this diagram. So, a became 0 at that time there was no action b remained x c remained x at 6 c became 1 at 8 b became 0 and now at 20 we have at 14 c became 1, but it was already 1 and at 20 now a has a transaction from 0 to 1. So, a was earlier 0 now it is 1. So, a has had any event who cares well the inverter cares what happens to a and the NAND depends on what happens to a. Therefore, we must go to both and ask them saying a just became 1 what do you do? So, we go to the inverter and say the current time is 20 and a has just become 1. What does the inverter say? Inverter says the current time is 20 and a is 1 then please make b equal to 0 at 28 because it is delay is 8 current time is 20. So, therefore, at 28 if the input is 1 I am an inverter make my output 0. So, please make b equal to 0 at 28 and what does the NAND say? Notice b is b is resting at 1 and now a has also become 1. So, we go to the NAND and tell him sir the current time is 20 and both your inputs have become 1 what do you say? So, this guy says I am NAND if both my inputs are 1 then my output should be 0, but please do it at 26 because the current time is 20 and my delay is 6. So, therefore, we insert these 2 transactions into our transaction queue and as before we insert them in time order. So, I say at 26 makes c equal to 0 at 28 make b equal to 0. Now, what is the lowest time in our time ordered queue at 26? So, I advance the time variable to the value 26 and arrive at this event at 26 what is waiting to happen at 26 c should become 0. So, c which was 1 earlier now becomes 0 notice in the timing diagram c which was 1 is now becoming 0 at 20. This should actually be drawn at 26 sorry at 26 c has become 0. So, at 26 c has this 1 to 0 transaction c value has changed. So, we ask who cares? Well nobody cares c is not anybody's input. So, we just make c equal to 0 and we done with it. So, that is what we do we assign 0 to c and take out this transaction we are now left with these 2 transactions at 28 and at 50. What is the lowest time in our time ordered queue 28? So, what we do is that assign 28 to the time variable and come and make b equal to 0. So, that is what we will do at time equal to 28. So, now we have arrived at 28 the transaction waiting to happen is that b should become 0. So, at 28 we make b equal to 0 notice that b has had a change of value b has had an event. So, b has an event. So, we say who cares if b has changed now only the nand cares that b has changed. So, we go to the nand and we tell him the current time is 28 and b just became 0. So, the nand says b became 0 then my output must be 1 because if either input or both inputs are 0 then nand must go to 1. So, it says if b has become 0 make me 1, but make me 1 at 34 units of time because the current value of time is 28 and my delay is 6. So, at 28 plus 6 equal to 34 please make my output equal to 1. So, we insert this transaction into our time order queue saying remember to make c equal to 1 at 34 and then that is it only 1 thing was sensitive to b. We now advance the time to 34 as we have been doing before and to the lowest value and arrive at t equal to 34. What happens at 34 c becomes 1 because c became 1 c has an event it was earlier 0 it has now become 1, but nobody is sensitive to c. So, all we do is we make c equal to 1 and just proceed. So, our c as you can see here has become 1 at what at 34 c has become 1 at 34 c has become 1 and that is it no other change. So, now we go to the next value in our time order queue the only entry left is at 50. So, we advance the value of time equal to 50 and then make a equal to 0. So, which is what we do at t equal to 50. So, what is the waiting transaction make a equal to 0? So, at 50 we make a equal to 0 it is this transition. Now, a was 1 earlier it has now become 0 therefore, a has had an event and who cares if a has changed well both the inverter and the NAND have to reevaluate their output if a changes because it is an input to this and it is an input to the NAND as well. So, we must go both to the inverter and to the NAND at 50. So, we go to the inverter and say the current time is 50 and a just became 0. So, the inverter says in that case make b equal to 1, but do it at 58 because the current time is 50 and my delay is 8. So, therefore we place a transaction at 58 for b becoming 1 the NAND says o a became 0 then my output should be 1 irrespective of what b is doing. And it places a transaction current time is 50 it adds its delay 6 to it and places a transaction at 56 saying please make c equal to 1 at 56. So, we insert these two transactions at that time and take off the transaction for 50. So, now we have two transactions left at 56 make c equal to 1 at 58 make b equal to 1. We again advance to the lowest available time which is 56 and do the next thing. So, at 56 what do we need to do? We need to make c equal to 1 c is already 1. So, nobody cares we just keep c at 1 and do nothing more and advance to the next time which is 58. What is waiting to happen at 58? b is to become 1. So, at 58 b is to become 1 who cares well only the NAND cares for b. So, we go and tell NAND look b just became 1, but a is 0 and remains 0 therefore, its output remains 1. So, the NAND says please make my output 1 the current time is 58 please add my delay 6 and remember to make c equal to 1 at 64. Now, this is the only transaction left. So, we advance the time to 64 and make c equal to 1, but what happens then? Nobody cares c was already 1 it has become 1 time has arrived at 64, but nothing has happened and now we have no transactions left nothing to do. We have finished our simulation and this is the waveform that we have produced and indeed now we are able to predict that the output will have a glitch of this size at this time. So, we have correctly simulated this hardware. This example specifies how we handle time and how we handle events and transactions and how the simulation actually receives. Now, up to now we have not made use of the fact that there could have been two kinds of delay indeed depending on the type of the delay this treatment actually changes a little. Now, unfortunately I do not think we will have enough time to go through this example, but since we have gone very thoroughly through the previous example in this lecture there is one more example which illustrates what to do for inertial delay and what to do for transport delay. So, please go through this part in your final output and it will essentially appropriately simulate the two kinds of delay with the same values and so on that we had taken. So, please take the time to go through this. Now, notice one thing about the concurrent descriptions. We have executed many statements a statement like a equal to 0, a statement like a equal to 1, b equal to 0, b equal to 1 and so on. We never had to care where was this statement placed in our program its position was irrelevant. It was executed when it was required to be executed by its sensitivity. We have gone and we have we always knew that now we have to wake up the inverter, now we have to wake up the NAND and the NAND and inverter code was then run. So, therefore, running of the code unlike a program does not depend on the position of this line in the program. It in fact depends on when is your sensitivity struck that means when is your input changed and then wherever is the code is the program the simulator will go and seek you out and ask you what should be your new output. Therefore, a hallmark of concurrent statements is that it does not matter where you place them you can place them anywhere in your description and they will be woken up when their input namely the right hand side variables in that assignment changes this statement will be woken up. This is the hallmark of a concurrent description. However, this assumes that the concurrent description is a single line, but very often the behavior of a module may not fit in a single line. In fact, it rarely does then what are we to do? What it means is that the behavior is described by actually a traditional program a logical program which runs in zero time and then when that program is run I know what the output of this program should be. So, this whole program which is like a traditional software program must be run when the sensitivity of this program is struck. Now, because that is like a program now the position of a statement matters. So, this is called a concurrent block the block as a whole is concurrent. However, its innards are run like a program sequentially. So, those statements which occur inside this block are run one after the other as you would for a program and those are called sequential statements. The entire block however is woken up whenever its sensitivity is struck and that essentially runs concurrently and the position of the entire block does not matter. In particular certain concurrent blocks might be just a single straight line single line of code and in that case there is no sequential line in there, but if they require multiple sequential lines then we must delimit the ends of this and that entire block should be treated as if it has the logical status of a single line and it will be woken up whenever its sensitivity is struck. Please read through the rules about sequential and concurrent descriptions unfortunately our time is quite limited and therefore, we will not have time to describe all of this