 Welcome to this lecture on VHDL test benches in the course digital system design with PLDs and FPGAs. I have covered almost the complete syllabus what is remaining is basically discussing a case study winding up everything that means the design the VHDL FPGA and all that. And I am planning to show towards the end in the last lecture a VHDL design tool from Silings and I will also as part of that lecture I will show the case study we are going to discuss in the next lecture on an FPGA board. I keep this part towards the end so that it is kind of decoupled from what we have discussed because these tools change the interfaces change so if I show as part of the lecture then that part of the lecture become irrelevant after a while so that is why I kept it towards the end. But one part which is essential for writing VHDL and verifying is the test bench which we have not covered and I have not covered many things like functions and procedures and libraries in VHDL but I am sure you will be able to back it up by reading. I have been covered that because is not much used in the design the functions and procedures by you know there is less need of writing functions and procedures so that I have kind of skipped what you can go through it. Similarly the libraries and packages it is a very minor kind of syntax, extra syntax and something is tool specific working you know compiling into some kind of library and all that which is not part of the VHDL. The part of the VHDL is how to generate the syntax for creating package header and so on. So today we will look at the test benches which enables us to do the verification of the design we do in the tool. So let us go into the slides so normally when you simulate at the beginning most of the time you do this called interactive simulation that means you will compile your design into a library and in the simulator you apply some stimulus and see the output as a waveform. Again you give some input then view the waveform and so on ok. It is a very kind of interactive session you keep giving the inputs then verify the output and this is a very it is ok for a very simple design. But in a complex design this is quite difficult because the complex design will have lot of inputs, lot of outputs and to essentially verify the functionality you need quite a lot of inputs. So this is a long run of simulation and that to verify from one end to other and maybe it will run into seconds and the steps are say order of nanoseconds and to verify all that you know going through the waveform is very very difficult if not impossible. And in addition to that you know you have functional simulation you will iterate through the functional simulation then you will come to timing simulation and you will iterate through that again sometime you go back all the way to functional simulation depending on the errors and in the optimization you want to do. So in all these if you want to verify the long run of waveform manually it is quite a difficult task. So the so called test bench is a VHDL code which instantiate your design and apply the stimulus in kind of in a step by step manner and verify the output in the automated you know that process can be automated. So that is how the test bench is useful. So essentially what I am saying is that you can store the input test vectors and for those test vectors what are the expected outputs in one place it could be in an array or a file then either you can view the waveform in the waveform window in a simulator or even better is that after applying each set of inputs you can extract the expected response stored and you know compare against the actual output. So step by step you apply the set of inputs then check the output is kind of equal to the expected response sometime it is called the golden result or whatever so that is compared against the good one you know the really expected correct one is compared normally that can be generated from a correct model of the of your design. So basically it allows you to automate you know that means that you run it might take quite some time to run through all the test vectors but at the end if the response say that it is kind of verified then you are sure that it is working you do not have to run through long run of waveform and sometime you know suppose at some point there was a output mismatch you know what the expected output was not met by the actual output then at that point in the console there will be a message saying that the particular output did not match the expected output. So you can go to that particular instant and verify you know can check what is going wrong and you could try to you know address that particular issue. So test bench that way automate the whole verification process it is a must you know you cannot do without test bench in verification. So let us look at the process in a single process where and we apply the inputs you know one by one and assume that now for the starting we just manually verify the output at least let us understand how we can automate the whole applying the stimulus at the input in a automated manner and we will verify this manually. So that is the assumption so the process is that you have to compile the design into a library it need not be a particular you know special library it can be the work library. So in a simulator or a compiler any tool whatever you compile gets into work library so you have to compile your design into work library. Now create a test bench code with empty entities test bench code is nothing but a VHDL code that is used for verifying the design component you have designed ok. Now we have no plans to implement this is not a kind of implementation code this is just a verification code and so that we do not need an entity with the input output port it is not a component which we are going to implement it just we want to see the input output waveform. So we just keep the entity empty we do not declare anything in the entity now what we are going to do is that we have to instantiate this particular into the test bench code ok. Then only we can apply the input you know we will instantiate that as a component probably only component you know there is no need of anything else you know you just instantiate that top level component maybe your component consists of the interconnection of various other components but we are not interested in that we are interested in the top level component. Though when you compile that into work library everything will be there in the code but we instantiate we are going to instantiate that design into our test bench code. So we have to declare that component we have seen that to instantiate we have to declare the component because it is in the work library it is not in compile into a particular library in a package and all that not required. So we declare the top level component of the design and now when we instantiate a component we have to connect some signals to it you know you cannot instantiate a component without connecting a signal. But we are not connecting this component to anything else you know we just want to access the input to apply the stimulus we want to access the output just to observe the waveform. So it is enough if you declare the signals of the type of the ports of top level component that by that I mean if the component has say a b input and a z output we have to say there is a signal called a a signal called b which is 4 which are 4 bits and there is a signal called z which is a 1 bit signal that is all. Now the moment you declare the component moment you declare the signals you can instantiate that component basically in the code it is nothing but you know a is connected to signal a b is connected to signal b z is connected to signal z that is all when you instantiate that. Now to the input signal you can apply the stimulus and you apply the stimulus in the code then the test bench code is complete now you can compile that test bench and run the simulation and there will be a probably a long set of inputs which is applied you will get all the waveforms in one shot you can verify it ok that is the essence of the test bench code a symbol test bench code. So you compile design into library create a test bench code with empty entity declare the component declare the signal instantiate the component into the code apply the stimulus then the code is over the test bench code is over you compile it into the work library and you know unrun simulation and you observe the waveform and verify. So I am going to show that VHDL code as an example what I have written is a comparator with 2 4 bit inputs called a b which is standard logic vector 3 down to 0 both a and b and you have 3 output one is a greater than b a equal to b and a less than b. So all the 3 you know these are kind of mutually exclusive that one is any time only one of them could be one. So let us create a test bench code to verify the functionality or the timing of this component and initially we will concentrate on the functional simulation not the timing simulation. So this is a code you know you have the library declaration library IEEE then the package declaration use IEEE dot standard logic 1164 dot all that is to be able to use the standard logic data type and you see here entity com underscore tb is and you say n com tb ok tb I have appended to show that it is a test bench you know you can use your own kind of names whatever mode you want to use it you can use it whatever particular style you want to adopt you can adopt that. So it is an ndmdt now we write the architecture a name of this particular entity is now before the begin we have to declare the component we have to declare the signal ok. So component com 4 is port a b in standard logic vector 3 down to 0 ok this is the left part of the code up to here ok and this is the right part of the code ok. And now a b is 4 bit vector inputs a greater than b a equal to b a less than b is single bits out standard logic n component now we when we instantiate we have to connect some signal to a b all these. So we declare the signals of the same name ok it is very easy you say signal a b is standard logic vector 3 down to 0 signal a greater b a equal to b a less than b is standard logic exactly same. So the declaration is over we say begin and now we can instantiate the component ok we give a label and you say particular component com 4 port map and the positional association a is connected to a b is connected to b greater to greater equal to equal less to less. So a b a greater equal less in the same order and then so we have instantiated the component now to this particular wire a and b we are applying the input and now you see how that is done you say a is assigned all 0s that means at 0 nanosecond these are the commens and you say comma 111 after 100 nanosecond 110 after 200 nanosecond comma and so on ok. So we have not seen this kind of syntax we have seen after some delay but it is possible to keep on specifying you know after 100 nanosecond after 200 nanosecond and so on ok. So this is like a kind of sequence of inputs at the particular instant is applied to a. So we write similarly for the b only thing is that the commens say that you know both are 00 at 0 nanosecond so it is equal and here it is 11110 so it is a greater than b. So that is enough the VHDL code is complete so as I said library package, empty entity, component and signal declaration instantiate the component apply the waveform to the input signal ok. Now one problem with this particular and you just compile and run the simulation in simulator it will apply all these and you will get the output waveform and you can verify. But the trouble with this code is that assume there are some 5 sets of inputs ok and you will have a b c d e and this may not be a comparator very different kind of inputs. Then if you want to kind of check you know something has gone wrong at 300 nanosecond and you want to check and modify something so you have to go to different part of the code. You know like at 300 for a 300 for b maybe another place 300 for c. So it is a very cumbersome code because stimulus is part of the code and it is all over you know it is kind of distributed at many places and to verify what are the inputs you have supplied what if you want to modify it is going to be quite tough. But maybe some simple ways that we could a better method at least in this kind of type of test bench is that instead of giving a sequence of input to a alone. What you do is that at 0 nanosecond you specify what is a what is b then give a delay then you specify what is a what is b 400 nanosecond and so on ok. So that is what is shown a better method would be is saying that a get 000 semicolon b get 000 then you say wait 400 nanosecond. So you can imagine that is much better because if you have c d e we will specify everything in one line give a delay and a b c d e here give a delay and so on. So all the inputs are the instance a particular time instance all the input are in one place and you can easily modify it verify it and you can you know append to it and so on. So this is a better way than this particular thing yet it is still a kind of distributed in the code all the way you have to write it manually. So it will be good if you can store all the inputs in one place ok. Now in this test bench we are verifying the output manually we are you know kind of supplying the inputs and we are verifying the output waveform ok. So the question is can we for in this case say store a and b and for 000 and we also store say a equal to b a less than b a greater than b for this value that means here a equal to b will be 1 other 2 will be 0s ok. So you store along with this particular set of inputs and then what you do is that you apply the input stimulus and check that these outputs are equal to what is specified what is stored along with the inputs you know. So that is a better method of doing it so you do not have to manually verify it if everything goes well you know there is an error you have to see the waveform what is going wrong. So that is a better method of doing it. So the question is that can we store input test vectors and expected output together ok. Now mind you that these input test vectors could be of different type you know there could be one which is a single bit another could be a 5 bit vector and the output could be 3 bit vector and 2 bit vector and so on. So somehow we have to combine the data types which are of different types together ok. So what is the data structure sorry what is the data type that is best suited for this to combine together like in our case you have a b which are 4 bit vector and then a greater a equal a less b is kind of 1 bit standard logic. So which is the data type best for this in a C it is structure and in VHDL it is a record now record itself is not enough because we want to store a sequence of inputs and expected response ok. So now but the basic element is record but we need an array of record to be able to store different sets you know the input expected results at 0 nanosecond and inputs and expected result at 100 nanosecond and so on ok. So we need a record for individual element and then array of record for sequence of these data ok. So that is what we are going to do next we are going to store the inputs and the expected outputs sequence of them in an array of a record and we are going to extract it and one by one apply the input and verify the output against the stored output ok that is the basic idea. So let us look at the process which is little more complex than the earlier one. So we compile the design into library and we create a test bench code with empty entity all same we declare the top level component it is required same declare the signals of type of ports of the top level component. Again this is required because we need to connect a wire when we enchant it but here is the kind of difference. Now we declare a record with port signals of top level component these ports we put together in a record we declare a record of that type with the port signals. Now we declare an array of this record we will declare a generic array with unlimited length. Now we initialize a lookup table of this type array ok. So with input test vectors and expected output now after that we instantiate the component in the test bench code. Now we need to loop through this array read each record by record and apply the input. So then we need a process we declare a variable of type record because we are going to read from the array one by one the elements of the array. And now see each element is a record we have to declare a variable of that particular type of record which we have declared earlier. Now in a loop from the beginning of the array to the end we read the current array element into record variable because it is an array of record. So we read the current index record into this particular variable ok. Now that variable allow all the inputs all the expected output. So now we will apply the stimulus to the input port. So individual elements of the record has to be kind of applied to the input. Then similarly we can verify the actual output against the expected output ok. Now once you do that you can compile the test bench and run simulation and everything is automated you do not have to manually verify the output if everything goes well. If the simulation console say our message saying that the test bench has completed and there are no errors reported in the console then you are assured that your design has passed this particular test vectors for verification ok. To say whether the design is working completely depend on the quality of the test vectors you are applying whether you are you know applying all cases or all corner cases which kind of corner cases would mean the extreme cases which kind of typically represent the various behaviour. Suppose you are designing a ripple adder so naturally if you check that the old stages ripple through like say you give an input all the ones one input and the other input is one then it will be kind of rippling through all the stages then you know that all the stages are ok. And you might give all 0's all that you know say kind of overflow then all 0's depending on the case you have to apply your mind and find the corner cases you know it may not be easy at all and then you have to verify that everything works then you are sure that the design is completely verified. So I suppose that is clear to your mind so we have compile the design test bench code with the empty entity declare the top level component of the design declare the signals declare a record with the ports of the top level component declare an array of the card initialize the a kind of lookup table with of this type array then instantiate the component in a process you declare the variable of type record then loop through the array read the current element into this particular variable apply the individual's inputs verify the outputs against the stored output that is the process. So let us look at a component and the test bench code the component we are going to use is a 4 bit counter nothing but it is a simple counter you know you have clock reset and output ok. So this is the library design I mean library declaration library package 1164 package unsigned because I am going to use a plus here so that is why unsigned is used entity count for is clock reset is in q is out standard logic vector 3 down to 0. And now since q is out we cannot write q gets q plus 1 so we declare a signal count which is standard logic vector 3 down to 0 we write the code in terms of count and you see count is assigned to q. So in the begin we assign the count q we write a process clock reset begin if reset is 1 count is 0 else if clock event clock is equal to 1 count gets count plus 1 ok so end if end process so that is the counter code which we have seen ok. So we have an entity a signal to circumvent the kind of buffer type of mode and then q is assigned to count upon the reset the count is 0 upon the clock count is count plus 1 and the process ends and that is the component which we compile into work library and now we are going to write a test bench using the array to verify the functionality of this particular counter ok. So let us come to the test bench code initial part looks same we have the library declaration empty entity in the architecture declaration region before the begin we have component declaration with port reset and clock which is input the q which is 4 bit output and component then we say signal clock reset of this type signal q of this type so that we can instantiate this. Now before doing instantiation we have to declare the record so we say type some name t block is record reset clock and q mind you have shown that in a different order than this ok this particular yeah the order is same but it does not matter even if the order is different it really does not matter. Now we declare an array of that record so type test v is array now instead of giving a particular range we are giving an unlimited range of the natural numbers natural range unlimited of t block so test v when we say it is an array of this particular record ok and this is not we are not defining it is just a declaration ok. So this is just a declaration saying that when you say t block it means that when you say test v it is an array of this t block that is meaning of it. Now we are going to initialise a lookup table we say constant because it is one time initialise tv tv is a real lookup table we are going to initialise e colon equal sorry tv is colon then is type this test v it is an array of record then we initialise colon equal then element by element so the first time the reset is 1 clock is 0 so the outputs are 0 reset is 1 0 output is 0 then the reset is made 0 output is still 0 then we give a 1 to a clock so which is a positive at the count become 1 then we make it 0 the count is still 1 make it 1 then the count is 1 sorry 2 and so on ok. So you make the clock 0 clock 1 and so on ok you can write as many as you like then you say begin ok. Now we instantiate the component count 4 is port map reset to reset clock to clock q to q symbol now this is the main process which tested so test process now mind you there is no sensitivity list because we are not waiting for an event we are applying the inputs ok ourselves so there is no sensitivity list. So we declare a variable of this particular record ok to be able to read one by one so variable v tv is of type t block now we begin we loop through our lookup table for i in tv tick range ok. So this is an attribute when you say this is tv when you say tv tick range it means it is kind of 0 to whatever number you know automatically that correct number will come tv sorry for i in tv tick range loop now v tv that is this variable equal to tv i so that is the current index when it is 0 the 0th index 0th index this particular one is read into this particular variable you know this all 3 are read into this v tv. Now we have to apply the reset and clock we say reset get v tv dot reset individual element clock gets v tv dot clock. So when then we give a delay wait for 20 nanosecond now this is the game we say assert that means you make sure that q that is actual output of the counter is equal to v tv dot q. So that is the stored value like this particular one for the time instant 0. So v tv dot q so the syntax of assert is that if it is true keep quiet if it is false then you report you know whatever is written message written will come it will come into the console will be printed on the console. So if it is not equal then the console will say 0 nanosecond counter output is not what is expected then you can go and verify it and there are very severities different severities and you say severity note and warning means it will just printed if you say error or failure it will exit the simulation ok. So normally it is enough if you use not or warning so you say end loop ok. So this is the loop which loop through the lookup table apply the inputs one by one verify the outputs and then we say assert false report test over severity note. So when you say false this will be printed anyway severity note. There are you know later VHDL syntax allows you to write without assert false you just say report some message and it will come on the screen but I do not take risk because maybe that is part of the VHDL 2012 which may not be or 1997 which may not be supported in some kind of some simulator or simulator sometime allows you to select what particular language version you are supposed to use and all that. But very important you know that the process does not have a sensitivity list. So we cannot just say end process then again it will go back to the process. So we just say wait you know everything is over you wait ok otherwise it will go on doing it because we are writing all these in the concurrent body of the VHDL code. So this is always active so if there is no sensitivity list then it will go through after getting out of the loop it will start again. So that is avoided by saying wait and then end process. So that is how we store the test vectors in an array with expected result ok. So once again Qcran library package the MD entity component declaration signal declaration record declaration array of record declaration then initialize the lookup table then we begin instantiate the component in the test process we declare the variable then loop through the lookup table read the current index into the variable apply the individual elements to the input give a delay check that actual output is equal to the stored output then if it is not you write a message the end of the loop when you come out of the loop you flash a message to the screen then you wait and end process. So that is how the test bench you know this is a real very useful test bench ok. Now only problem with this test bench is that this is written for functional simulation ok. Now if you write this kind of test bench it cannot be used in timing simulation ok that you have to be very careful because say even if you take a simple combinational circuit of course the counter is a sequential circuit you know that you apply the input output will be available only after some delay when you do timing simulation. So if you just apply the input and give an arbitrary delay and if you check the output output may not be ready at all. So maybe the total delay is 25 nanosecond so if you apply the input wait for 20 nanosecond and check if the actual output is equal to the expected output it will show error ok. So when you do timing simulation you have to make sure that all the time parameters specified are correct and in the case of simple combinational circuit this is a propagation delay but when we come to sequential circuit it is not only verifying the output even applying the input we have to meet some timing requirement ok. So in a sequential circuit you know that the input should be applied to the flip flop sometime before the clock edge ok. So in a test bench when you apply the input you have to make sure that it is applied sometime before the setup time with respect to active clock edge. Similarly the input should remain there for some more time called hold time and now once that is done we are sure that the input will be transferred to the output but that we can check only after the propagation delay TCO of the flip flop. So that also we need to ensure one is meeting the setup and hold time another is verifying the result after the worst case the TCO ok. So that I am showing in a waveform and it means that we have to be careful when you apply the input we have to be careful when you verify the output at the proper instances we have to do this we have to generate a clock and let us see suppose we generate a clock in the simulator periodic clock ok. Now our job is that always come before the setup time with respect to active clock edge apply the input now the moment you are say setup time before this clock edge what you need to do for applying the next input is just wait for a clock period then correctly your before setup time before the next active clock edge. So once you are correctly behind the clock edge by setup time it is enough if you just keep on adding one clock period apply the input one clock period apply the inputs and so on ok. Now verifying the output you have to like after the applying the input then you have to wait for the clock edge then wait for TCO then you verify that the output is equal to the stored output ok. So that is one way of doing is that first of all you come setup time before the clock edge you know that if you detect the clock edge there is no way to go back but what you can do is that suppose you have detected the clock edge by clock the given clock is equal to 1 or at the beginning you know that it is starting with the half clock period from 0 then you can wait for half clock period minus setup time ok or you somehow latch on to active clock edge by implicitly or explicitly. Then you can say wait for a clock period that is from here to here and minus setup time then you are correctly behind that ok. Now once you are there then the next clock edge the input will be latch and output can be tested say from this instant you say plus setup time plus TCO then you are here then you can verify the output. Now to come here you can say a period minus TCO because we were in right so much in front of the TCO by TCO you say from here you say plus period minus TCO minus setup time then you are correctly here ok. And we will not in this game we will not store the clock not required clock is a periodical waveform so we can write a loop to generate the clock ok. So that is how the timing simulation is done so I will kind of illustrate various part of it one is generating the clock so in a loop we will generate the clock in a process. And we can specify the period we can specify the duty cycle if it is not square wave and we can give an initial offset you know maybe 400 nanosecond clock can be inactive say that might kind of reflect the real life scenario because there could be PLL based clock managers and which will at the beginning it will take some time for the PLL to lock. So we can to simulate that we can kind of give an initial offset or for any other purpose. And very important thing to remember is that when you apply asynchronous reset ok you can apply the reset anytime because it has priority you know just apply anywhere the output will go to 0 irrespective of the clock. But when you remove the reset if it is near to the clock edge then that can create metastability we have not studied it. But then essentially the asynchronous reset what it is doing is that it is going into manipulate the internal latches directly ok. Now the problem is that if you are removing the input in this setup time window very near to the clock edge the input is also manipulating the active latch and there will be a kind of kind of contention. And by the time you remove the reset there may not be enough time for the input to drive the internal latch and that can create metastability. So when you apply the input you remove the input I mean when you apply the reset remove the reset sometime before the clock edge it is called reset recovery time for safety you know in this code I am assuming that I am removing it by the setup time ok before the clock edge by setup time. Now very important question to ask is that what do you get this information we have not even simulated how do we know what is the TS to be applied or what is the TCO to be taken or what is the clock period to be taken. Now this will be part of the static timing analysis I had briefly mentioned that static timing analysis do the timing estimation by looking at the delay of the block delay of the wires ok. It can go wrong but you can specify the cases where the tool should not analyse like false path, multi cycle path and all that. So if you do that the static timing analysis will give correct estimate then you can use that plugged in the test bench to verify write a verification code with respect to timing ok. So that is what is asynchronous reset apply the reset before the setup time then applying the input is that we detect the clock edge either you say clock event clock is equal to 1 or you are synchronised from the beginning because we know that when the process start it is at 0 nanosecond and we know how the clock is going at 0 nanosecond to the period by 2 it is 0 then the clock goes for half period 1 and all that. So we can make out what is going on and can be in synchrony with the clock generation and we say you can wait for a period minus setup time then it will be right behind the clock edge by setup time ok. Now once you give a delay of the full run maybe the design you are doing it will take multiple clock cycles so you can give wait for all that clock cycle and check whether the data is valid and this I have taken kind of after the xilings test bench template and this is how they do it and I have used that template particular template for illustration. So the component we are going to check the functionality is a divider 8 bit divider so you can see there is a clock and reset because it is a complete complex divider complex in the sense that it is a multiple cycle divider it has a start signal so you apply the input dividend and diviser which are 8 bit then you give a start pulse it will start dividing do the divide operation then the quotient and reminder will come here and a data valid signal will indicate that the data is valid. So you know that the division is over ok so that is the component clock reset start and dividend diviser quotient and reminder and dv is indicating that division is over and what we do is that we generate a clock in a process we give reset and start manually because it is only required reset is required only at the beginning at the power on start is required only once per every iteration ok. So we won't store all these values in the array we will store dividend, divisor, quotient and reminder in an array and in a loop we will apply the input give a start signal and remove the start signal wait for this data valid or wait for the complete run then verify the output ok that is a game and let us see the code we have the library and package code I am using unsigned because somewhere I am going to use the plus so that is why it is used and empty entity and this is in the architecture declaration region we have the component which is called nr div8 it is an 8 bit divider so I indicate nr by non restoring you do not worry about it it is something some case study which I have done. So we will just take it is just a name and the port is clock reset start dv dividend divisor, reminder and quotient so these are inputs and these two are output dv is output so you declare the component then we declare the signals and mind you can see that reset is applied one at the beginning ok clock is made 0 at the beginning start is made 0. So all these are made to some kind of useful values at the beginning itself ok start is 0 because we make it inactive reset is 1 because at the beginning itself it is reset and dividend and divisor also we are giving some time some input. So that you do not see all the red you know red waveforms otherwise it will show some kind of u or z or some u it looks not good to have a simulation having lot of red waveforms. So this avoid that and the quotient and reminder these are the constant which is used for clock generation and the timing. So the period is 200 nanosecond duty cycle is 0.5 square wave initial offset is 0 nanosecond so it is as good as not having offset setup time is 15 nanosecond TCO is 15 one run is 2200 nanosecond ok. So that is around 11 clock cycles of 200 nanosecond ok and these are picked up from the period setup TCO is picked up from the static timing analysis. So we declare the record which is of dividend, divisor, quotient and reminder declare an array of this particular record then we a lookup table constant TV is test V then we say 4 values dividend, divisor, quotient, reminder and so on ok. So however many values you can write not a problem then we really start it then we have the component instantiated of the Nr div 8 component and this is a position named association formal clock is mapped to actual clock reset to reset start to start and so on ok. So all the inputs and outputs are mapped to appropriate signal now we write a process for the clock you say clock process no sensitivity list. So it is going to loop forever you say begin and then wait for offset some initial delay then we say we write a loop now which is clock loop we say loop. So you say an infinite loop it is not say for i in 0 to something it is just goes on looping it clock is initially made 0 wait for period minus period into duty cycle ok because you know we start with 0 then goes 1 for a duty cycle ok. So that is period into duty cycle so we have to say total period minus period into duty cycle that is the duration of the 0 then you say make it 1 then wait for period into duty cycle. So you see now it adapts period minus period into duty cycle plus period into duty cycle is the period. So you say n loop clock loop so it keeps on looping and keep on generating the clock cycle one after the other. So remember that the clock is 0 for the period minus period into duty cycle 1 for period into duty cycle ok in our case it is 50% so clock is 0 at the beginning from 0 to 100 nanosecond because it is 200 nanosecond then from 100 nanosecond to 200 nanosecond it is 1 and it repeats ok. Now this is the test process similar to the previous one so we write a process without sensitivity list we say variable VTV is T block. Now we say now this is where the difference is earlier we just applied the signal but now initially we made reset is 1 now the divider as reset internal registers are reset internal state machine is reset. Now we say we remove the reset now we said avoid metastability we have to remove some time before and we have taken it as setup time. So you say wait for period so the 1 full clock period minus period into duty cycle minus setup ok. So we are just coming so because it is you know it is kind of the if you see this is where we are at the beginning because it is 0 then 1 we are saying wait for 1 clock period minus period into duty cycle so we are here minus setup time so we are here ok. So that is what is shown here wait for period minus period into duty cycle minus setup now we remove the reset correctly to avoid reset to give reset recovery time reset is 0. Now we are correctly before the setup time before the clock you say wait for period so we are at the right point. Now we say for I in TVT ranged loop we are looping through this particular lookup table and we say we read the first element VTV colon equal to TVI ok. Now what we do is that we have to apply the input give a start ok. So we say start is 1 dividend is VTV dot dividend whatever was read divisor is VTV dot divisor input ok that we are reading from this and this ok. Now input is applied we can give we have to remove the start signal because if start signal is 1 it will end and again restart if the internal divider state machine will restart again. So we give only the start for a clock period and it is correctly applied before the setup time all these 3 wait for a period so we are still before the setup time you make start 0. So correctly we have applied the input applied the start removed the start at the correct place. Now the divider will start dividing and so we say wait for one run that is a time taken for complete division or you can write it as you know so many clock cycles into the clock period plus setup time because we are behind setup time before the active clock it plus setup time plus TCO because we are going to check the output so plus TCO. Now we verify the quotient and the reminder we say assert quotient is equal to stored quotient report if it is not correct similarly assert reminder is VTV dot reminder otherwise report reminder is not what is expected and we say severity note ok. So that is how we verify the quotient and reminder now we were now here you know at this point of the simulation we are at this point we are verifying the output. Now before the next clock cycle we have to come here so what we do is that we say wait for a 1 full clock period minus TCO minus setup time ok so we are right here ok. So that is what we are doing here we say wait for a period minus setup plus TCO or minus setup minus TCO and then it goes back you know the old process is repeated then again you apply the input give the start signal remove the start signal verify the output and so on. End loop so that is where everything is applied you say assert false report test over severity note you know that is the game is over so one quick run through this we have empty entity component declaration signal declaration with default values these are the parameters for clock generation and timing record array of record lookup table instantiate the component clock process with the loop for you know you know infinite loop for generating the clock test process declare the variable come before the setup time remove the reset loop through the array read the current element apply the start apply the input wait for a period remove the start then wait for the complete run add setup time TCO verify the output then before coming to the next iteration come behind the setup time then loop print report ok. Now there is another way of doing this explicitly you can say for setup time you can say wait for clock tick event clock is equal to 1 then you are on the clock then you can say wait for period minus period in the duty cycle for you know meeting the setup time similarly for checking the output you can say wait for clock event clock is equal to 1 at some after a one run or something like that and you say wait for TCO or if there is data value you can say wait for DVT given DV is equal to 1 ok. So, there are different method of doing it so basically the test pages are nothing but pure VHDL code you know there is nothing to do with synthesis so you are free to write the way you like I have shown you some kind of probable possible ways of correctly doing it 2 was 1 was very simple then was an array which is good for functional simulation but then I have shown real timing simulation. So my advice is that at the beginning itself you write a test span which is fit for timing simulation so you can use that for functional simulation also which avoids you know repeating you know again and again one for functional simulation one for timing simulation not required to write one for timing simulation use it for functional simulation with some value it does not matter but when it comes to timing simulation you have to go to the static timing analysis pick up the worst case setup time whole time sorry setup time and the TCO and the clock period and do that in the you know plug that in the timing simulation test bench code and then you can run the simulation I will show that when we declare kind of you know give the lecture on the case study and the tool I will show this particular thing no issue. So, please go through it revise it understand it properly I wish you all the best and thank you.