The first technique I’m interested in presenting you to try to reduce the overhead introduced by the reconfiguration time with respect to the baseline identified by the optimal overall execution of your system is the RECONFIGURATION HIDING. Let us suppose to have a set of functionalities, each of which represented by a node. Within this example we have six functionalities, A, B, C D, E, and F, that have to be implemented on the FPGA. Just for the sake of simplicity, we are considering the FPGA as an homogenous device that has been partitioned in three RECONFIGURABLE REGIONS, RR, in a mono-dimensional way. Mono-dimensional means that the height of the region is as high as the FPGA, while we are playing on the length to define the area of the region. Furthermore, all the three regions are defined exactly in the same way. Again, this is just an example, I am not interested in focusing on details that are not helping me in making the case of showing you how the reconfiguration hiding is working. Going back to our context, I do have to define just one more thing. Each functionality, to be implemented, needs to have a physical assignment. This means that to properly create the corresponding bitstream, I do have to assign to each functionality a region, or a set of regions to implement it. It is worthy to mention one thing: within this model I’m considering the case in which a functionality can span more than one region if needed. This is a reasonable assumption that can be realised with some tricks during the design phase. We are going to know more about this in the following classes, but so far this is all you need to know. We need just one more thing to have a complete set of information about our functionalities: the execution time. Now, just to give you an example, we know that the functionality labeled as A is characterised by two numbers: two and one. Two is referring to the number of reconfigurable regions needed to implement the functionality, while one is the time unit needed to complete its execution. We are representing our application as a DIRECT GRAPH. The proposed graph, represents data relationships between functionalities in our program. Each node represents a functionality and each edge indicates a data dependency. The direction of the edge is used to identify the producer and the consumer, which is the edge pointed by the arrow. In our example we have a root and A and B can be executed in parallel. C has two data dependencies: one from A and one from B, while D needs only the data computed by B. E depends on D, and finally, F on E. A basic starting scenario is one in which we are working with a complete reconfiguration. Within this context, at design time, we are trying to combine the functionalities to maximise the usage of the available resources by providing the best execution time. Just to give you an example: within our example does not make any sense to combine functionality A and D together. Why? Quite simple! D needs the computation of B to start its own. That means that the first configuration of the FPGA with A and D is not getting any advantages by having D implemented at that time on the FPGA. Said that, we have to try to identify an interesting candidate to be executed with A. As it can be seen, this is B. Now, once that the first configuration of the FPGA has been identified we can move to the second one. We have at least two options: D and C, or D and E Having D and E at the same time on the FPGA does not seem to be a great idea because E depends on D. Having C and D at the same time seems to be interesting because they can start their executions at the same time and, by doing this, we have the second configuration. Now, we do have two more functionalities: E and F that can be implemented at the same time on the FPGA. This is a feasible solution but, as we can see, we are WASTING TIME. Wasting time means that we have resources that are available on the device that are not used by any computation, and this is the case of RR1 and RR2 after the execution of A. B is requiring two time unit to complete its execution and that means that we cannot configure the FPGA till it’ll be done with its execution. We need a better solution and we are going to have by using a partial dynamic reconfiguration instead of a complete one Within this context we can fully appreciate the benefits of using a partial dynamic reconfiguration. As soon as A is done with its computation we can reconfigure those regions to host the new functionality, in this example C. Obviously C cannot start its execution even if it is configured on the device, and it is because it needs the data computed by B. Once that B is done we can start C right away while we have to configure D before starting its execution. Within this context we can see that the reconfiguration of C is hidden by the execution of B, while the reconfiguration of E is hidden by the execution of C and finally the reconfiguration of F is hidden by the execution of E.