BELK-TN-005: Running PYNQ on Bora
- 1 History
- 2 Introduction
- 3 Testbed's Hardware and Software Configuration
- 4 Setting Up the Board
- 5 Testing the PYNQ Framework
- 5.1 Basic Operations
- 5.2 Editing and executing Python functions
- 5.3 Implementing a Hardware-Accelerated Version of the FIR Filter in PL
|September 2018||First public release|
|1.1.0||November 2018||Moved to PYNQ 2.3|
Added sections about FIR filter implementation and testing
As stated in the official documentation, Python Productivity for Zynq (Pynq)'s main goal is ...
This Technical Note shows hot to run PYNQ on Bora platform. It is worth remembering that, even though the procedure was tested on Bora, it should work on BoraX as well without any modification.
To see PYNQ in action, please see this clip.
Testbed's Hardware and Software Configuration
As stated before, the procedure was tested on Bora/BoraEVB hardware platform.
With regard to the software configuration, the following versions were used:
- U-Boot 2018.1 (at the time of this writing, this version was not officially supported by any BELK release yet)
- Linux kernel 4.14.0 (at the time of this writing, this version was not officially supported by any BELK release yet)
- Root filesystem: extracted from Pynq-Z1 v2.3 image and mounted from microSD card.
Original root file system included several kernel drivers built as modules. The Linux kernel used for this test was different than the kernel released along with the PYNQ's root file system, however. Consequently, these modules were not compatible with the kernel running on Bora. To overcome this issue, these drivers were linked statically into the kernel image.
Setting Up the Board
U-Boot environment was configured in order to retrieve the kernel image and the device tree blob from the microSD card. Also, it was configured to make the kernel to mount the root file system from a partition of the microSD card.
The following box shows the full boot process (clock on the "Expand" box):
U-Boot 2018.01-00022-g322f20f (Aug 28 2018 - 11:20:19 +0200) Model: Bora Board: Xilinx Zynq Silicon: v3.1 I2C: ready DRAM: ECC disabled 1 GiB Relocating to 3ff22000, new gd at 3eae1ee8, sp at 3eae1ec0 NAND: 1024 MiB MMC: sdhci@e0100000: 0 (SD) SF: Detected s25fl256s_64k with page size 256 Bytes, erase size 64 KiB, total 3B In: serial@e0001000 Out: serial@e0001000 Err: serial@e0001000 SF: Detected s25fl256s_64k with page size 256 Bytes, erase size 64 KiB, total 3B SF: Detected s25fl256s_64k with page size 256 Bytes, erase size 64 KiB, total 3B SOM ConfigID#: 00000001 SOM UniqueID#: 01234567:89abcdef ds2431_readmem(): error in chip reset ds2431_readmem(): error in reading buffer ds2431_readmem(): error in chip reset ds2431_readmem(): error in reading buffer CB ConfigID CRC mismatch for 0x00000000 (was 0x00000000, expected 0x2144df1c) at CB ConfigID#: ffffffff CB UniqueID#: 00000000:00000000 Net: ZYNQ GEM: e000b000, phyaddr 7, interface rgmii-id eth0: ethernet@e000b000 Hit ENTER within 3 seconds to stop autoboot reading uImage 4140752 bytes read in 239 ms (16.5 MiB/s) reading bora.dtb 10678 bytes read in 13 ms (801.8 KiB/s) FDT: property som_configid FDT: override 'som_configid' with '00000001' FDT: property cb_configid does not match ## Booting kernel from Legacy Image at 02080000 ... Image Name: Linux-4.14.0-xilinx-00009-g30fab Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 4140688 Bytes = 3.9 MiB Load Address: 00008000 Entry Point: 00008000 Verifying Checksum ... OK ## Flattened Device Tree blob at 02000000 Booting using the fdt blob at 0x2000000 Loading Kernel Image ... OK Loading Device Tree to 1effa000, end 1efff9b5 ... OK Switching to NAND storage before starting Linux Starting kernel ... Uncompressing Linux... done, booting the kernel. [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 4.14.0-xilinx-00009-g30fabf3-dirty (sysadmin@stage8 [ 0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instructie [ 0.000000] OF: fdt: Machine model: Bora [ 0.000000] bootconsole [earlycon0] enabled [ 0.000000] Memory policy: Data cache writealloc [ 0.000000] cma: Reserved 16 MiB at 0x3f000000 [ 0.000000] On node 0 totalpages: 262144 [ 0.000000] free_area_init_node: node 0, pgdat c0a3e2c0, node_mem_map ef6f700 [ 0.000000] Normal zone: 1728 pages used for memmap [ 0.000000] Normal zone: 0 pages reserved [ 0.000000] Normal zone: 196608 pages, LIFO batch:31 [ 0.000000] HighMem zone: 65536 pages, LIFO batch:15 [ 0.000000] random: fast init done [ 0.000000] percpu: Embedded 16 pages/cpu @ef6cd000 s35340 r8192 d22004 u6556 [ 0.000000] pcpu-alloc: s35340 r8192 d22004 u65536 alloc=16*4096 [ 0.000000] pcpu-alloc:  0  1 [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 260416 [ 0.000000] Kernel command line: root=/dev/mmcblk0p2 rootwait rw console=tty) [ 0.000000] PID hash table entries: 4096 (order: 2, 16384 bytes) [ 0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes) [ 0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) [ 0.000000] Memory: 1011668K/1048576K available (6144K kernel code, 301K rwd) [ 0.000000] Virtual kernel memory layout: [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB) [ 0.000000] vmalloc : 0xf0800000 - 0xff800000 ( 240 MB) [ 0.000000] lowmem : 0xc0000000 - 0xf0000000 ( 768 MB) [ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB) [ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB) [ 0.000000] .text : 0xc0008000 - 0xc0700000 (7136 kB) [ 0.000000] .init : 0xc0900000 - 0xc0a00000 (1024 kB) [ 0.000000] .data : 0xc0a00000 - 0xc0a4b730 ( 302 kB) [ 0.000000] .bss : 0xc0a51640 - 0xc0a9156c ( 256 kB) [ 0.000000] Preemptible hierarchical RCU implementation. [ 0.000000] RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2. [ 0.000000] Tasks RCU enabled. [ 0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2 [ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16 [ 0.000000] efuse mapped to f0802000 [ 0.000000] slcr mapped to f0804000 [ 0.000000] L2C: platform modifies aux control register: 0x02060000 -> 0x3240 [ 0.000000] L2C: DT/platform modifies aux control register: 0x02060000 -> 0x0 [ 0.000000] L2C-310 erratum 769419 enabled [ 0.000000] L2C-310 enabling early BRESP for Cortex-A9 [ 0.000000] L2C-310 full line of zeros enabled for Cortex-A9 [ 0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled [ 0.000000] L2C-310 cache controller enabled, 8 ways, 512 kB [ 0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x46460001 [ 0.000000] zynq_clock_init: clkc starts at f0804100 [ 0.000000] Zynq clock init [ 0.000000] ps_clk frequency not specified, using 33 MHz. [ 0.000012] sched_clock: 64 bits at 333MHz, resolution 3ns, wraps every 4398s [ 0.007869] clocksource: arm_global_timer: mask: 0xffffffffffffffff max_cycls [ 0.018887] Switching to timer-based delay loop, resolution 3ns [ 0.024890] clocksource: ttc_clocksource: mask: 0xffff max_cycles: 0xffff, ms [ 0.033942] timer #0 at f080c000, irq=17 [ 0.038284] Console: colour dummy device 80x30 [ 0.042621] Calibrating delay loop (skipped), value calculated using timer f) [ 0.053124] pid_max: default: 32768 minimum: 301 [ 0.057934] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes) [ 0.064426] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes) [ 0.072195] CPU: Testing write buffer coherency: ok [ 0.077177] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000 [ 0.118018] Setting up static identity map for 0x100000 - 0x100060 [ 0.124192] Hierarchical SRCU implementation. [ 0.167977] smp: Bringing up secondary CPUs ... [ 0.218359] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001 [ 0.218485] smp: Brought up 1 node, 2 CPUs [ 0.228186] SMP: Total of 2 processors activated (1333.33 BogoMIPS). [ 0.234494] CPU: All CPU(s) started in SVC mode. [ 0.240192] devtmpfs: initialized [ 0.246309] VFP support v0.3: implementor 41 architecture 3 part 30 variant 4 [ 0.254104] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, ms [ 0.263796] futex hash table entries: 512 (order: 3, 32768 bytes) [ 0.271171] pinctrl core: initialized pinctrl subsystem [ 0.277724] NET: Registered protocol family 16 [ 0.290094] DMA: preallocated 256 KiB pool for atomic coherent allocations [ 0.298458] cpuidle: using governor ladder [ 0.302469] cpuidle: using governor menu [ 0.313247] hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint. [ 0.321146] hw-breakpoint: maximum watchpoint size is 4 bytes. [ 0.327068] zynq-ocm f800c000.ocmc: ZYNQ OCM pool: 256 KiB @ 0xf0880000 [ 0.334169] zynq-pinctrl 700.pinctrl: zynq pinctrl initialized [ 0.340355] e0000000.serial: ttyPS1 at MMIO 0xe0000000 (irq = 27, base_baud s [ 0.349793] e0001000.serial: ttyPS0 at MMIO 0xe0001000 (irq = 28, base_baud s `+$$$$&i???????????????m???AM?u????????5)m???????58813] console [ttyPS0] enable[ 0.365860] bootconsole [earlycon0] disabled [ 0.365860] bootconsole [earlycon0] disabled [ 0.391828] vgaarb: loaded [ 0.394848] SCSI subsystem initialized [ 0.398856] usbcore: registered new interface driver usbfs [ 0.404322] usbcore: registered new interface driver hub [ 0.409684] usbcore: registered new device driver usb [ 0.414850] pps_core: LinuxPPS API ver. 1 registered [ 0.421049] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giom> [ 0.430186] PTP clock support registered [ 0.438162] FPGA manager framework [ 0.441748] fpga-region fpga-full: FPGA Region probed [ 0.447818] clocksource: Switched to clocksource arm_global_timer [ 0.464385] NET: Registered protocol family 2 [ 0.469379] TCP established hash table entries: 8192 (order: 3, 32768 bytes) [ 0.476433] TCP bind hash table entries: 8192 (order: 4, 65536 bytes) [ 0.482972] TCP: Hash tables configured (established 8192 bind 8192) [ 0.489406] UDP hash table entries: 512 (order: 2, 16384 bytes) [ 0.495287] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes) [ 0.501835] NET: Registered protocol family 1 [ 0.506513] RPC: Registered named UNIX socket transport module. [ 0.512397] RPC: Registered udp transport module. [ 0.517038] RPC: Registered tcp transport module. [ 0.521756] RPC: Registered tcp NFSv4.1 backchannel transport module. [ 0.528176] PCI: CLS 0 bytes, default 64 [ 0.532666] hw perfevents: no interrupt-affinity property for /pmu@f8891000,. [ 0.540745] hw perfevents: enabled with armv7_cortex_a9 PMU driver, 7 countee [ 0.550340] workingset: timestamp_bits=14 max_order=18 bucket_order=4 [ 0.557518] jffs2: version 2.2. (NAND) (SUMMARY) ?? 2001-2006 Red Hat, Inc. [ 0.566071] bounce: pool size: 64 pages [ 0.569999] io scheduler noop registered [ 0.573841] io scheduler deadline registered [ 0.578319] io scheduler cfq registered (default) [ 0.582938] io scheduler mq-deadline registered [ 0.587451] io scheduler kyber registered [ 0.593500] dma-pl330 f8003000.dmac: Loaded driver for PL330 DMAC-241330 [ 0.600167] dma-pl330 f8003000.dmac: DBUFF-128x8bytes Num_Chans-8 Nu6 [ 0.619150] brd: module loaded [ 0.630120] loop: module loaded [ 0.634849] libphy: Fixed MDIO Bus: probed [ 0.640197] CAN device driver interface [ 0.646007] libphy: MACB_mii_bus: probed [ 0.748568] macb e000b000.ethernet eth0: Cadence GEM rev 0x00020118 at 0xe00) [ 0.758351] Micrel KSZ9031 Gigabit PHY e000b000.ethernet-ffffffff:07: attach) [ 0.774459] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k [ 0.780234] e1000e: Copyright(c) 1999 - 2015 Intel Corporation. [ 0.787046] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver [ 0.793549] ehci-pci: EHCI PCI platform driver [ 0.798084] usbcore: registered new interface driver usb-storage [ 0.804265] chipidea-usb2 e0002000.usb: e0002000.usb supply vbus not found, r [ 0.813361] ULPI transceiver vendor/product ID 0x0424/0x0006 [ 0.818966] Found SMSC USB331x ULPI transceiver. [ 0.823545] ULPI integrity check: passed. [ 0.829554] i2c /dev entries driver [ 0.834590] rtc-ds3232 0-0068: oscillator discontinuity flagged, time unrelie [ 0.844360] rtc-ds3232 0-0068: rtc core: registered ds3232 as rtc0 [ 0.850581] cdns-i2c e0004000.i2c: 100 kHz mmio e0004000 irq 24 [ 0.856711] IR NEC protocol handler initialized [ 0.861182] IR RC5(x/sz) protocol handler initialized [ 0.866191] IR RC6 protocol handler initialized [ 0.870729] IR JVC protocol handler initialized [ 0.875218] IR Sony protocol handler initialized [ 0.879885] IR SANYO protocol handler initialized [ 0.884506] IR Sharp protocol handler initialized [ 0.889221] IR MCE Keyboard/mouse protocol handler initialized [ 0.895008] IR XMP protocol handler initialized [ 0.900782] ina2xx 0-0041: power monitor ina226 (Rshunt = 10000 uOhm) [ 0.908903] cdns-wdt f8005000.watchdog: Xilinx Watchdog Timer at f098f000 wis [ 0.917362] Xilinx Zynq CpuIdle Driver started [ 0.922177] sdhci: Secure Digital Host Controller Interface driver [ 0.928301] sdhci: Copyright(c) Pierre Ossman [ 0.932611] sdhci-pltfm: SDHCI platform and OF driver helper [ 0.997882] mmc0: SDHCI controller on e0100000.sdhci [e0100000.sdhci] using A [ 1.005617] usbcore: registered new interface driver usbhid [ 1.011141] usbhid: USB HID core driver [ 1.015101] xlnk xlnk: Major 246 [ 1.021504] xlnk xlnk: xlnk driver loaded [ 1.025455] xlnk xlnk: xlnk_pdev is not null [ 1.031043] nand: device found, Manufacturer ID: 0x01, Chip ID: 0xd3 [ 1.037334] nand: AMD/Spansion S34ML08G1 [ 1.041248] nand: 1024 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB s4 [ 1.052658] Bad block table found at page 524224, version 0x01 [ 1.059763] Bad block table found at page 524160, version 0x01 [ 1.066390] 8 ofpart partitions found on MTD device pl35x-nand [ 1.072164] Creating 8 MTD partitions on "pl35x-nand": [ 1.077262] 0x000000000000-0x000000040000 : "nand-SPL" [ 1.083630] 0x000000040000-0x000000100000 : "nand-uboot" [ 1.090029] 0x000000100000-0x000000140000 : "nand-uboot-env1" [ 1.096879] 0x000000140000-0x000000180000 : "nand-uboot-env2" [ 1.103695] 0x000000180000-0x000000780000 : "nand-bitstream" [ 1.110419] 0x000000780000-0x000000800000 : "nand-device-tree" [ 1.117252] 0x000000800000-0x000001000000 : "nand-linux" [ 1.123684] 0x000001000000-0x000020000000 : "nand-rootfs" [ 1.129119] mmc0: new high speed SDHC card at address 59b4 [ 1.135058] mmcblk0: mmc0:59b4 USDU1 7.51 GiB [ 1.140519] mmcblk0: p1 p2 [ 1.141949] fpga_manager fpga0: Xilinx Zynq FPGA Manager registered [ 1.142637] NET: Registered protocol family 17 [ 1.142656] can: controller area network core (rev 20170425 abi 9) [ 1.142727] NET: Registered protocol family 29 [ 1.142745] can: raw protocol (rev 20170425) [ 1.142751] can: broadcast manager protocol (rev 20170425 t) [ 1.142761] can: netlink gateway (rev 20170425) max_hops=1 [ 1.143201] Registering SWP/SWPB emulation handler [ 1.150741] rtc-ds3232 0-0068: hctosys: unable to read the hardware clock [ 1.194018] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incoms [ 1.401631] EXT4-fs (mmcblk0p2): recovery complete [ 1.408763] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. ) [ 1.416811] VFS: Mounted root (ext4 filesystem) on device 179:2. [ 1.424413] devtmpfs: mounted [ 1.430489] Freeing unused kernel memory: 1024K [ 1.962437] systemd: System time before build time, advancing clock. [ 2.053678] systemd: systemd 237 running in system mode. (+PAM +AUDIT +SE) [ 2.075084] systemd: No virtualization found in DMI [ 2.080193] systemd: No virtualization found in CPUID [ 2.085472] systemd: Virtualization XEN not found, /proc/xen does not exit [ 2.092904] systemd: No virtualization found in /proc/device-tree/* [ 2.099533] systemd: No virtualization found in /proc/cpuinfo. [ 2.105561] systemd: This platform does not support /proc/sysinfo [ 2.111936] systemd: Found VM virtualization none [ 2.116853] systemd: Detected architecture arm. [ 2.129403] systemd: Mounting cgroup to /sys/fs/cgroup/cpuset of type cgr. Welcome to PynqLinux, based on Ubuntu 18.04! [ 2.327802] systemd-gpt-auto-generator: /dev/mmcblk0p2: root device /de. [ 2.347055] systemd-fstab-generator: Parsing /etc/fstab [ 2.367721] systemd-getty-generator: Automatically adding serial getty . [ 2.383535] systemd-fstab-generator: Found entry what=/var/swap where=no [ 2.394393] systemd-fstab-generator: Swap not supported, ignoring fstab. [ 2.396033] systemd-sysv-generator: Native unit for binfmt-support.serv. [ 2.404927] systemd-sysv-generator: Native unit for dbus.service alread. [ 2.405867] systemd-sysv-generator: Native unit for 2ping.service alrea. [ 2.422705] systemd-sysv-generator: Native unit for ssh.service already. [ 2.439590] systemd-sysv-generator: Native unit for resolvconf.service . [ 2.449886] systemd-sysv-generator: Native unit for rsync.service alrea. [ 2.466783] systemd-sysv-generator: Native unit for hwclock.service alr. [ 2.477732] systemd-sysv-generator: Native unit for udev.service alread. [ 2.486743] systemd-sysv-generator: Cannot find unit cpufrequtils.servi. [ 2.495013] systemd-sysv-generator: Native unit for rsyslog.service alr. [ 2.612620] systemd-gpt-auto-generator: No suitable partition table fou. [ 2.632294] systemd-sysv-ge: 72 output lines suppressed due to ratelimiting [ OK ] Created slice User and Session Slice. [ OK ] Created slice System Slice. [ OK ] Listening on Syslog Socket. [ OK ] Reached target System Time Synchronized. [ OK ] Listening on /dev/initctl Compatibility Named Pipe. [ OK ] Listening on udev Control Socket. [ OK ] Created slice system-getty.slice. [ OK ] Listening on udev Kernel Socket. [ OK ] Started ntp-systemd-netif.path. [ OK ] Listening on Journal Socket. Starting Restore / save the current clock... Mounting Kernel Debug File System... [ OK ] Listening on Journal Socket (/dev/log). Starting Journal Service... [ 3.407066] systemd: Operating on architecture: arm [ 3.414031] systemd: Operating on architecture: arm [ 3.419607] systemd: Operating on architecture: arm [ 3.425049] systemd: Restricting namespace to: . [ 3.430138] systemd: Operating on architecture: arm [ 3.435508] systemd: Blocking cgroup. Starting Create Static Device Nodes in /dev... [ 3.439657] systemd: Blocking ipc. [ 3.448528] systemd: Blocking net. [ 3.452384] systemd: Blocking mnt. [ 3.456241] systemd: Blocking pid. [ 3.460181] systemd: Blocking user. [ 3.464128] systemd: Blocking uts. [ 3.468467] systemd: Operating on architecture: arm [ 3.473876] systemd: Failed to add rule for system call mpx() / -10030,n [ 3.484747] systemd: Failed to add rule for system call security() / -1n [ 3.496026] systemd: Failed to add rule for system call tuxcall() / -10n [ 3.507233] systemd: Failed to add rule for system call get_kernel_symsn [ 3.519123] systemd: Failed to add rule for system call kexec_file_loadn [ 3.531046] systemd: Failed to add rule for system call spu_run() / -10n [ OK [ 3.542268] systemd: Failed to add rule for system call iopl() /n [ 3.554737] systemd: Failed to add rule for system call putpmsg() / -10n [ 3.565922] systemd: Failed to add rule for system call rtas() / -10187n ] [ 3.576844] systemd: Failed to add rule for system call prof() / -100n Started Dispatch Password Requests to Console Directory Watch. [ 3.587946] systemd: Failed to add rule for system call break() / -1000n [ 3.604337] systemd: Failed to add rule for system call modify_ldt() / n [ 3.615755] systemd: Failed to add rule for system call s390_pci_mmio_wn [ 3.627969] systemd: Failed to add rule for system call profil() / -100n [ 3.639044] systemd: Failed to add rule for system call vm86old() / -10n [ 3.650184] systemd: Failed to add rule for system call ssetmask() / -1n [ 3.661428] systemd: Failed to add rule for system call stty() / -10065n [[ 3.672357] systemd: Failed to add rule for system call umount() / -10n OK ] Created slice system-serial\x2dgetty.slice. [ 3.683529] systemd: Failed to add rule for system call idle() / -10023n [ 3.699932] systemd: Failed to add rule for system call sgetmask() / -1n [ 3.711182] systemd: Failed to add rule for system call switch_endian()n [ 3.722844] systemd: Failed to add rule for system call stime() / -1006n [ 3.733813] systemd: Failed to add rule for system call afs_syscall() /n [ 3.745317] systemd: Failed to add rule for system call ulimit() / -100n [ OK [ 3.756411] systemd: Failed to add rule for system call gtty() /n ] Reached target Swap. [ 3.768851] systemd: Failed to add rule for system call s390_pci_mmio_rn [ 3.782994] systemd: Failed to add rule for system call query_module() n [ 3.794602] systemd: Failed to add rule for system call vm86() / -10071n [ 3.805488] systemd: Failed to add rule for system call ftime() / -1001n [ 3.816452] systemd: Failed to add rule for system call ioperm() / -100n [ 3.827506] systemd: Failed to add rule for system call create_module()n [ 3.839168] systemd: Failed to add rule for system call lock() / -10027n [ OK [ 3.850068] systemd: Failed to add rule for system call getpmsg(n ] Reached target Slices. [ 3.862759] systemd: Failed to add rule for system call s390_runtime_inn Starting Remount Root and Kernel File Systems... [ 3.909061] systemd-journald: Found cgroup2 on /sys/fs/cgroup/unified, r [ 3.922659] systemd-journald: Fixed min_use=1.0M max_use=50.2M max_size0 [ 3.940166] systemd-journald: Reserving 11434 entries in hash table. [ 3.947461] systemd-journald: Vacuuming... [ 3.952153] systemd-journald: Vacuuming done, freed 0B of archived jour. [ 3.964548] systemd-journald: Flushing /dev/kmsg... Starting Nameserver information manager...[ 3.969888] systemd-journ7 [ 3.982554] systemd-journald: /dev/kmsg buffer overrun, some messages l. Starting udev Coldplug all Devices... [ 4.045414] systemd-journald: Sent READY=1 notification. [ 4.051488] systemd-journald: Sent WATCHDOG=1 notification. [ OK ] Started Forward Password Requests to Wall Directory Watch. [ OK ] Reached target Local Encrypted Volumes. Starting Load Kernel Modules... [ OK ] Reached target Remote File Systems. Mounting POSIX Message Queue File System... [ OK ] Started Journal Service. [ OK ] Started Restore / save the current clock. [ OK ] Mounted Kernel Debug File System. [ OK ] Started Create Static Device Nodes in /dev. [ OK ] Started Remount Root and Kernel File Systems. [ OK ] Started Load Kernel Modules. [ OK ] Mounted POSIX Message Queue File System. [ OK ] Started Nameserver information manager. [ OK ] Reached target Network (Pre). Starting Apply Kernel Variables... Mounting Kernel Configuration File System... Starting Load/Save Random Seed... [ OK ] Reached target Local File Systems (Pre). [ OK ] Reached target Local File Systems. Starting Enable support for additional executable binary formats... Starting udev Kernel Device Manager... Starting Flush Journal to Persistent Storage... [ OK ] Started udev Coldplug all Devices. [ OK ] Started Apply Kernel Variables. [ OK ] Mounted Kernel Configuration File System. [ OK ] Started udev Kernel Device Manager. [ OK ] Started Load/Save Random Seed. [ OK ] Started Enable support for additional executable binary formats. Starting Raise network interfaces... [ OK ] Found device /dev/ttyPS0. [ OK ] Started Flush Journal to Persistent Storage. Starting Create Volatile Files and Directories... [ OK ] Found device /sys/subsystem/net/devices/eth0. [ OK ] Started ifup for eth0. [ OK ] Started Create Volatile Files and Directories. Starting Network Time Synchronization... Starting Update UTMP about System Boot/Shutdown... Starting Network Name Resolution... [ OK ] Started Update UTMP about System Boot/Shutdown. [ OK ] Started Network Time Synchronization. [ OK ] Reached target System Initialization. [ OK ] Started Discard unused blocks once a week. [ OK ] Started Message of the Day. [ OK ] Started resolvconf-pull-resolved.path. [ OK ] Reached target Paths. [ OK ] Started Daily Cleanup of Temporary Directories. [ OK ] Started Daily apt download activities. [ OK ] Started Daily apt upgrade and clean activities. [ OK ] Reached target Timers. [ OK ] Listening on D-Bus System Message Bus Socket. [ OK ] Reached target Sockets. [ OK ] Reached target Basic System. [ OK ] Started ntp-systemd-netif.service. Starting Resize Filesystem on SD card... Starting PYNQ PL Server... Starting Login Service... Starting resolvconf-pull-resolved.service... [ OK ] Started Regular background program processing daemon. Starting System Logging Service... [ OK ] Started Set the CPU Frequency Scaling governor. Starting Jupyter Notebook Server... Starting LSB: Load kernel modules needed to enable cpufreq scaling... [ OK ] Started D-Bus System Message Bus. [ OK ] Started Login Service. Starting WPA supplicant... [ OK ] Started Network Name Resolution. [ OK ] Started System Logging Service. [ OK ] Started Resize Filesystem on SD card. [ OK ] Started PYNQ PL Server. [ OK ] Started resolvconf-pull-resolved.service. [ OK ] Started WPA supplicant. [ OK ] Reached target Host and Network Name Lookups. [ OK ] Started LSB: Load kernel modules needed to enable cpufreq scaling. Starting LSB: set CPUFreq kernel parameters... [ OK ] Started LSB: set CPUFreq kernel parameters. Stopping Network Name Resolution... [ OK ] Stopped Network Name Resolution. Starting Network Name Resolution... [ OK ] Started Network Name Resolution. Starting resolvconf-pull-resolved.service... [ OK ] Started resolvconf-pull-resolved.service. [ OK ] Started Raise network interfaces. [ OK ] Reached target Network. Starting OpenBSD Secure Shell server... [ OK ] Started Unattended Upgrades Shutdown. Starting Permit User Sessions... [ OK ] Reached target Network is Online. [ OK ] Started ISC DHCP IPv6 server. Starting Samba NMB Daemon... [ OK ] Started ISC DHCP IPv4 server. [ OK ] Started Permit User Sessions. [ OK ] Started Serial Getty on ttyPS0. [ OK ] Started Getty on tty1. [ OK ] Reached target Login Prompts. PYNQ Linux, based on Ubuntu 18.04 pynq ttyPS0 pynq login: xilinx (automatic login) Last login: Fri Oct 5 19:21:09 UTC 2018 from 192.168.2.10 on pts/0 Welcome to PYNQ Linux, based on Ubuntu 18.04 (GNU/Linux 4.14.0-xilinx-00009-g30) xilinx@pynq:~$
Testing the PYNQ Framework
The following image shows the PYNQ processes running.
To test the whole framework, the following testbed was used.
The test consisted of the following steps:
- First, a software implementation of an FIR filter was created
- A hardware implementation of the same FIR filter was generated using the FIR Compiler provided by Vivado.
- The resulting IP was instantiated in Programmable Logic (PL).
- Using Jupyter Notebooks, a simple Python test code was edited and run to exercise the filter.
- Two different approaches were used: generic driver and IP-specific driver.
This example was inspired by this tutorial.
- In order to open the Jupyter Notebook web dashboard, do the following steps:
- Open the browser (only Google Chrome is supported)
- Go to http://<IP address>:9090 if your board is connected to a computer via static IP address or to http://pynq:9090 if your host can resolve the target's hostname
- Log in with username
- To move files to/from Jupyter Notebook it is convenient to share the home directory of the target's
xilinxuser. For instance, to access the Pynq home area as a network drive via Samba protocol:
- Open a file browser and click "Go" > "Enter Location"
- Insert location
- Log as
Editing and executing Python functions
Before implementing the FIR filter in PL, we created a software implementation with the SciPy library. To verify it, we applied it to a noisy signal.
In essence we
- created a new notebook by clicking on the New button at the top and select Python 3
- selected Code on the top bar and write some Python code
- clicked Run on the top bar to run code on a kernel.
The following image shows the noisy and the filtered signals.
For more details, please refer to the section Software FIR filter using SciPy.
Implementing a Hardware-Accelerated Version of the FIR Filter in PL
To access an hardware-accelerated function from Python, PYNQ requires to load a custom overlay. Overlays are built with Vivado and are composed by:
- an FPGA bitstream (.bit file)
- a block design (.tcl file)
Creating and Running a New Custom Overlay: Approach #1
We created a custom overlay associated with the hardware implementation of the FIR filter. This first approach made use of the FIR Compiler tool provided by Vivado.
The fundamental steps required to do this are:
- Opening a new Vivado project, selecting RTL project and Bora SOM as the target board
- Creating your block design
- Adding FIR compiler block (included in Vivado default IP) and setting it up
- Adding AXI direct memory access block and setting it up
- On ZYNQ7 Processing System block, enabling a High-Performance AXI 32b/64b Slave Ports on interface HP0
- Connecting AXIS_DATA bus of AXI and FIR block
- Runnin Connection Automation to complete wiring
- Creating Hierarchy of AXI and FIR block named
- Exporting bitstream file running Generate Bitstream
- Exporting block design using Tcl console command
- Renaming generated files as
- Creating a folder named
<overlay_name>and inserting generated files
- Copying the folder to the target's filesystem in
The overlay is ready to be used in the PYNQ Python console.
Running Custom Overlays with Generic Driver
To access the overlay with the generic driver:
These steps allows you to communicate directly through a DMA buffer.
For more details, please refer to the section Hardware FIR Implementation.
Running Custom Overlays with IP-Specific Driver
To access the overlay with a specific driver:
- create a new class for FIR filter with a method to communicate directly thorough a DMA buffer
- create a
checkhierarchymethod to check the IP contained under filter hierarchy
For more details, please refer to the section Driver for FIR accelerator.
Creating and Running a New Custom Overlay: Approach #2
This approach makes use of a different method to implement the filter. In this case, the filter was written in C++ and implemented by using Vivado High-Level Synthesis (HLS).
The fundamental steps required to do this are:
- Opening a new Vivado HLS project, selecting Bora SOM as the target board
- Creating a new C++ source file
- Writing C++ code of FIR custom IP
- Creating AXI Stream interfaces for input and output
- Defining FIR coefficients and normalizing their values
- Using some #pragmas to optimize the execution of the algorithm
- Synthesizing new IP running Run C synthesis
- Exporting new IP running Export RTL
- Opening a new Vivado project, selecting RTL project and Bora SOM as the target board
- Adding the new IP in IP list
- Opening IP Catalog
- Adding repository of the custom IP
To complete the procedure and export the Vivado project, the same steps described previously have to be done.
The data flows are implemented as AXI streams. The following images show the input and the output to/from the filter respectively.