 And welcome to this lecture on FSM plus data path. So, we will try to illustrate some of the concepts the design the thought process behind design implementation, but through a couple of examples. So, FSM plus data path, FSM stands for recall finite state machine and data path is a collection of components which will which can store data, which can move data, route the data which can operate on the data. So, data path will consist of registers, multiplexers, ALUs etcetera decoders and so on so forth. So, this sum of the components on the data path like register multiplexers specifically multiplexers have control signals based on which the routing gets decided that is the configuration of data path is achieved by controlling some most of this particular components on data path. And the job of creating generating this control signal appropriate values is of the finite state machine. So, finite state machine is going to work as a controller of the data path. So, finite state machine in the first courses on digital systems most of us in a familiarity with finite state machine. So, here the finite state machine will be studied in the context of data path, how it controls the data path and the typical like examples of custom computing machines or general purpose computing machines will be illustrated in the course of this lectures. So, let me focus mostly on the example a very well known example that of GCD greatest common divisor. Let us for the sake of simplicity of the presentation we will I will assume that we are given two numbers x and y both non-negative. Let us say we are given the numbers 1, 1, 2 and number say 35 yeah and we want to compute a GCD of this using a synchronous sequential system. And that synchronous sequential system would be designed using the methodology or notion of FSM and data path. Let us see in the thought typical thought process which one comes first and how does the rest follow. So, let us first recall the GCD example. So, here we have these two non-negative numbers stored in x and y loaded into x and y at the beginning of the computation. Then let us see what would be happening at every clock cycle. So, before I write down the pseudo code let us go through this standard like you know standard computation which most of you would be familiar with. So, noticing that x is bigger than y we can do this so called modulo operation. But instead of doing the modulo operation which is what we do in case of write when we write a program with help of powerful libraries C program with the help of C libraries or whatever which we have remainder modular arithmetic I mean remainder function available. Instead here we will take a more simple approach of repeated subtraction rather than doing the integer division and finding the remainder and the quotient. So, here what we will do is we will subtract this x y from x and the result will put it back in x. So, that gives us 77 which is 1 1 2 minus 35 and 35 will remain over here. So, what we did in this first clock cycle was so called subtract like operation I just call it quote unquote subtract. In the next clock cycle again we notice that x is bigger than y. So, again I repeat this step of subtracting y from x which gives me 42 and 35. So, once again in this clock cycle I issue the command to this synchronous machine subtract I am deliberately using the words issuing the command that is what we will see the job of the controller would be to issue commands to the data path which is actually doing the computation on the data as well as movement of the data. So, here we get 7 and 35 42 minus 35 7 and 35 remains as it is in here. Now, x is now less than y or x is not greater than y. So, we have to do the swap operation. So, that we get bigger number on this side smaller on that side and we can process again. So, here is at the result of swapping 35 comes here into x and 7 is loaded into 7 moves to y. Here now we are again ready back in the family situation of doing the subtract. So, we get 27 7 similar again subtract 21 7 14 7 subtract again 7 7. Now, we have situation that now still x is greater or equal to y. So, we will again subtract we get 0 7. Now, we see that x is less than y. So, we swap. So, here we say swap and as a result of swap we get 7 here and 0 over here. Once we get 0 in the in the register variable y then we stop the process sorry. So, here you notice the last step. So, we were here say sometime ago at the step 7 7 7 resulted from 14 minus 7. So, 7 7 now we have I mean x is still greater or equal to y. So, we do not have x less than y a situation for swapping. So, we subtract. So, 7 minus 7 is 0 and 7 remains over here, but now we have x less than y. So, we swap 7 comes over here 0 comes over here. Now, any subtraction repeated subtraction is not going to help and anyway this is the end of this process and which is indicated by noticing 0 in the in the in the variable y. So, whatever is in variable x will be the result of this computation which is the GCD. So, GCD of 1 1 2 comma 35 is found out to be 7 computed to be 7. So, this is the algorithm very simple algorithm which works in terms of using the very simple hardware which does comparison, which does subtraction and which does swapping movement of data. So, we will realize this GCD algorithm by probably like you know wasting number of machine clock cycles doing in a very simple way, but using a very simple hardware which we can illustrate very easily and associated data path FSM concepts also. So, now let me abstract let me capture this what we just discussed in terms of pseudo code. Here, there is a loop some kind of iterative computation and in every loop we check if we already have a result or not that is if y happens to be 0 then we know that result is ready then we realize that result is ready where in x. Else if the result is not ready that is if y is not equal to 0 then we check whether there is a need to swap or not whether x is smaller than y which will make it like you know which will induce us to swap. So, if x happens to be less than y then we will swap x and y. Else what we will do is we will do a subtract operation the subtract operation will have this result at in the x in the location storage of x will load x minus y the result of the subtraction and y will be updated with y will not be updated y will remain as it is x will be updated with the result of subtraction x minus y and y will be as it is. So, this is the subtract operation this is where we swap and this we keep on doing in a loop. So, do not think of it as a C program sequential program it is a description with say like you know using if and else involving condition checks and also involving some operations like swap x and y and this subtraction operation and then movement of loading certain variables with appropriate results. So, from this it will become fairly clear what will be the data path what will be the components on the data path to support this kind of algorithm where in every clock cycle we will have every typical clock cycle of computation we will have all this logic being implemented. So, what we need on the data path we will need obviously to store variables we require storage locations flip flops we are going we have been focusing assuming synchronous computing. So, h triggered flip flops so, let us say this register called x and this register for y this indicates their h triggered registers what else we do we need we need some a subtractor we will require a subtractor which will subtract y from x. So, this is let us say a specialized ALU which is only used for configured for subtraction. So, this signal is say I call it x minus y this is the name I give it because I know it is going to carry the value x minus y we also require comparator less than comparator to which we are going to have feed in the input x and input y if x is less than y we will have a true value Boolean value 1 here or Boolean value 0 if it is not a case. So, this I denote this signal output signal by x l t y x I read it as x less than y this is the 0 1 signal these are 2 data items 2 integers what else to be require we require an equality checker with 0 checker whether this y input to this equality checker is 0 or not. So, again this is a Boolean output I denoted by I call y e q 0 y q 0 plus as I mentioned other than registers and ALU's comparators and so on. We also require multiplexes because data path is basically a collection of this components you know where through which at in which data is stored or data is operated upon or data is routed. So, one important kind of component that we are still missing over here is multiplexes multiplexes are almost invariably there in every kind of data path omnipresent things other than registers the multiplexes will be more or less always there. So, what kind of where do we require multiplexes we notice that like there is in different situations either we depending on situation either we swap contents of x and y or we load x with x minus y and we let y remain with as it is. So, we will require multiplexer to which one of the input is x itself and other input is x minus y and this the output of this multiplexer will be available to be loaded into x eventually I am deliberately still not completing this path because we realize that we need something more for the algorithm to start. So, this will require multiplexer which based on a select signal will either root x. So, will either root x minus y or in case of swap in case swap is required will root y. So, just like we will have more clear picture of this, but just realize the need that x might have to be load depending on different conditions x would have to be loaded with either with y in case of swap or with x minus y. So, we require multiplexer which will whose output will be routed eventually to a register x. Similarly, for y will require multiplexer which will either root x or y towards y register again. So, some multiplexers are required let us see couple of things that we have missed out. So, far let us go back to the we just basically I just showed you the main loop of this computation which has something like if y equal 0 then something else if else if x less than y then swap else subtract and so on. But before we once settles down into the loop and input has to be loaded into the registers. So, we will have in certain state this system will be doing this computation in every clock cycle, but before that there will be some kind of state wherein we say like supposing we notice a signal called start then we then we load into x and input meant for it and load into y and input meant for y. So, this is something extra that we are going to require because of which we will have we will need a multiplexer over here to which one of the inputs is the input from outside x in or the other input is this either y in case of swap or x or x x minus y in some the other situations. So, we require and output of this multiplexer will be ready as the input to this x register and this x is sorry x is going over here and and some other places let me draw it neatly again. If we have fair idea of how many components we require. So, I think it will help me draw it more neatly this is x, x is driven by output of this multiplexer where one of the input is something that is coming from outside and the other input is as we said it is the result of the multiplexer output of the multiplexer to which one of the input is x minus y and the other input is y in case of swap. Similarly, for y will have an multiplexer driving the register y or like ready at the input of register y one of the choices input choices to the multiplexer will be y in which is the input coming from outside the other one will be the output of a multiplexer would be either in case of swap y is to be loaded with x or it should remain as it is. So, this is my x signal this is my y signal this here if I allows my bit of clutter I can draw this y is y from carrying the signal from here over here this x from going from here to here y going from here to here and so on. But this is clear enough x minus is generated by an a l u where the input at the plus terminal is x and the input at the minus terminal is y x is coming from here y is coming from here else we also mentioned that we would need a comparator less than to which the inputs are x and y and output is x l t y and an equality checker whether something is 0 or not to which the input is y and output I denoted by y e q 0. So, let us root this. So, this is x goes to all these places y that seems to be more or less the data path, but like I mean this does not describe everything this completely because we are not describe what will be the control signals to this multiplexers that is what will be the select signal based on whose value whether this either this or this gets rooted. Similarly, the select signal to this multiplexer this is what we yet we have we are yet to describe a multiplexer here this we know this a l u is going to do subtraction. So, there is no control to be specified here we assume that x and y resistors are going to be ready for loading all the time in every clock cycle. So, no further enable signal is required here in general we do use it, but in this example turn out that we do not need it. So, let me start like you know fixing some more details. So, let us identify this multiplexer inputs by the standard in the standard way. So, if this select input is 1 then x in is going to be loaded into x. Similarly, if the select input here for this multiplexer is 1 then y in is going to be loaded over here. So, I denote this input port of this multiplexer by 1 because this which it indicates that when the select input is 1 this one will be rooted at the output. So, this one will be 0 this one will be 0 and I call this select signal appropriately load x in because its purpose is to facilitate loading of x in into the register x at the end of that clock cycle. Similarly, this one I call it load y in then what do I call let us look at this particular multiplexer what should we call the select input to this multiplexer this I named swap. So, if swap is 1 then I must allow root this root y over here in a way. So, that y can be kept ready at the input of x. So, when swap is 1 y will be rooted eventually to x. So, this is the input port number 1 and this is the port number 0. So, this select input to this multiplexer is going to be called a control signal y. Similarly, this one this one also I will call it y call it the same the name swap. So, when swap is 1 then y is going to be loaded with x. So, x will be rooted over to like y and if not swapping then y will be rooted eventually to y. This multiplexer is for the input situation that is when we are loading the fresh new inputs ready inputs into the x and y that is at the start of the computation before the loop begins. And this 0 input to this multiplexers this and this are going to be used in that in the looping computation in the computational loop. So, this is how generally we will kind of once we take a we build inventory of the data path components we figure out which data path components we require and how they are to be connected with each other and to wire them up. Then we start figuring out the control signals that are required to control this data path at different times with different control signals. So, it is not going to be any magic. So, we need something which will generate appropriate values of this control signals namely load x in load y in swap. Yeah, I mean such control signals have to be generated by a sequential circuit by itself and that sequential circuit will be a finite state machine typically. So, that data path might look like a bit of clutter, but it is quite easy to capture it in the syntax of very log. So, let me try that now. So, what we are doing over here in the data path is specifying that the registers in the data path are x and y. Now, I specify how the registers are going to be updated at the end of every clock cycle that is at the at the triggering edge of the clock the positive edge of the clock. So, the logic for now first I will describe the logic for updating register x. So, the logic is as follows if we notice that we saw in the previous just while ago that there is a multiplexer here and when we have when we need to take the input and register it to latch it into x we generate we we assert this particular control signal we need to assert control signal load x in and similarly load y in has to be asserted. So, and when that happens x in is going to be loaded into x and y in is going to be loaded into y. So, we will assume that somebody has helped us assert that particular signal load x load x in as well as the signal load y in. So, if load x in is asserted then x is to be loaded with x underscore in else, else again let us look at this. If load x in is not asserted then it is definitely not the the situation at the beginning before the computation begins. That means, we are likely to be in the computational loop there the root to x register x is going to be going to be like through this input port of this multiplexer and what we what will be loading into x will be the result of this particular multiplexer which either would be y or x minus y which would depend on swap. So, if swap is equal to 1 then we x will be loaded in that situation with y and if swap is equal to 0 then x minus y the result of this a l u will be rooted at the input of x. So, else if swap has been asserted then x is to be loaded with y else x is to be loaded with x minus y. This x minus y is like I am using the power of very log the right hand side is x minus y. In fact, implicitly this means that there is a arithmetic logic unit the subtractor which will be subtracting x and y and the result of that subtractor is going to be kept ready at the input of x. So, this statement captures the use of this a l u as well as the use of this multiplexer So, that is a power of very log is also being illustrated here. So, this is this is this if else statement which also has another nested if else describes the way x is updated register x is updated. Similarly, the way register y is updated is almost the same if load y in which is the input to the multiplexer is asserted is equal to 1 then y is to be loaded with the fresh input from outside else if else what is to be loaded in y the other option the other signal which is again the result of this multiplexer which is controlled by the control input swap. So, if swap is 1 then y is going to be loaded with x else y is going to be loaded with y itself swap y else I can say y, but with the help of I mean this very log synthesizer will find is redundant we do not need to say it will understand it automatically we do not need to say it redundant it is not wrong it is redundant. So, this is the main part of the logic of update of x and y. So, try and connected up with multiplexers and arithmetic logic unit and so their multiplexers are kind of implied by this if else statements to there will be a multiplexer with the control input load x in there is a role of multiplexer with the control select input swap is a role of multiplexer with select input load y in and another multiplexer with again the swap as the select input then there is a role of this subtract ALU, subtractor ALU I mean in this behavioral statement we it is implicit that we are making use of the subtractor data path component and result of that is to be routed to x using appropriate multiplexer input. So, that is swap is 0 then x minus the result of the subtractor is going to be routed to x. So, very log synthesizer is going to map this to major portion of the data path that we just drew. So, with the help of this very log we have a fairly like you know a text based and fairly unambiguous description of how the data moves how the data is computed I mean how is data is processed through subtractors and so on so forth. How the movement of data is controlled by the multiplexers now what remains obviously the major thing that remains is to understand how this control signals are to be generated and who is going to generate that. So, what we need is logic for control signals load x in load y in control signal swap. So, the entity that does this is called a controller and output of this controller are this control signals which are being used to drive the data path. So, in particular load x in load y in and swap we missed once signal that we would like we would like signal to indicate to the outside world to the external system I mean subsystem to the external universe whether the result of the computation is ready. So, I believe a controller can help me do that. So, let me assume that controller also generates a signal called ready. What are the inputs to the controller obviously the clock is one of the important inputs to the controller I mean is a synchronous sequential system by itself. So, the clock will be input then other inputs to the controller are we assume an input from external sources which triggers this computation to begin. So, when start input asserted then the x and y resistors are to be loaded with the data available at the input ports of this module of this design unit. So, this is an example of an external input also sometimes the some signals from the data path are also input to the controller. So, for in this case we realize that the comparator is output which says whether x is less than y and 0 checkers output whether which says whether y is equal to 0 are also going to be used in controlling this data path. So, we are just about to discuss the controller the controller as we just said would have generate this control signals which are input to the data path and also controller would make use of these data signals from the data path say x less than y y equal to 0 as input other than the input from the external sources for start for triggering the system to do the computation and a clock because very typical this controller is going to be of synchronous finite state machine. Further the controller also would generate output for the external world say ready indicating that computation is complete. So, let us look at the internals of a controller it will turn out that we can make this controller I mean quite often this controller is going to be very simple. In fact, in this particular case as an illustration will show a controller which is purely combinational it is not even a an FSM with multiple states a single state FSM which is essentially a purely combinational logic. So, controller is going to be a single state finite state machine which is essentially purely combinational this is the state which is the in which the controller loops performing different types multiple iterations of that GCD computations which involves essentially swapping and subtracting. The highest priority is given to the input signal start. So, the controller decides looking at start whether start is has been asserted or the start is de asserted. This is the situation when start is asserted when start is asserted the controller's job is to assert the control signals load x in and load y in right. So, and after it does that it will go back to the same state. So, it just simply asserts this control signals load x in and load y in when the start signal start input signal is found to be asserted is found to be high. On the other hand when the start signal is found to be de asserted that means it is a like it means the situation is like that we are already inside a computational loop and we should be doing things based on the result based on the status input from the comparator. The status input from the comparator says x is less than y or it could tell us that x is not less than y either this condition holds or that condition does not hold. In both the cases will stay back in the same state, but different kind of control signals would be generated different values of control signals will be generated. In particular if x is less than y we know the controller's job is to tell the data path that it must swap x and y. So, the swap signal is asserted in response to noticing that x is less than y and if x is not less than y then swap signal is de asserted whether I am bit casual with the notation sometimes for negation I use over bar sometimes I use this exclamation mark. So, you know that is ok I think. So, you see that this is what is the essential description of the controller it is a single state controller that means purely combinational it is simply generating the output signals load x in load y in swap etcetera simply by looking at the values of the inputs. I think I miss something let us look at it again this state loop if start is asserted then x input and y input are to be loaded into the x and y resistors at the end of this clock cycle. On the other hand if start is not asserted then it is a that means we are in the computational loop. Now, it is a situation whether now we look at whether y is whether the computation is finished or not that would depend on whether y is already equal to 0 or not either y is equal to 0 or y is not equal to 0. If y is equal to 0 we will assert the radio signal the controller will assert the radio signal and get ready for the next clock cycle. If y is not equal to 0 then we have two situations which are based which depend on whether x is less than y or whether x is not less than y. If x is less than y anyway the controller will in next clock cycle will stay in the same state but the control signal swap will be asserted that is the output of the controller and if x is not less than y then swap will be de asserted swap will be set to 0 and we will go back to the same state. So, I miss that the use of y equal to 0 which is very important because every time in the beginning of the clock cycle while in the computational loop you should the controller will check whether y has become 0 or not if that happens to be the case that means the output the gcd is ready in x. So, the external system has to be told that we are ready with the result in x if y is not equal to 0 that means we are still not ready with the result that means we have to like compute further. So, that would depend on whether x is less than y or x is not less than y if x is less than y we should be telling the controller should be telling the data path that it should swap or it should like in the other case it would not swap it would subtract x subtract y from x and let y remain as it is that is a not swap case. So, that is the controller this controller can be described in very long the this is the single state gcd controller. So, it is going to be purely combinational no role of clocks here combinational logic can be described using as continuous assign statements or as always blocks which are not sensitive to the edges of the clock like this. So, initially the defaults. So, I will specify that default values for the all the control signals are as follows load x in is 0 load y in is 0. So, up is de asserted and so is ready now depending on different situations this values are to be like appropriate values of the this outputs of the controller as to be specified. So, if start is asserted then this we know that load x in will be 1 and load y in will be 1 will be asserted that is the end of the case start is asserted if start is not asserted then we are in the computational loop and first we will check for whether y is equal to 0 or not. If y is equal to 0 then will further check else sorry else if y is equal to 0 will further check will immediately I mean this this necessary means that ready signal has to be asserted in this clock cycle else if y is not equal to 0 then it would depend on whether x is less than y in which case the swap signal has to be asserted else the swap signal will be de asserted letting x minus y subtracted subtractors result go to x and y remain as it is. So, this is the logic for generation of this control signals and output signal ready. So, this always block is purely combinational you see that with the help of this default blocking assignments we have made sure that in for in every possible situation depending on the input value start y equal to 0 x less than y we have in all situations specified values of this fork signals load x in load y in swap and ready then default values are this and non default values happen to be like get specified for specific conditions. So, it is exactly it is a very low description of this particular state diagram a single state diagram can check it start is asserted if start is asserted then load x in load y in are asserted if start is not 0. So, if start is not asserted that is start is 0 in that else block it would depend on whether y is equal to 0 or if y is equal to 0 ready signals will be asserted and if y is not equal to 0 then it would further depend on x whether x is less than y or x is not less than y in which case swap will be asserted or be asserted which is described over here. If y is not equal to 0 then it would depend on whether x is less than y. So, this x this captures that particular state single state GCD controller which is purely combinational. So, now it is a bit surprising that this particular controller that we discussed although it had this I mean we thought this is also an example of a synchronous system it is in general it is in fact indeed going to be in a very typical finite state machine. So, it is going to depend on the clock signal for synchronizing its state updates. So, this was a controller which turned out to be a single state controller. So, just to illustrate that like most typically because we will have some protocol on the inputs some protocol about the outputs what the external universe wants is I mean how the external world wants to interact with this particular computing machine special custom computing machine for say greatest common divisor computations. So, we will just modify the specifications we will understand what is the limitation of that single state controller machine and trans understand what would be the modification what could be the modification and how that modification of the specification would result in a slightly more general controller. So, note that in this this is the clock let us see the waveforms sample scenario this is start signal this we are using rising edge trigger discipline. So, the clock clock clock periods clock cycle starts at the rising edge and ends at the rising edge of the next clock period. So, let us say the start signal got asserted sometime here and state asserted for whatever let us say couple of clock cycles and got de asserted here. Now, we note that why because the way the logic has been specified in this if else statement the priority is given to start signal if start is asserted then we load inputs x input and y input into x and y resistors and we simply do not proceed to the computations until start is found to be de asserted right. So, if some but the if the external circuitry which is driving or GCD keeps the start signal high for long enough time hoping like you know just feel believing that it has triggered the system, but until the start is de asserted the computation would not start. While start is remains asserted the system will the GCD subsystem will keep on like loading the x and y resistors from the input. So, the computation would not start computation would start only over here only after start is goes low. So, at the end of towards the end of this clock cycle something will start happening in terms of swapping and subtracting and so on. And it will take a few more clock cycles for the data path to yield a result and the system would stay in the same state that is a that is what a behavior of that is that is a purely combinational controller right. So, the drawback of this single state controller is that it does not respond to start at the earliest it responds to start sort of like you know when the start goes down the computation begins. So, let us try and modify work around this like little bit of problem. So, we would like to like to react to rising age of start as soon as possible. So, the FSM will be in a state called state idle in state idle the system will be essentially waiting for start to be asserted. So, the system would stay in this controller would stay in this state as long as start is as long as start is 0. Moment start becomes 1 the system would go to a new state let us call it state loop and in this state it will do the computation. So, you notice that moment start becomes when start becomes 1 it is noticed by the controller controller would have been in that state idle state, but it is going to in the next clock cycle it is going to go to a new state in that new state the controller will start responding to like will start will ignore like the start signal and would simply like base its actions like based on the status from the data path that is whether y is equal to 0 or not that is when the whether the computation is done or not or whether if computation is not yet done whether x is less than y. So, which is which is when we should swap or we should not swap. So, that is what is the interesting things are going to happen in this state loop let us see what exactly happens in the state loop. So, this is the state idle the system controller stays here as long as start is 0 and start is found out to be asserted the system moves to a state called state loop is an arbitrary name that we have given to it. In this state again first we are going to look at this controller would look at whether y is equal to 0 or not or y not equal to 0 if y is equal to 0 then that means the computation is done. So, it is a case it is a situation for to wait for the next start trigger. So, immediately we will assert the ready flag and in the next clock cycle will go to the state idle waiting for the start to be asserted. If y is not equal to 0 that means the computation has to continue then it would depend on whether x is less than y or whether x is whether it is not the case that is x is not less than y. In either case we know the computation has to carry be done for one more iteration at least. So, we go back into I mean we go back to the same state to I mean you can see the we are still in the computation. So, we will go back to the same state, but different control signals will be generated. So, here swap will be asserted and here swap will be de asserted. So, it is essentially like we are just split that particular earlier single state controller removed the created to one extra state to respond to which is with job is to only kind of wait for the start signal and as main state which is which is where the computation is happening. So, now we see that this kind of controller will ensure that the start signals is responded to as soon as possible. We do not have to as in the previous case we would not wait for the start signal to die and then the computation will begin. This is the power of finite state machine just a minor changes in the finite state machine. Note that data path would not have changed at all it just the way it just that we have chosen a different protocol we decided to react to start like focus on start signal in a state idle state which is the initial state and once a start signal is noticed we immediately move into a different state. If we had state back in the same state priority to start would still would have been there and it would have like you know inhibited this swap and subtract operations. So, by moving into a different state we have sort of like you know help the system controllers ignore the start signal note that in this particular state there is no role of start signal ok it completely ignores the start signal it only depends on whether y is equal to 0 in which case it is going to know that computation is finished. Rate signal is associated and if y is not equal to 0 it would depend further on whether x is less than y or x is not less than y ok.