<jupyter_start><jupyter_text>Using Dynamic IP on the Composable Pipeline----Please use Jupyter labs http://&lt;board_ip_address&gt;/lab for this notebook.This notebook shows your how to load dynamic IP and compose branched pipelines Aims* Load dynamic IP* Compose branched pipelines Table of Contents* [Download Composable Overlay](download)* [Start HDMI Video](start_hdmi)* [Load Dynamic IP](dynamic)* [Let us Compose](compose)* [Branched Pipeline](branched)* [Conflicting Dynamic IP](conflicting)* [Stop HDMI Video](stop_hdmi)* [Conclusion](conclusion)---- Revision History* v1.0 | 30 March 2021 | First notebook revision.----  Download Composable Overlay Import the pynq video libraries as well as ComposableOverlay class and the drivers for the IP.Download the Composable Overlay using the `ComposableOverlay` and grab a handler to the `composable` hierarchy<jupyter_code>from pynq.lib.video import *
from composable_pipeline import ComposableOverlay
from composable_pipeline.libs import *

ol = ComposableOverlay("../overlay/cv_dfx_4_pr.bit")

cpipe = ol.composable<jupyter_output><empty_output><jupyter_text>Start HDMI Video Get `HDMIVideo` object and start video    Warning:Failure to connect HDMI cables to a valid video source and screen may cause the notebook to hang<jupyter_code>video = HDMIVideo(ol)
video.start()<jupyter_output><empty_output><jupyter_text>Load Dynamic IP The Composable Overlay provides DFX regions where IP can be loaded dynamically to bring new functionality. If we want to load an IP within a DFX region, the `.loadIP` method is used. Let us start by looking at the `.c_dict` to see what IP cores are loaded<jupyter_code>cpipe.c_dict.loaded<jupyter_output><empty_output><jupyter_text>The documentation of `.loadIP` specify that IP can be loaded using the full name or the IP object<jupyter_code>cpipe.loadIP?
cpipe.loadIP([cpipe.pr_1.dilate_accel])<jupyter_output><empty_output><jupyter_text>Examine the `.c_dict` again and verify that `dilate_accel` and `erode_accel` are indeed loaded, both are in the same DFX region<jupyter_code>cpipe.c_dict.loaded<jupyter_output><empty_output><jupyter_text>Let us Compose Grab handlers to these dynamic IP objects and compose a pipeline with them<jupyter_code>video_in_in = cpipe.video.hdmi_in.color_convert
video_in_out = cpipe.video.hdmi_in.pixel_pack

dilate = cpipe.pr_1.dilate_accel
cpipe.compose([video_in_in, dilate, video_in_out])

cpipe.graph<jupyter_output><empty_output><jupyter_text>Branched Pipeline In this part of the notebook, we will bring new functionality into the four DFX regions to compose the [Difference of Gaussians](https://en.wikipedia.org/wiki/Difference_of_Gaussians) application that was also introduced in the previous session. Load dynamic IP, grab handlers and set up default values<jupyter_code>cpipe.loadIP(['pr_fork/duplicate_accel', 'pr_join/subtract_accel', 'pr_0/filter2d_accel'])
filter2d = cpipe.video.composable.filter2d_accel
duplicate = cpipe.pr_fork.duplicate_accel
subtract = cpipe.pr_join.subtract_accel
fifo = cpipe.pr_0.axis_data_fifo_1
filter2d_d = cpipe.pr_0.filter2d_accel

filter2d.sigma = 0.3
filter2d.kernel_type = 'gaussian_blur'

filter2d_d.sigma = 12
filter2d_d.kernel_type = 'gaussian_blur'<jupyter_output><empty_output><jupyter_text>The Difference of Gaussians is realized by subtracting one Gaussian blurred version of an original image from another less blurred version of the original. In the Composable Overlay this is achieved by branching the pipeline, which is expressed as a list of a list.<jupyter_code>video_pipeline = [video_in_in, filter2d, duplicate, [[filter2d_d], [1]], subtract, video_in_out]

cpipe.compose(video_pipeline)

cpipe.graph<jupyter_output><empty_output><jupyter_text>Conflicting Dynamic IP Note that IP within the DFX regions are often mutually exclusive (some DFX regions support multiple IP at the same time), this means that they cannot be loaded at the same time. The `.loadIP` will raise an exception in these cases, try it by yourself running the following cell<jupyter_code>cpipe.loadIP(['pr_fork/duplicate_accel', 'pr_fork/colorthresholding_accel'])<jupyter_output><empty_output><jupyter_text>Info! Use the dfx_dict attribute to identify which IP are mutually exclusive  Stop HDMI Video Finally stop the HDMI video pipeline    Warning:Failure to stop the HDMI Video may hang the board when trying to download another bitstream onto the FPGA<jupyter_code>video.stop()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07590685176892073, 'fraction_numerical': 0.006941334527541424, 'mean_word_length': 6.688468158347677, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 41, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '63754', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1445, 'n_tokens_neox': 1386, 'n_words': 456, 'path': 'composable_pipeline/notebooks/custom_pipeline/05_dynamic_ip.ipynb', 'repo_name': 'mariodruiz/PYNQ_Composable_Pipeline', 'size': '4466'}