 So, welcome to this lecture on VHDL in the course digital system design with PLDs and FPGAs. In the last lecture we have looked at basically how to write packages basically to write components in a package and put it in a library and instantiate it in some top level entity. Here we have looked at the configuration, specification and configuration declaration which talks essentially about how to say like you are instantiating some components from a library, so the configuration specification bind this instantiation to a specific library, specific package, specific entity and specific architecture that is a basic idea. And configuration declaration does this thing in a separate design unit, also it has an additional function suppose the top level entity has multiple architectures, it tells which architecture to be used for that configuration specified, so depending on how you write configuration and the top level entity can have multiple architectures that is a basic idea. Because when we at the beginning of the lecture we have discussed that the VHDL can have multiple architectures but we did not say how the tools are going to infer which architecture you require okay, so this can happen in two scenario. One scenario is that you have a one entity and multiple architecture and you want to use at the time of synthesizing or simulating or implementing whatever may be the case that a particular architecture, suppose you have an entity with three architectures and you are just going to use that entity alone, that component alone and you want to say out of the three which architecture to be used for the current compilation okay, so that is done by the configuration declaration. In addition suppose in your entity you are instantiating components from library and you can specifically say a particular component should come from a particular library, otherwise you will be at the mercy of the tool because there could be similarly named components in various packages and various libraries and if you just say some library name and use that library.package and various maybe you will write some five use closes, so the tool will pick whichever comes first to suppose you have used a component called counter. The tool is going to look at the first package, second package and so on, wherever it finds a name which is matching the instantiation and the arguments of like various ports you have the you know you have the data type and if the data type matches it will pick up that particular component probably that is not the one you want. Then in that case you can very specifically say a particular component instantiation you can go to the level of specifying a particular label. We have used XOR gate five times like suppose the labels were X1, X2, X3, X4, X5 these component instantiation labels and you can say for X1 it has to come from a particular package and for X2 maybe from another package and so on. So it is very it can be very specific very detailed, so that is what we have seen in the last lecture. So let us quickly look at the slides of the last lecture for a revision, so we have taken an example of a double synchronizer as a top level entity and a flip flop as a component and we have seen that in the normal course you will write the code for the flip flop. So the library entity and the architecture and in the same file or in the same project you will have the double synchronize circuit the top level entity which has you know the input and the clock and the output and you declare the component which is just particular data flip flop, declare the signal to interconnect because you have it will have to declare this, declare this internal signal, instantiate it twice and connect all the signals and that is what we have done, declare the component, declare the signal, the first flip flop is instantiated with appropriate mapping, second one that is it. But when you write okay this is a bit about the package and library, the hierarchy is that library, multiple libraries within each library you can have multiple packages and within a package you can have components, functions, procedures and data types. And there are predefined library one is STD which contains these two packages, standard package and text.io package, this is what which contains the bit, binary, the real all those definitions and all the operators related to it. And the text.io is used for file operation which can be used in test pages and the work library is the one which your current design whatever you write is compiled into the work library. And normally it is understood that without these two no tool can work so you do not kind of explicitly declare these like libraries, STD, work is not required it is implicit it is understood. Similarly the essential package in the standard library is standard so you do not have to say use std.standard.all this is implicit this is assumed it is there and but if you have to use a text.io in the STD library that is not implicitly declared because it is not used often it is used only in the test pages. And so when you want to use it you have to say use std.txt.io.all and this is how we write the package. So the top you write a package header follow that with the entity and architecture and we are calling our component the same component dff so at the bottom you have a library entity and architecture of dflipflop and at the top you have a package header package some name is n package within that you write the component of this dff exactly same as the component declaration in the top level entity which is nothing but this entity whatever is inside the entity is repeated there and that is it. Once you do that this particular component is the package definition is over and this can be put in a particular library and that is tool specific vendor specific how to compile a package into a library you have to refer to the manual or the user guide of the tools you use but when we go for a demo we can definitely see that at least the tool we are going to use how to use that within that tool we will see. So how to use this the fact that you have put a component in a package and compile into a library but we have to see how it is to be used in a top level entity in our case this double synchronizer so first thing is to note that we have put that package in a particular library so you have to add the library close library xylip that is where we have assumed we put this xy package and you have to say use xylip.xy package.all then comes entity but in the architecture declaration region we do not have the component declaration because now that is part of the package or part of the component which is in the library. So we do not have that we just declare the internal signal which is required and then we instantiate as previously this particular component that is all what is required and as I said you can have multiple component in a package it does not matter suppose you have 10 components you can include the component declarations all the component declarations within the package body and follow it up with the entity and architecture of all the components ok suppose you have 10 components write the entity and architecture of the first component followed with the second component and so on you can write that in a single file compile it into library that is simple as it is and definitely when you instantiate you can use positional association or named association this is any time better than this particular thing where you have to keep we have to remember the order of the formal parameters which is sometime difficult to know and moreover when you write a component one would like it to be generic because if you have a counter then you should not be worried about 8 bit counter 16 bit counter and so on you should have a counter which is generic in size and when you instantiate it you should be able to specify the size we have seen that and how we do is that instead of hard coding the size we define a constant called generic is nothing but a constant say here it is called size and we say size is 4 we say size-1 down to 0. So the syntax is that in the entity declaration you include generic and open the parenthesis and within that you can write any number of generic depending on the requirement say here we require only a size but in the case of a FIFO we have discussed maybe you have a data width and the size of the FIFO in terms of locations and so on. So here size is declared as an integer with a default value of 4 this is the default value when you instantiate if you do not specify anything then it is treated as 4 ok. So and definitely for a 4 bit vector we have 3 down to 0 so we say size-1 down to 0 and we have a signal so wherever required the size is required then you say size-1 down to 0 then follow it up with the architecture and at the top you have a component declaration which is nothing but similar to the entity. So all these appears at the component side then you can put it into a library but then we have to see how to use that ok how to specify the size we require when you instantiate it. So that is what is shown here in the normal case if you say count that is the counter we put port map and the input signal output signal the width will be 4 but you want a specific width. So like ports are mapped we have to say generics are mapped so the count generic map and 8 and there is only one generic here so that gets the value 8 so everything here is 7 down to 0 now ok. So you get an 8 bit counter and if there are multiple generics then you have to say comma like here you can say comma 16 and so on. And this is nothing but positional association you can have a kind of named association which say size that is what it say here size and with the forward arrow 8th you can say then if there are multiple generic then you put a comma and the next one and so on ok. And this is the normal port map so you can have any number of parameters and we have seen an example of a NAND gate with propagation delay TPLH and TPHL defined and we have seen that the behaviour is specified like O1 gets I1 and 2 after TPLH plus TPHL by 2 ok. And we have also seen that when you instantiate a particular component in a top level entity the top level entities generic can be passed down to the component which is instantiated ok. Example we have treated was a counter which is a generic counter which is instantiated in a generic timer. So naturally the width of the timer will be width of the counter so when you instantiate the counter in the top level entity of the timer and top level architecture of the timer then instead of hard coding it we say the generic of the timer t width. So when that is ultimately specified you know it is going to be you know instantiated or specified then like the timer can be instantiated in a CPU then that will be specified at that time and that will be passed down to the counter. So that is the generic in hierarchy and this is a configuration specification which tells how to bind the instantiated components to entity architecture pair and this is specified in the architecture declaration region. Configuration declaration as the two purposes one is the same purpose bind the components to a particular library also it binds a top level entity of this particular top level design to a particular architecture it has ok. And this is a separate unit this is hierarchical ok we will see what is the meaning of that and we have seen an example a full order with 2 XOR gate 3 AND gates and 2 OR gates. So you know the component declaration is XOR AND and OR and we have in the architecture statement region we have instantiated this. But in the declaration region you can say 4 X1 X2 that those are the labels of XOR 2 instantiation that it comes from use entity library dot package here there is no package but because it is in the work library. So the entity and the architecture ok for A3 that means in the AND gate A3 alone use entity this library this entity this architecture and whatever the formal ports which is in the library is mapped to something called A1 just a name change in case you have used a different name here ok. We have not used we have used a positional association so probably this does not matter. But suppose you have said instead of HSB suppose here we write say for A3 we say instead of saying HSB mapped to S4 suppose you had said kind of A1 mapped to S4 then this could be done to change it. And there are two special syntax for all OR2 that means for all the instantiation of OR2 use a particular entity architecture prepare and you say for others that means here you see AND gate instantiation for particular A3 we have used a particular component from a library for all others that means A1 and A2 use something from elsewhere that is the way it is specified. And when it comes to configuration declaration for a simple binding of the entity top level entity to architecture you write a configuration name of the entity you say for a particular architecture name N4 that means this entity is mapped to this particular thing that is all. But you want to specify the component binding that can be done inside so you say for A1, A2, A3 use a particular AND gate say N4 for others OR2, N4 that means we are not specifying anything for all XOR2 use configuration work.xorcon that means XOR2 has a configuration as part of its entity architecture which say that which are the where this particular thing should come from and which is architecture to use all that. So that shows the hierarchy of the configuration. So I think this is what we have started briefly in the last classes so there are different packages and different packages as different operators, functions and it can be little confusing at the beginning which particular operator to use, which particular function to use and so on. So we will look at and it is very difficult maybe it is not given in a textbook sometime and one way to know this particular operator's definition is by looking into the libraries okay that would mean that you go through the source code of the library okay that is a very cumbersome thing because you have to open the source of the library in VHDL or Verilog you know go through all the code and in the process you make some changes to it and then if you compile it for some tool, simulator tool then it can give errors and all that. So I am giving you a brief about the various packages, various operators and functions. So the primary package we have come across other than the standard package is the standard logic 1164 where this standard U logic is defined with all the 9 values we have seen that okay and a standard logic is nothing but a standard U logic but it is going through a resolution function in the case of multiple drivers and we have a standard logic vector, standard U logic vector and standard logic vector which is defined as an unconstrained array of standard U logic and standard logic respectively. So it can take any value of you know 2 raise to 32 okay and when we declare we constrain it by specifying the size and standard logic 1164 contains only the logical operators for this particular standard U logic, standard logic, standard U logic vector and standard logic vector. So if you want to do some arithmetic with it then we need to use a different package this contains only the logical operators. So please keep that in mind. So the next thing we have already seen in some example which is the package standard logic unsigned this is also the nightly package. So it is written nightly dot standard logic unsigned. It has standard logic and standard logic vector as a data type the operators like plus minus multiplication division is overloaded for it. Also it has relational operators all greater than equal to not equal to less than or equal to greater than or equal to all that is there. So you can the moment you say use IEEE standard logic unsigned you can use all these. In addition it has shift operators which is called SHR which is shift right and SHL which is shift left okay. This is all logical shift there is no arithmetic shift which is offered in this particular library. So if you are working with two's complement maybe it is little difficult either you will not be able to use this particular operator you may have to write code for arithmetic shift okay and as I said the digital I mean design when you design through the VHDL it enforces strict type checking. So suppose you have a standard logic vector which has to be converted to integer then you have to specifically convert it to integer it will not be you cannot assign a standard logic vector to an integer. Maybe it is 8 bit but you know that the 8 bit goes from 0 to 255 for unsigned but that like you cannot assign that to an integer unless you convert standard logic vector to an integer. So this is this particular function convert this standard logic vector to integer you can say conf underscore integer open the bracket and whichever is your standard logic vector you know the object you can put here and it will return an integer you know that is how this is this particular function to be used and there is a synopsis specified library which is called std underscore logic underscore arith okay. Now that does not use a standard logic vector as a base vector type it has two arrays of standard logic which is unconstrained one is called unsigned other is called signed as this name suggest that can be used for arithmetic you can have unsigned addition and signed addition it is exactly similar to standard logic vector but then the name is unsigned and the name is signed here. So you have this package as all the operators overloaded for unsigned and signed. So you have all the arithmetic operators all the relational operators like in the previous case you have like standard logic unsigned you have shr and shl but if the type you are using is unsigned then it is a logical shift if it is a signed data type you are using then this will be an arithmetic shift automatically so you do not have to worry. So if you play with the two complement number then this can be very useful because you do some kind of computation with the sign extension then you have to shift it properly with the sign bit otherwise the value will not be correct the result will not be correct. So this is taken care of in this shr and shl the provided use the proper data type signed. So it also has conversion function so basically it has conversion function from standard logic vector unsigned, signed and integer. So there are four conversion functions so the convert integer will convert from all the other three like standard logic vectors signed and unsigned to the integer. So you just open the bracket and write whatever so that means this convert integer is overloaded three times in this case for standard logic vector for unsigned and signed. Similarly you have convert unsigned which will convert from standard logic vector signed and integer convert signed, convert standard logic vector and all that ok. So that means it means that it convert to standard logic vector convert to integer from these three types whatever is not mentioned here is the from kind of data type. Now if you want to use this libraries synopsis libraries you say library IEEE use IEEE standard logic 1164 because the standard logic base type itself is defined here then you say standard logic areth wherein you can use kind of all the arithmetic relationship and logical operators and sorry functions. And you say at the end IEEE standard logic unsigned because the shift operators unsigned it has yeah there are arithmetic and shift and all that operators here and mind you this is put below this so that main operators are from the areth. So these are the recommendation for all the design you have to use standard logic areth and unsigned you can use it for counters and test pages and do not use a package there is a package called std logic signed do not use it. Now like there is a package from IEEE standard like in place of the synopsis packages. So these two are synopsis packages areth and sorry areth is a synopsis package. So there is another similar package from the IEEE so that is called numeric underscore std or we call numeric standard. Similar to areth you have unsigned and signed specify as array of standard logic and you have arithmetic operators now you not only you have plus minus multiply and division you have absolute rum and mode you have in the numeric standard you have relational operators you have logical operators you have shift operations you have a shift left shift right rotate left rotate right SLL SRL which is nothing but this ROL ROR which is nothing but this. So exactly same and you have conversion function to integer to unsigned from like if you take two integer it is from unsigned or signed or standard logic vector and similarly others and how to use this particular package. So you say library IEEE use IEEE dot standard logic 1164.all that is required because standard logic is defined there and use IEEE dot numeric standard.all ok. So that is how the IEEE numeric standard library is used in the earlier case we have seen that we have to use 1164 unsigned and areth but here is only numeric standard need to be used. So that is the various libraries various packages operators and functions. Now when it comes to type conversion many a times you have to do because we use different libraries and so you have to move between sometime standard logic vector to signed and unsigned and integer and so on. So there are three ways you can convert so it is automatic between base type and sub type ok. So suppose you have a sub type then you do not have to worry you have to define a sub type of something then you do not have to worry you just assign it will work it is automatic you do not have to do the type conversion. In some cases you have to use the explicit conversion function like to integer convert integer and so on. May be so you have to convert from standard logic vector to an integer. So you can use either of this functions and you know that the signed unsigned and standard logic vector all are the unconstrained array of standard logic. So essentially though the name is different the data type is same it is only the name difference. So the VHDL allows you to do a type casting as in C. So when you convert between these three between any two of them then you can just use a type casting say suppose you have a standard logic vector called SLVect and you want to assign this unsigned vector USTVect to this. You do not have to call two standard logic vector or two standard logic or convert standard logic just say STD logic vector open bracket and just write the UST vector you get the standard logic vector. And similarly suppose you have a UST unsigned vector and you want to assign a standard logic vector you just say unsigned then you give this standard logic vector as an argument then unsigned vector will get it. And particularly suppose you want to use some numerical value for whatever purpose and say you want to pass this as sign number then you just say signed you know in the code you give that numerical value of the standard logic vector it will be automatically converted to the signed data type ok. So that is about do the type conversion between the various similar data types. Now you should be careful when we write when we call a function say suppose in some case we needed a standard logic vector to be converted to an integer ok. So we will call a function which convert the standard logic to an integer ok. And if you know that suppose you have a 4 bit binary number to convert to an integer the algorithm is that just simple you know you trade through the binary number bit wise wherever there is one you say the you have an accumulator you say that accumulator is nothing but accumulator plus 2 raise to i, i is the current index of that bit position ok. So if you have 1010 so it is basically 2 raise to 8 sorry 2 raise to 3 plus 2 raise to 1 which is 10 ok. So and that you go through an iteration like for i in 0, 2, 3 then if i is 1 then some variable is accumulator variable is variable plus 2 raise to i and so on ok. So that is how it is computed but like you should not think that this is going to be synthesized into a hardware ok. The data type checking is enforced by the VHDL as a language ok. So the fact that we write some code to convert a data type that should not be synthesized into a circuit ok. So basically that you should understand and so there are attributes which say like when you write a library function for this type conversion there are like attributes which is inserted so that the synthesis tool will not synthesize that part of the code that you should understand. So that is what is written here but having said that sometime when you convert suppose take an example of memory ok and suppose you have a memory with 8 bit address ok. And so the number of locations are 256 it will be normally address from 0 to 255 ok. Now like in VHDL code you can specify an array of location index by the address ok. So you will have a memory array which goes from 0 to 255. So when you suppose you are reading a memory location you would put the output of that particular memory location to a data bus and you need to specify the array index. So to that extent we will kind of convert the address which is in standard logic vector to an integer and supply this as an index to the array ok. Now though the type conversion does not imply any hardware but there is a hardware here which is hidden that means you are converting an index which is in standard logic vector to an integer which is indexing an array ok. Then that represent an address decoder because you know that in a memory a particular location is accessed by an address decoder. You specify the address a particular decoder will go and select a particular location. And so that like implicitly sometime this type conversion not the type conversion alone but the fact that that converted integer is indexed into an array can represent a address decoder. I may be what I have written is little kind of misleading it is not the type conversion which implies an address decoder. The fact that that converted number is used as an index into array can mean that it is an address decoder. So that is what I want to convey. So I hope you are kind of clear about this particular type conversion. So let us see some examples of arithmetic ok maybe some kind of at least at the start this will bring in clarity. Suppose imagine there are a, b these are the input kind of vectors 8 bit vectors which is defined as unsigned 7 down to 0, s is we are going to assign some output unsigned 7 down to 0. All these a, b, s are 8 bit and we have a 9 bit s which is called s9 which is unsigned 8 down to 0. And we also have an s7 which is unsigned 6 down to 0 ok. Now very simple addition suppose we are kind of doing an addition or you are implementing an adder then the simple addition is that you say s get a plus b ok. Now a is 8 bit, b is 8 bit and s is also 8 bit and which normally in a digital course you would have learned that you add 2 8 bits and you end up with a 9 bit. But when you work with the operator you add a and b and you just end up with in kind of 8 bit result the carry is ignored when it is synthesized or implemented. But in some case you like when we suppose you are doing a multiplication we are trying to design a multiplier. Then you know that in the multiplier algorithm you need to add the partial products and then you have a shifting. So there if you add 2 8 bit that will result in a 9 bit and we require the 9 bit ok. In that case maybe in a simple addition we may not require the carry bit. But there are cases where we require the carry bit in such a case what we do is that say see how we can get that 9 bit. So s9 is a 9 bit vector which is assigned then we up and 0 at the most as a most significant bit of a. So you say 0 concatenate with the a which is 8 bit plus 0 concatenate with b. So if there is a carry from the MSP which is 7 down 7 a7 or b7 position then that goes to the 8th position and you get a 9 bit result ok. Suppose you want to live with only the 8 bit result then you can definitely say like sorry a 7 bit result then you can say a6 down to 0 plus b6 down to 0. Suppose you want to you have a larger input and you have a smaller output then you pick up the same size as the output then you will get there is no issue because this is 7 down to 0 which is 8 bit but a7 is only 7 bits wide. So you use a6 down to 0 plus b6 down to 0 and some cases you may need to supply a carry in ok maybe you have split the order for whatever reason in the two stages the carry out of the previous state come as a carry in of the next stage. In such a case we do the opposite of happening 0 at the MSP position what we do is that this is a 9 bit result and a and 1 at the least significant bit plus b and the carry input ok. So you get the a9 ok 9 bit result but this part should not be part of the address sorry part of the result ok because we say that suppose we are not interested in having the sum output we want to push some carry if it is generated to the next the first stage. So here you know we have made it 1 so if the carry in is 0 then the carry out from the first stage is 0 but if it is 1 then 1 plus 1 is 0 the carry into the second stage is 1. So but this 1 output the sum output itself at the least significant bit is not what we require so we ignore it. So ultimately you just take the up to the first bit from the 8th bit and cast it into an 8th bit result ok that is how we use the carry in if required. So this shows how to use a carry out this shows how to use the carry in with the standard operators and we have used so you do not have to write a ripple order code or the carry look at a code normally you can stick with this plus and in the case of FPGA there are dedicated resources to implement the plus so which is very kind of high performance area efficient and so on. We will see that when we go to the particular FPGA lectures and that is about the arithmetic with kind of addition with the carry out with carry in and so on. So now we let us look at arithmetic with time the you know that time is specified as kind of integer units so you say 1 nanosecond, 2 nanosecond you do not say 1.5 nanosecond. So but when you do some at least for simulation wise when you do some calculation like you want to calculate the period and you want to multiply the period with something then you may end up in a kind of real numbers. So it will be good if you can convert the time to a real number so suppose here I am showing that we declare a variable which is named period which is of type real. And now we say period get real that is a type casting and time data which is in nanosecond say 100 nanosecond divided by 1 nanosecond. So we remove the unit and you get a 100 and that is casted as real and then you get the period in real then you can multiply divide then you get the real number as a result. So that is how we do the arithmetic with time. So briefly we have looked at the packages basically the IEEE standard logic 1164 package standard logic unsigned which is IEEE library a synopsis package called standard logic areth how to use that various arithmetic operators, relational operators, logical operators, shift operators and conversion function. And we have seen numeric standard how to use that we also said the type conversion is not kind of does not represent a hardware it is just for the language type checking but when we in special cases when we convert and use it for indexing an array it can represent some decoder that should not be forgotten. And ultimately we have seen some example of arithmetic like some similar size result as a input when you add and when you have a carry input what to do when you have a carry output how to get the result the wider result with the carry out and so on. And we have ultimately seen the time some computation using the time during simulation where we convert the time unit into the real number so that you can multiply where you end up with the fractions then that can be preserved if you convert to the real number. So let us talk about this particular topic and which is called delay modelling how the VHDL model the delay we have already seen the syntax we say that something get after 5 nanosecond then there is a delay for that output to display or to come out with a 5 nanosecond delay. So there are two types of delay specified in the VHDL one is called inertial delay and another is called transport delay. So basically inertial delay will model the delay through capacitive networks you know that you have a line with capacitance you apply some binary value then that capacitor has to charge up to that particular value and before that before it getting fully charged if the input applied is removed then there would not be any effect. So that is what is inertial delay and that works for the gates with threshold because you have an inverter and you apply a 1 at the input of the inverter then naturally there is a capacitance on the line and the input has to charge up say previously it was 0 above the threshold for the output to start appearing ok. So there is like at the input there is some certain pulse width then only like a minimum pulse width then only the input will go above the threshold and the output will appear ok and also there is a propagation delay. So inertial delay has two parts one is a minimum pulse width which is required for the output to come ok. Suppose once again suppose you have a inverter with a fine nanosecond delay and if you apply a 1 nanosecond pulse at the input of the inverter for sure you can be sure that it will not make any effect at the output it will not appear at the output because the propagation delay was fine nanosecond then you apply a narrow pulse of 1 nanosecond so it will not appear ok. But we are not in a position to say that you apply a 4.5 nanosecond pulse whether it will appear at the output ok that we are not able to say. At the gate level we have no great way to predict this by simulation or anything like that but if you consider the equivalent transistor layout and do like suppose you have made an AND gate or an inverter using say take an inverter with a PMOS transistor and NMOS transistor do the layout do the place and route of a VLSI chip and do a SPICE simulation then you will be able to see the exact effect. But when we model this at the gate level we do not have such accuracies ok. So it is at a very gross level we are going to model and it has limitation you should understand that there are certain limitation with regard to this kind of modelling and that can be reflected there will be side effect if you are careful in simulation you will see the effect of this in certain cases depending on particular model used to represent the delay in the VHDL output code particularly for simulation timing simulation and so on. So it has two parameters one is the minimum pulse width required for the output to appear second is the propagation delay itself ok. So we will see so that is inertial delay so we will see the inertial delay and move on to the transport delay. So let us look at the inertial delay this index for it is that say X gets A after 5 nanosecond ok that means the meaning of it is that between X and A there is a 5 nanosecond delay. Also it means that anything less than 5 nanosecond anything less than 5 nanosecond suppose you apply to A will not appear at the X ok that is meaning of it. But exactly same if you say X is inertial A after 5 nanosecond it is same as like A after 5 nanosecond because the default delay is inertial. So whether you say A after 5 nanosecond or inertial A after 5 nanosecond does not matter but in this case the minimum pulse width is 5 nanosecond. But suppose you have a case where the pulse width required for the output to appear is 3 nanosecond and the propagation delay is 5 nanosecond which probably may not be true like it may be very close to 5 nanosecond but take this case then you can specify you can decouple the minimum pulse width and the propagation delay and the syntax for that is you say reject 3 nanosecond inertial A after 5 nanosecond ok. So it means that anything below 3 nanosecond will be rejected and anything above 3 nanosecond will be delayed by 5 nanosecond. Also you can say that you get say 1 after 5 nanosecond, 0 after 8 nanosecond, 1 after 12 nanosecond. It means that you will get a signal for a fast 5 nanosecond 1, next 3 nanosecond because here we are saying the real time ok real. So for fast 5 nanosecond will be 1, next 3 nanosecond it will be 0 and the next 4 nanosecond it will be 1. So this is a very useful kind of syntax to generate some waveform and particularly this is useful in test badges. So that is about the inertial delay and transport delay is the delay through a transmission line ok. Basically no pulse is rejected you know you have a long line of bus ok and you apply a pulse irrespective of the width of the pulse it is going to go to the other end with a delay ok. But it would not be rejected because the pulse width is some kind of less than something and way to specify the transport delay is you say z is transport a after 5 nanosecond ok. You say instead of inertial you say transport a after 5 nanosecond then you get the transport delay. So maybe I will show some examples of the waveform and some kind of cases where this delay modeling is used for verification but just for today we will wind up at this part we have told about delay modeling which is inertial delay and transport delay. Inertial delay kind of model the delay through capacitive networks or delay of a gate with the threshold which essentially means that you need some minimum pulse width at the input for the output to appear due to this threshold crossing and the propagation delay. And as I said again at the digital gate level we have kind of gross delay we cannot be accurate but if you take a VLSI transistor level implementation do the SPICE you will know the exact delay. But this is very useful at least where such like from the SPICE simulation such delays are known then we can if knowing the device characteristics you can model using this syntax reasonably correctly because it allows you to specify the minimum pulse width and propagation delay. So we have seen the syntax for that default is inertial so we have in the simple case when you say a after 5 nanosecond or inertial a after 5 nanosecond the propagation delay and the minimum pulse width the same when it is different use a reject close and you can generate wave form by specifying you know the various values using this syntax. And the transport delay model the delay through a transmission line wherein there is no reject like there is no minimum pulse width requirement and the syntax for is that z you know some output get transport a after 5 nanosecond ok. As I said in the next lecture we will see some kind of an example of this syntax with the waveforms and we will also see maybe how to use this delay modelling to verify some timing of a flip flop we will see that. Then we will go through some maybe the VHDL code examples in the next lecture so that you are familiar you get some good familiarity with the VHDL language. So I stop here please revise and do not take it lightly just because it is a language because it represents the hardware you have to get into the habit of thinking hardware than just treat it as a language. So I wish you all the best and thank you.