{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Lab: MicroBlaze\n", "\n", "Let's take a look inside the [BaseOverlay class](https://github.com/Xilinx/PYNQ/blob/master/boards/Pynq-Z1/base/base.py) which corresponds to the Overlay below: \n", "\n", "![](http://pynq.readthedocs.io/en/v2.0/_images/pynqz1_base_overlay.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's load the base overlay and check the IO Processors: iop_arduino, iop_pmoda, and iop_pmodb" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "import pynq\n", "from pynq.overlays.base import BaseOverlay\n", "\n", "ol = BaseOverlay(\"base.bit\")" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'audio_direct_0': {'addr_range': 65536,\n", " 'driver': pynq.lib.audio.AudioDirect,\n", " 'fullpath': 'audio_direct_0',\n", " 'gpio': {'sel_direct': {'index': 3,\n", " 'pins': {'audio_direct_0/sel_direct', 'audio_path_sel/Dout'},\n", " 'state': None}},\n", " 'interrupts': {},\n", " 'phys_addr': 1136656384,\n", " 'state': None,\n", " 'type': 'xilinx.com:user:audio_direct:1.1'},\n", " 'btns_gpio': {'addr_range': 65536,\n", " 'driver': pynq.lib.axigpio.AxiGPIO,\n", " 'fullpath': 'btns_gpio',\n", " 'gpio': {},\n", " 'interrupts': {'ip2intc_irpt': {'controller': 'system_interrupts',\n", " 'fullpath': 'btns_gpio/ip2intc_irpt',\n", " 'index': 11}},\n", " 'phys_addr': 1092681728,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_gpio:2.0'},\n", " 'iop_arduino/mb_bram_ctrl': {'addr_range': 65536,\n", " 'fullpath': 'iop_arduino/mb_bram_ctrl',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 1140850688,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_bram_ctrl:4.0'},\n", " 'iop_pmoda/mb_bram_ctrl': {'addr_range': 65536,\n", " 'fullpath': 'iop_pmoda/mb_bram_ctrl',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 1073741824,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_bram_ctrl:4.0'},\n", " 'iop_pmodb/mb_bram_ctrl': {'addr_range': 65536,\n", " 'fullpath': 'iop_pmodb/mb_bram_ctrl',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 1107296256,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_bram_ctrl:4.0'},\n", " 'leds_gpio': {'addr_range': 65536,\n", " 'driver': pynq.lib.axigpio.AxiGPIO,\n", " 'fullpath': 'leds_gpio',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 1092943872,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_gpio:2.0'},\n", " 'rgbleds_gpio': {'addr_range': 65536,\n", " 'driver': pynq.lib.axigpio.AxiGPIO,\n", " 'fullpath': 'rgbleds_gpio',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 1092878336,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_gpio:2.0'},\n", " 'switches_gpio': {'addr_range': 65536,\n", " 'driver': pynq.lib.axigpio.AxiGPIO,\n", " 'fullpath': 'switches_gpio',\n", " 'gpio': {},\n", " 'interrupts': {'ip2intc_irpt': {'controller': 'system_interrupts',\n", " 'fullpath': 'switches_gpio/ip2intc_irpt',\n", " 'index': 12}},\n", " 'phys_addr': 1092616192,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_gpio:2.0'},\n", " 'system_interrupts': {'addr_range': 65536,\n", " 'driver': pynq.overlay.DefaultIP,\n", " 'fullpath': 'system_interrupts',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 1098907648,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_intc:4.1'},\n", " 'trace_analyzer_arduino/axi_dma_0': {'addr_range': 65536,\n", " 'fullpath': 'trace_analyzer_arduino/axi_dma_0',\n", " 'gpio': {},\n", " 'interrupts': {'s2mm_introut': {'controller': 'system_interrupts',\n", " 'fullpath': 'trace_analyzer_arduino/axi_dma_0/s2mm_introut',\n", " 'index': 7}},\n", " 'phys_addr': 2151743488,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_dma:7.1'},\n", " 'trace_analyzer_arduino/trace_cntrl_64_0': {'addr_range': 65536,\n", " 'fullpath': 'trace_analyzer_arduino/trace_cntrl_64_0',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 2210398208,\n", " 'state': None,\n", " 'type': 'xilinx.com:hls:trace_cntrl_64:1.4'},\n", " 'trace_analyzer_pmoda/axi_dma_0': {'addr_range': 65536,\n", " 'fullpath': 'trace_analyzer_pmoda/axi_dma_0',\n", " 'gpio': {},\n", " 'interrupts': {'s2mm_introut': {'controller': 'system_interrupts',\n", " 'fullpath': 'trace_analyzer_pmoda/axi_dma_0/s2mm_introut',\n", " 'index': 6}},\n", " 'phys_addr': 2151677952,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_dma:7.1'},\n", " 'trace_analyzer_pmoda/trace_cntrl_32_0': {'addr_range': 65536,\n", " 'fullpath': 'trace_analyzer_pmoda/trace_cntrl_32_0',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 2210463744,\n", " 'state': None,\n", " 'type': 'xilinx.com:hls:trace_cntrl_32:1.4'},\n", " 'video/axi_vdma': {'addr_range': 65536,\n", " 'fullpath': 'video/axi_vdma',\n", " 'gpio': {},\n", " 'interrupts': {'mm2s_introut': {'controller': 'system_interrupts',\n", " 'fullpath': 'video/axi_vdma/mm2s_introut',\n", " 'index': 1},\n", " 's2mm_introut': {'controller': 'system_interrupts',\n", " 'fullpath': 'video/axi_vdma/s2mm_introut',\n", " 'index': 0}},\n", " 'phys_addr': 1124073472,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_vdma:6.3'},\n", " 'video/hdmi_in/color_convert': {'addr_range': 65536,\n", " 'fullpath': 'video/hdmi_in/color_convert',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 1136984064,\n", " 'state': None,\n", " 'type': 'xilinx.com:hls:color_convert:1.0'},\n", " 'video/hdmi_in/frontend/axi_gpio_hdmiin': {'addr_range': 65536,\n", " 'fullpath': 'video/hdmi_in/frontend/axi_gpio_hdmiin',\n", " 'gpio': {},\n", " 'interrupts': {'ip2intc_irpt': {'controller': 'system_interrupts',\n", " 'fullpath': 'video/hdmi_in/frontend/axi_gpio_hdmiin/ip2intc_irpt',\n", " 'index': 4}},\n", " 'phys_addr': 1092747264,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_gpio:2.0'},\n", " 'video/hdmi_in/frontend/vtc_in': {'addr_range': 65536,\n", " 'fullpath': 'video/hdmi_in/frontend/vtc_in',\n", " 'gpio': {},\n", " 'interrupts': {'irq': {'controller': 'system_interrupts',\n", " 'fullpath': 'video/hdmi_in/frontend/vtc_in/irq',\n", " 'index': 3}},\n", " 'phys_addr': 1136852992,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:v_tc:6.1'},\n", " 'video/hdmi_in/pixel_pack': {'addr_range': 65536,\n", " 'fullpath': 'video/hdmi_in/pixel_pack',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 1136918528,\n", " 'state': None,\n", " 'type': 'xilinx.com:hls:pixel_pack:1.0'},\n", " 'video/hdmi_out/color_convert': {'addr_range': 65536,\n", " 'fullpath': 'video/hdmi_out/color_convert',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 1137049600,\n", " 'state': None,\n", " 'type': 'xilinx.com:hls:color_convert:1.0'},\n", " 'video/hdmi_out/frontend/axi_dynclk': {'addr_range': 65536,\n", " 'fullpath': 'video/hdmi_out/frontend/axi_dynclk',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 1136721920,\n", " 'state': None,\n", " 'type': 'digilentinc.com:ip:axi_dynclk:1.0'},\n", " 'video/hdmi_out/frontend/hdmi_out_hpd_video': {'addr_range': 65536,\n", " 'fullpath': 'video/hdmi_out/frontend/hdmi_out_hpd_video',\n", " 'gpio': {},\n", " 'interrupts': {'ip2intc_irpt': {'controller': 'system_interrupts',\n", " 'fullpath': 'video/hdmi_out/frontend/hdmi_out_hpd_video/ip2intc_irpt',\n", " 'index': 5}},\n", " 'phys_addr': 1092812800,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:axi_gpio:2.0'},\n", " 'video/hdmi_out/frontend/vtc_out': {'addr_range': 65536,\n", " 'fullpath': 'video/hdmi_out/frontend/vtc_out',\n", " 'gpio': {},\n", " 'interrupts': {'irq': {'controller': 'system_interrupts',\n", " 'fullpath': 'video/hdmi_out/frontend/vtc_out/irq',\n", " 'index': 2}},\n", " 'phys_addr': 1136787456,\n", " 'state': None,\n", " 'type': 'xilinx.com:ip:v_tc:6.1'},\n", " 'video/hdmi_out/pixel_unpack': {'addr_range': 65536,\n", " 'fullpath': 'video/hdmi_out/pixel_unpack',\n", " 'gpio': {},\n", " 'interrupts': {},\n", " 'phys_addr': 1137115136,\n", " 'state': None,\n", " 'type': 'xilinx.com:hls:pixel_unpack:1.0'}}" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ol.ip_dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some PMODs already have drivers: [list of plug and play PMODs](/tree/base/pmod)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "from pynq.lib import Pmod_OLED\n", "pmod_oled = Pmod_OLED(ol.PMODA)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "pmod_oled.clear()\n", "pmod_oled.write('Welcome to \\n\\nPYNQ!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's take a look at it's code on [pynq github](https://github.com/Xilinx/PYNQ/tree/master/pynq/lib/pmod)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Hello World on Microblaze\n", "IO prrocessors can also be used for running small applications.\n", "\n", "[IPYthon magic](https://ipython.readthedocs.io/en/stable/interactive/magics.html) allow the execution of Non-Python code in a Python cell." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from pynq.lib import MicroblazeLibrary" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%microblaze ol.PMODA\n", "#include \n", "\n", "int mb_print(){\n", " pyprintf(\"Hello World!\");\n", " return 0;\n", "}\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mb_print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 1\n", "Here you learn how to use provided python libraries.\n", "\n", "Using the source code for [RGBLED](https://github.com/Xilinx/PYNQ/blob/master/pynq/lib/rgbled.py) write a for loop to change the coloring of your rgb leds between red, blue, and white similar to a police light bar. You can use *time.sleep* as delay between flashes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import time\n", "# write code for RGBLED" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 2\n", "Write a microblaze code to calculate factorial of an input on PL. Your result should be same as the python code output." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%microblaze ol.PMODB\n", "\n", "int mb_fact(int in){\n", "//write code here\n", "}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "inp = 10\n", "\n", "print('out = {}'.format(mb_fact(inp))) # your function is called here, note the function prototype\n", "\n", "ff=1\n", "for i in range(1,inp+1):\n", " ff = ff*i\n", "print('ans = {}'.format(ff))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 3\n", "Use the [source code](https://github.com/Xilinx/PYNQ/blob/master/pynq/lib/pmod/pmod_oled/src/pmod_oled.c) for OLED_PMOD to learn how to use the GPIO pins.\n", "\n", "Write two microblaze functions: *mba_send(v)* and *mbb_recv()* to send 1-bit accross the two PMODs *A* and *B*.\n", "\n", "You need to connect pin 0 of the two PMODs using a jumper wire.\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "%%microblaze ol.PMODA\n", "#include \n", "\n", "int mba_send(int v){\n", "//write code here\n", "}" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "%%microblaze ol.PMODB\n", "#include \n", "\n", "int mbb_recv(){\n", "//write code here\n", "}" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "mba_send(1)\n", "print(mbb_recv())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Task 4\n", "\n", "Read voltages from the Pmod_AD2. **Since there are only 2 Pmod_AD2. Write the code to the best of your ability and ask one of the TA's to check before testing on the Pmod_AD2.**\n", "\n", "* The first part of this task is to only use the pynq python libraries. You can reference the API [here](https://pynq.readthedocs.io/en/v2.0/pynq_package/pynq.lib/pynq.lib.pmod.html#). *Remember to close the pmod instance*" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "# write code here" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* For the second part of the task, we'll see how to communicate with the Pmod_AD2 by programming the microblaze in C. While this is more work, most of the PMODS we have available do not have python libraries pre-built so you'll need to search through the documentation and program the microblaze in order to use them.\n", "\n", "[microblaze libraries for pynq](https://pynq.readthedocs.io/en/latest/pynq_libraries/pynqmb_reference.html)\n", "\n", "[Pmod_AD2 reference manual](https://reference.digilentinc.com/reference/pmod/pmodad2/reference-manual)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%microblaze base.PMODA\n", "#include \n", "#include \n", "\n", "//TODO: Find the pmod_ad2 address value\n", "#define AD2IICAddr <#>\n", "\n", "//Configuration\n", "#define CH3 7\n", "#define CH2 6\n", "#define CH1 5\n", "#define CH0 4\n", "#define REF_SEL 3\n", "#define FLTR 2\n", "#define BitTrialDelay 1\n", "#define SampleDelay 0\n", "\n", "#define BitMask 0xFFF\n", "\n", "float read_i2c() {\n", " \n", " //TODO: open a new i2c device\n", " \n", " unsigned char WriteBuffer[1]; \n", " unsigned char cfgValue = (1 << CH3) |\n", " (1 << CH2) |\n", " (1 << CH1) |\n", " (1 << CH0) |\n", " (0 << REF_SEL) |\n", " (0 << FLTR) |\n", " (0 << BitTrialDelay) |\n", " (0 << SampleDelay);\n", " WriteBuffer[0]=cfgValue;\n", " //TODO: write the configuration to the pmod (1 byte)\n", " \n", " //Receiving data.\n", " unsigned char rcvbuffer[2];\n", " int rxData;\n", " //TODO: read from the pmod and format the raw data (2 bytes)\n", " // The first byte is MSB, while the second byte is LSB\n", " rxData = //;\n", " \n", " \n", " //Format as a voltage\n", " int raw = (rxData & BitMask); \n", " return (float)(raw * 2.00 / 4096.0); // 2.0 V is the reference voltage for the AD2 Pmod.\n", "}" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }