As mentioned in the First Blog, this blog will be focussed on Vivado based HW design. I will be writing about my experience in creating a simplest/minimalistic hardware design with the least amount of peripherals that is sufficient to do a SD card boot. I will be comparing this design against the reference u96v2_sbc_base design by exploring the design and building the design from the Avnet repository, Let's get started.
Objective:
The Ultra96V2 board comes with a lot of peripherals (as shown below) that are already configured.
I started with the aim of creating a simple SD card boot image with just the SD, DDR and UART peripherals (highlighted in red) on Zynq Ultrascale+ MPSoC. I didn't want to add any more peripherals as I wanted to test my understanding of how to configure a SoC with just the bare minimum information (Device/Chip name, SD, DDR and UART pin configuration). I intentionally avoided using the board specification file during project creation as I wanted to understand what it was doing and how different the manual configuration was different to using board definition file.
Disassembling the existing file:
The first step for me was to understand what I wanted to do a SD boot. The out of box flash image that was provided by Avnet was a good pointer. When I was flashing the ultra96v2 out of box image, it resulted in 3 files as shown below:
- BOOT.BIN - Boot.bin is a crucial binary file commonly used in booting embedded systems based on Zynq UltraScale+ MPSoC architectures. The boot.bin file is typically generated during the development process and contains several components (First Stage bootloader, Second Stage bootloader, Platform Management Unit, Device tree blob, Trust zone binary etc) essential for the system's boot process. More about this in the next blog.
- boot.scr - boot.scr, short for "boot script," is a human-readable script file used in the boot process of embedded systems, particularly those running on U-Boot, a popular open-source bootloader commonly used with various hardware platforms. U-Boot provides the flexibility to customize the boot process through boot.scr, allowing developers to define specific boot configurations and actions. The boot.scr file contains a sequence of U-Boot commands, written in a simple text format, which instruct the bootloader on how to initialize the system and load the necessary components during the boot process. These commands may include setting environment variables, loading kernel images, device tree blobs, RAM disks, or even additional U-Boot scripts.
- image.ub - image.ub is a binary file commonly used as the main bootable image in embedded systems, particularly those running on U-Boot as the bootloader. The image.ub file contains u-boot bootloader, linux kernel, device tree blob and other components like file system.Based on the training provided, we all know that the above files are generated by the software (Vits/Petalinux) based on the underlying hardware (.xsa file). So the first step is to build the .xsa file for the minimal hardware design
First approach:
As discussed previously, I needed the bare minimum information (Device/Chip name, SD and UART pin configuration) to generate the hardware output .xsa that can be used further to generate the SD card boot image. Looking at the following documents
Ultra96-V2 Getting Started Guide v2.0 (avnet.com) - The device name ZU3EG-SBVA484-1-I could be extracted from the document.
Ultra96-V2 Rev1 Schematic - The MIO pins connected to SD0 and UART 1 can be easily taken from the connector image shown below.
Based on the above information, we can create a project based on the above device and the MIO information for SD card and UART pins was translated to the PS configuration block as shown below.
I left the remaining configuration of DDR, clocks in the default setting(would latter come to haunt me), validated the block design and generated the bitfile and exported the .xsa file and generated the petalinux image based on the above hardware.
When I tested the image on the board, the INIT led was always red and DONE led never lit up. That indicated that there was some issue with the initialization code and the FPGA programming. Moreover, I was not able to see any output from the com port. So I was not sure if I was configuring the UART port in the petalinux properly.
Second approach
To identify if the issue was in my hardware design or petalinux configuration, I wanted a reference hardware design against which I could run my petalinux configuration against. After doing some searching online, I came across the following article, which showed how to build a base design for Ultra96v2 board from avnet repositories.
Ultra96-V2 - Building the foundational designs - Hackster.io
So I created a place holder and cloned the repositories of interest as discussed. Since I was using Vivado, petalinux and Vitis versions 2021.2, I checked out the branches to that specific versions.
$ cd ~
$ mkdir ultra96v2_2021_2
$ cd ~/ultra96v2_2021_2
$ git clone https://github.com/Avnet/bdf
$ git clone -b 2021.2 https://github.com/Avnet/hdl
$ git clone -b 2021.2 https://github.com/Avnet/petalinux
The author in the article, tries to run the top level petalinux script, that will call the specific project of interest, create the block design, generate the bit files, export .xsa file, use petalinux to generate the bootable image. As you can realize, it is a heavily scripted environment. Though I was interested to explore how it was done, in the interest of time I just focused on finding the specific script that was calling the block design and generating the .xsa. So that I can build the reference design for my purpose.
After doing some exploration, I found that petalinux script was calling the make_u96v2_sbc_base.tcl script inside hdl/scripts. Hence I followed up with running the vivado tool in batch mode to generate the image and get the .xsa file.
manihatn@test:/ultra96v2_2021_2/hdl/scripts$ vivado -mode batch -source make_u96v2_sbc_base.tcl -notrace -tclargs u96v2_sbc base
****** Vivado v2021.2 (64-bit)
**** SW Build 3367213 on Tue Oct 19 02:47:39 MDT 2021
**** IP Build 3369179 on Thu Oct 21 08:25:16 MDT 2021
** Copyright 1986-2021 Xilinx, Inc. All Rights Reserved.
source make_u96v2_sbc_base.tcl -notrace
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
*- -*
*- Welcome to the Avnet Project Builder -*
*- -*
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Selected
BDF path /tmp/repos/bdf
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Creating projects Folder
+------------------+------------------------------------+
| Setting | Configuration |
+------------------+------------------------------------+
| Board | u96v2_sbc |
+------------------+------------------------------------+
| Project | base |
+------------------+------------------------------------+
| SDK | no |
+------------------+------------------------------------+
| No Close Project | yes |
+------------------+------------------------------------+
| Device | zynqmp |
+------------------+------------------------------------+
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Vivado version 2021.2 acceptable,
continuing...
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Selected Board and Project as:
u96v2_sbc and base
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Not Requesting Tag
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Setting Up Project u96v2_sbc_base...
***** Creating Vivado project...
The reference design was a bit more complex (as can be seen from the block design below) as it was aiming to exercise all the peripherals. As I am aiming to only test my petalinux config against the above, I didn't mind its design.
I exported the .xsa and generated a petalinux image against my petalinux config. I ran the design in the board. The board sprang into life and I was able to see the kernel booting through the UART console and arrived at the login prompt. This test suggested that my petalinux config was correct and the issue lies with my hardware design and I was missing some configuration in the PS configuration block.
Going back to my first approach:
After revisiting the design and looking into the PS configuration details, I noticed that the clocks and DDR configuration was different between my design and the reference design. I remember doing some of the DDR and clock related configuration in the Vivado HW training Labs 2 and 3.
Once I made the above changes, I saved the block design and validated the design. Even though there was a critical warning about the DDR clock frequency (479 MHz) lower than the expected (500 MHz), the validation was successful. I will need to investigate this at a later point.
I ran a petalinux build against the generated .xsa file and when I switched on the board, I was happy to see the kernel booting in the com port with the minimalistic hardware.
Xilinx Zynq MP First Stage Boot Loader
Release 2021.2 Oct 13 2021 - 07:15:53
NOTICE: BL31: v2.4(release):xlnx_rebase_v2.4_2021.1_update1-23-g9188496b9
NOTICE: BL31: Built : 07:41:24, Oct 13 2021
U-Boot 2021.01 (Oct 12 2021 - 09:28:42 +0000)
CPU: ZynqMP
Silicon: v3
Board: Xilinx ZynqMP
DRAM: 2 GiB
PMUFW: v1.1
EL Level: EL2
Chip ID: zu3eg
NAND: 0 MiB
MMC: mmc@ff160000: 0
Loading Environment from FAT... *** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Bootmode: SD_MODE
Reset reason: EXTERNAL
Net: No ethernet found.
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr
2710 bytes read in 20 ms (131.8 KiB/s)
## Executing script at 20000000
Trying to load boot images from mmc0
19827296 bytes read in 1438 ms (13.1 MiB/s)
## Loading kernel from FIT Image at 10000000 ...
Using 'conf-system-top.dtb' configuration
Trying 'kernel-1' kernel subimage
Description: Linux kernel
Created: 2021-10-12 9:30:57 UTC
Type: Kernel Image
Compression: gzip compressed
Data Start: 0x100000f8
Data Size: 9386420 Bytes = 9 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x00200000
Entry Point: 0x00200000
Hash algo: sha256
Hash value: d70b157b0df9e7c48dee5f6d34548a8d131291eb34d3f6a0d73429fac29c1fdd
Verifying Hash Integrity ... sha256+ OK
## Loading ramdisk from FIT Image at 10000000 ...
Using 'conf-system-top.dtb' configuration
Trying 'ramdisk-1' ramdisk subimage
Description: petalinux-image-minimal
Created: 2021-10-12 9:30:57 UTC
Type: RAMDisk Image
Compression: uncompressed
Data Start: 0x108fca1c
Data Size: 10402508 Bytes = 9.9 MiB
Architecture: AArch64
OS: Linux
Load Address: unavailable
Entry Point: unavailable
Hash algo: sha256
Hash value: 810bb98863420f079ddef4204d40c37b3670ad3b01a164e6896dcc2d5c3467db
Verifying Hash Integrity ... sha256+ OK
## Loading fdt from FIT Image at 10000000 ...
Using 'conf-system-top.dtb' configuration
Trying 'fdt-system-top.dtb' fdt subimage
Description: Flattened Device Tree blob
Created: 2021-10-12 9:30:57 UTC
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x108f3bbc
Data Size: 36238 Bytes = 35.4 KiB
Architecture: AArch64
Hash algo: sha256
Hash value: 76bcbf9c35c0a52e3dd7538e02df2462e7ca197580750f92333d0b8c44458175
Verifying Hash Integrity ... sha256+ OK
Booting using the fdt blob at 0x108f3bbc
Uncompressing Kernel Image
Loading Ramdisk to 7d327000, end 7dd12acc ... OK
Loading Device Tree to 000000007d31b000, end 000000007d326d8d ... OK
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[ 0.000000] Linux version 5.10.0-xilinx-v2021.2 (oe-user@oe-host) (aarch64-xilinx-linux-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.35.1) #1 SMP Tue Oct 12 09:30:57 UTC 2021
[ 0.000000] Machine model: xlnx,zynqmp
[ 0.000000] earlycon: cdns0 at MMIO 0x00000000ff010000 (options '115200n8')
[ 0.000000] printk: bootconsole [cdns0] enabled
[ 0.000000] efi: UEFI not found.
[ 0.000000] cma: Reserved 256 MiB at 0x000000006d000000
[ 0.000000] Zone ranges:
[ 0.000000] DMA32 [mem 0x0000000000000000-0x000000007fefffff]
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000000000000-0x000000007fefffff]
[ 0.000000] Zeroed struct page in unavailable ranges: 256 pages
[ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x000000007fefffff]
[ 0.000000] psci: probing for conduit method from DT.
[ 0.000000] psci: PSCIv1.1 detected in firmware.
[ 0.000000] psci: Using standard PSCI v0.2 function IDs
[ 0.000000] psci: MIGRATE_INFO_TYPE not supported.
[ 0.000000] psci: SMC Calling Convention v1.2
[ 0.000000] percpu: Embedded 22 pages/cpu s50968 r8192 d30952 u90112
[ 0.000000] Detected VIPT I-cache on CPU0
[ 0.000000] CPU features: detected: ARM erratum 845719
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 515844
[ 0.000000] Kernel command line: earlycon console=ttyPS0,115200 clk_ignore_unused root=/dev/ram0 rw
[ 0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 1761644K/2096128K available (13952K kernel code, 982K rwdata, 3928K rodata, 2112K init, 586K bss, 72340K reserved, 262144K cma-reserved)
[ 0.000000] rcu: Hierarchical RCU implementation.
[ 0.000000] rcu: RCU event tracing is enabled.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[ 0.000000] GIC: Adjusting CPU interface base to 0x00000000f902f000
[ 0.000000] GIC: Using split EOI/Deactivate mode
[ 0.000000] random: get_random_bytes called from start_kernel+0x31c/0x524 with crng_init=0
[ 0.000000] arch_timer: cp15 timer(s) running at 33.33MHz (phys).
[ 0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x7b0074340, max_idle_ns: 440795202884 ns
[ 0.000004] sched_clock: 56 bits at 33MHz, resolution 30ns, wraps every 2199023255543ns
[ 0.008324] Console: colour dummy device 80x25
[ 0.012404] Calibrating delay loop (skipped), value calculated using timer frequency.. 66.66 BogoMIPS (lpj=133332)
[ 0.022667] pid_max: default: 32768 minimum: 301
[ 0.027414] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes, linear)
[ 0.034616] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes, linear)
[ 0.043830] rcu: Hierarchical SRCU implementation.
[ 0.047411] EFI services will not be available.
[ 0.051827] smp: Bringing up secondary CPUs ...
[ 0.056599] Detected VIPT I-cache on CPU1
[ 0.056660] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[ 0.057106] Detected VIPT I-cache on CPU2
[ 0.057131] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
[ 0.057532] Detected VIPT I-cache on CPU3
[ 0.057556] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
[ 0.057605] smp: Brought up 1 node, 4 CPUs
[ 0.091607] SMP: Total of 4 processors activated.
[ 0.096279] CPU features: detected: 32-bit EL0 Support
[ 0.101382] CPU features: detected: CRC32 instructions
[ 0.106526] CPU: All CPU(s) started at EL2
[ 0.110565] alternatives: patching kernel code
[ 0.116443] devtmpfs: initialized
[ 0.122824] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[ 0.127958] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
[ 0.142533] pinctrl core: initialized pinctrl subsystem
[ 0.143326] DMI not present or invalid.
[ 0.146154] NET: Registered protocol family 16
[ 0.152105] DMA: preallocated 256 KiB GFP_KERNEL pool for atomic allocations
[ 0.157468] DMA: preallocated 256 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
[ 0.165281] audit: initializing netlink subsys (disabled)
[ 0.170693] audit: type=2000 audit(0.108:1): state=initialized audit_enabled=0 res=1
[ 0.178313] cpuidle: using governor menu
[ 0.182265] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[ 0.188994] ASID allocator initialised with 65536 entries
[ 0.194412] Serial: AMBA PL011 UART driver
[ 0.216342] HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages
[ 0.217401] HugeTLB registered 32.0 MiB page size, pre-allocated 0 pages
[ 0.224073] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[ 0.230741] HugeTLB registered 64.0 KiB page size, pre-allocated 0 pages
[ 1.282418] cryptd: max_cpu_qlen set to 1000
[ 1.309642] DRBG: Continuing without Jitter RNG
[ 1.390188] raid6: neonx8 gen() 2135 MB/s
[ 1.458246] raid6: neonx8 xor() 1596 MB/s
[ 1.526308] raid6: neonx4 gen() 2188 MB/s
[ 1.594369] raid6: neonx4 xor() 1563 MB/s
[ 1.662443] raid6: neonx2 gen() 2076 MB/s
[ 1.730501] raid6: neonx2 xor() 1431 MB/s
[ 1.798577] raid6: neonx1 gen() 1775 MB/s
[ 1.866624] raid6: neonx1 xor() 1219 MB/s
[ 1.934686] raid6: int64x8 gen() 1437 MB/s
[ 2.002756] raid6: int64x8 xor() 771 MB/s
[ 2.070827] raid6: int64x4 gen() 1601 MB/s
[ 2.138890] raid6: int64x4 xor() 814 MB/s
[ 2.206951] raid6: int64x2 gen() 1398 MB/s
[ 2.275009] raid6: int64x2 xor() 749 MB/s
[ 2.343099] raid6: int64x1 gen() 1032 MB/s
[ 2.411162] raid6: int64x1 xor() 517 MB/s
[ 2.411204] raid6: using algorithm neonx4 gen() 2188 MB/s
[ 2.415158] raid6: .... xor() 1563 MB/s, rmw enabled
[ 2.420089] raid6: using neon recovery algorithm
[ 2.425230] iommu: Default domain type: Translated
[ 2.429814] SCSI subsystem initialized
[ 2.433417] usbcore: registered new interface driver usbfs
[ 2.438723] usbcore: registered new interface driver hub
[ 2.443994] usbcore: registered new device driver usb
[ 2.449045] mc: Linux media interface: v0.10
[ 2.453238] videodev: Linux video capture interface: v2.00
[ 2.458714] EDAC MC: Ver: 3.0.0
[ 2.462273] zynqmp-ipi-mbox mailbox@ff990400: Registered ZynqMP IPI mbox with TX/RX channels.
[ 2.470491] FPGA manager framework
[ 2.473765] Advanced Linux Sound Architecture Driver Initialized.
[ 2.480075] Bluetooth: Core ver 2.22
[ 2.483250] NET: Registered protocol family 31
[ 2.487647] Bluetooth: HCI device and connection manager initialized
[ 2.493966] Bluetooth: HCI socket layer initialized
[ 2.498807] Bluetooth: L2CAP socket layer initialized
[ 2.503832] Bluetooth: SCO socket layer initialized
[ 2.508983] clocksource: Switched to clocksource arch_sys_counter
[ 2.514892] VFS: Disk quotas dquot_6.6.0
[ 2.518669] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[ 2.530207] NET: Registered protocol family 2
[ 2.530691] tcp_listen_portaddr_hash hash table entries: 1024 (order: 2, 16384 bytes, linear)
[ 2.538279] TCP established hash table entries: 16384 (order: 5, 131072 bytes, linear)
[ 2.546226] TCP bind hash table entries: 16384 (order: 6, 262144 bytes, linear)
[ 2.553730] TCP: Hash tables configured (established 16384 bind 16384)
[ 2.559992] UDP hash table entries: 1024 (order: 3, 32768 bytes, linear)
[ 2.566576] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes, linear)
[ 2.573775] NET: Registered protocol family 1
[ 2.578326] RPC: Registered named UNIX socket transport module.
[ 2.583843] RPC: Registered udp transport module.
[ 2.588509] RPC: Registered tcp transport module.
[ 2.593184] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 2.600215] PCI: CLS 0 bytes, default 64
[ 2.603608] Trying to unpack rootfs image as initramfs...
[ 3.076394] Freeing initrd memory: 10156K
[ 3.155850] Initialise system trusted keyrings
[ 3.156019] workingset: timestamp_bits=46 max_order=19 bucket_order=0
[ 3.161934] NFS: Registering the id_resolver key type
[ 3.166112] Key type id_resolver registered
[ 3.170241] Key type id_legacy registered
[ 3.174245] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[ 3.180900] jffs2: version 2.2. (NAND) (SUMMARY) © 2001-2006 Red Hat, Inc.
[ 3.224294] NET: Registered protocol family 38
[ 3.224360] xor: measuring software checksum speed
[ 3.232037] 8regs : 2363 MB/sec
[ 3.235697] 32regs : 2799 MB/sec
[ 3.240643] arm64_neon : 2379 MB/sec
[ 3.240829] xor: using function: 32regs (2799 MB/sec)
[ 3.245854] Key type asymmetric registered
[ 3.249918] Asymmetric key parser 'x509' registered
[ 3.254790] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 247)
[ 3.262117] io scheduler mq-deadline registered
[ 3.266612] io scheduler kyber registered
[ 3.272533] ps_pcie_dma init()
[ 3.301702] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[ 3.303659] Serial: AMBA driver
[ 3.307311] cacheinfo: Unable to detect cache hierarchy for CPU 0
[ 3.317015] brd: module loaded
[ 3.322733] loop: module loaded
[ 3.323530] mtdoops: mtd device (mtddev=name/number) must be supplied
[ 3.328193] libphy: Fixed MDIO Bus: probed
[ 3.332137] tun: Universal TUN/TAP device driver, 1.6
[ 3.335834] CAN device driver interface
[ 3.340075] usbcore: registered new interface driver asix
[ 3.344954] usbcore: registered new interface driver ax88179_178a
[ 3.350973] usbcore: registered new interface driver cdc_ether
[ 3.356767] usbcore: registered new interface driver net1080
[ 3.362398] usbcore: registered new interface driver cdc_subset
[ 3.368272] usbcore: registered new interface driver zaurus
[ 3.373823] usbcore: registered new interface driver cdc_ncm
[ 3.380327] usbcore: registered new interface driver uas
[ 3.384730] usbcore: registered new interface driver usb-storage
[ 3.391398] rtc_zynqmp ffa60000.rtc: registered as rtc0
[ 3.395871] rtc_zynqmp ffa60000.rtc: setting system clock to 1970-01-01T00:00:05 UTC (5)
[ 3.403931] i2c /dev entries driver
[ 3.408681] usbcore: registered new interface driver uvcvideo
[ 3.413060] USB Video Class driver (1.1.1)
[ 3.417465] Bluetooth: HCI UART driver ver 2.3
[ 3.421540] Bluetooth: HCI UART protocol H4 registered
[ 3.426642] Bluetooth: HCI UART protocol BCSP registered
[ 3.431935] Bluetooth: HCI UART protocol LL registered
[ 3.437020] Bluetooth: HCI UART protocol ATH3K registered
[ 3.442396] Bluetooth: HCI UART protocol Three-wire (H5) registered
[ 3.448641] Bluetooth: HCI UART protocol Intel registered
[ 3.453987] Bluetooth: HCI UART protocol QCA registered
[ 3.459195] usbcore: registered new interface driver bcm203x
[ 3.464818] usbcore: registered new interface driver bpa10x
[ 3.470349] usbcore: registered new interface driver bfusb
[ 3.475799] usbcore: registered new interface driver btusb
[ 3.481265] usbcore: registered new interface driver ath3k
[ 3.486759] EDAC MC: ECC not enabled
[ 3.490359] EDAC DEVICE0: Giving out device to module zynqmp-ocm-edac controller zynqmp_ocm: DEV ff960000.memory-controller (INTERRUPT)
[ 3.502714] sdhci: Secure Digital Host Controller Interface driver
[ 3.508475] sdhci: Copyright(c) Pierre Ossman
[ 3.512795] sdhci-pltfm: SDHCI platform and OF driver helper
[ 3.518703] ledtrig-cpu: registered to indicate activity on CPUs
[ 3.524403] SMCCC: SOC_ID: ARCH_SOC_ID not implemented, skipping ....
[ 3.530841] zynqmp_firmware_probe Platform Management API v1.1
[ 3.536585] zynqmp_firmware_probe Trustzone version v1.0
[ 3.585349] securefw securefw: securefw probed
[ 3.585732] alg: No test for xilinx-zynqmp-aes (zynqmp-aes)
[ 3.589808] zynqmp_aes firmware:zynqmp-firmware:zynqmp-aes: AES Successfully Registered
[ 3.597925] alg: No test for xilinx-keccak-384 (zynqmp-keccak-384)
[ 3.604056] alg: No test for xilinx-zynqmp-rsa (zynqmp-rsa)
[ 3.609624] usbcore: registered new interface driver usbhid
[ 3.614957] usbhid: USB HID core driver
[ 3.621659] ARM CCI_400_r1 PMU driver probed
[ 3.622142] fpga_manager fpga0: Xilinx ZynqMP FPGA Manager registered
[ 3.629837] usbcore: registered new interface driver snd-usb-audio
[ 3.636336] pktgen: Packet Generator for packet performance testing. Version: 2.75
[ 3.643859] Initializing XFRM netlink socket
[ 3.647414] NET: Registered protocol family 10
[ 3.652266] Segment Routing with IPv6
[ 3.655552] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[ 3.661664] NET: Registered protocol family 17
[ 3.665659] NET: Registered protocol family 15
[ 3.670068] can: controller area network core
[ 3.674413] NET: Registered protocol family 29
[ 3.678792] can: raw protocol
[ 3.681733] can: broadcast manager protocol
[ 3.685886] can: netlink gateway - max_hops=1
[ 3.690306] Bluetooth: RFCOMM TTY layer initialized
[ 3.695062] Bluetooth: RFCOMM socket layer initialized
[ 3.700182] Bluetooth: RFCOMM ver 1.11
[ 3.703879] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 3.709150] Bluetooth: BNEP filters: protocol multicast
[ 3.714344] Bluetooth: BNEP socket layer initialized
[ 3.719271] Bluetooth: HIDP (Human Interface Emulation) ver 1.2
[ 3.725159] Bluetooth: HIDP socket layer initialized
[ 3.730236] 9pnet: Installing 9P2000 support
[ 3.734350] Key type dns_resolver registered
[ 3.738816] registered taskstats version 1
[ 3.742633] Loading compiled-in X.509 certificates
[ 3.748740] Btrfs loaded, crc32c=crc32c-generic
[ 3.763010] ff010000.serial: ttyPS0 at MMIO 0xff010000 (irq = 45, base_baud = 6249999) is a xuartps
[ 3.772048] printk: console [ttyPS0] enabled
[ 3.772048] printk: console [ttyPS0] enabled
[ 3.776353] printk: bootconsole [cdns0] disabled
[ 3.776353] printk: bootconsole [cdns0] disabled
[ 3.785805] of-fpga-region fpga-full: FPGA Region probed
[ 3.796029] xilinx-zynqmp-dma fd500000.dma: ZynqMP DMA driver Probe success
[ 3.803234] xilinx-zynqmp-dma fd510000.dma: ZynqMP DMA driver Probe success
[ 3.810427] xilinx-zynqmp-dma fd520000.dma: ZynqMP DMA driver Probe success
[ 3.817623] xilinx-zynqmp-dma fd530000.dma: ZynqMP DMA driver Probe success
[ 3.824820] xilinx-zynqmp-dma fd540000.dma: ZynqMP DMA driver Probe success
[ 3.832012] xilinx-zynqmp-dma fd550000.dma: ZynqMP DMA driver Probe success
[ 3.839211] xilinx-zynqmp-dma fd560000.dma: ZynqMP DMA driver Probe success
[ 3.846410] xilinx-zynqmp-dma fd570000.dma: ZynqMP DMA driver Probe success
[ 3.853690] xilinx-zynqmp-dma ffa80000.dma: ZynqMP DMA driver Probe success
[ 3.860889] xilinx-zynqmp-dma ffa90000.dma: ZynqMP DMA driver Probe success
[ 3.868084] xilinx-zynqmp-dma ffaa0000.dma: ZynqMP DMA driver Probe success
[ 3.875281] xilinx-zynqmp-dma ffab0000.dma: ZynqMP DMA driver Probe success
[ 3.882472] xilinx-zynqmp-dma ffac0000.dma: ZynqMP DMA driver Probe success
[ 3.889668] xilinx-zynqmp-dma ffad0000.dma: ZynqMP DMA driver Probe success
[ 3.896861] xilinx-zynqmp-dma ffae0000.dma: ZynqMP DMA driver Probe success
[ 3.904056] xilinx-zynqmp-dma ffaf0000.dma: ZynqMP DMA driver Probe success
[ 3.911579] xilinx-axipmon ffa00000.perf-monitor: Probed Xilinx APM
[ 3.918173] xilinx-axipmon fd0b0000.perf-monitor: Probed Xilinx APM
[ 3.924713] xilinx-axipmon fd490000.perf-monitor: Probed Xilinx APM
[ 3.931250] xilinx-axipmon ffa10000.perf-monitor: Probed Xilinx APM
[ 3.938027] cdns-i2c ff030000.i2c: 400 kHz mmio ff030000 irq 38
[ 3.948232] of_cfs_init
[ 3.950720] of_cfs_init: OK
[ 3.953664] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[ 3.969972] zynqmp_pll_disable() clock disable failed for dpll_int, ret = -13
[ 3.982428] mmc0: SDHCI controller on ff160000.mmc [ff160000.mmc] using ADMA 64-bit
[ 4.067007] mmc0: error -110 whilst initialising SD card
[ 4.093421] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[ 4.099957] clk: Not disabling unused clocks
[ 4.104408] ALSA device list:
[ 4.107365] No soundcards found.
[ 4.111253] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
[ 4.119866] cfg80211: failed to load regulatory.db
[ 4.125941] Freeing unused kernel memory: 2112K
[ 4.153039] Run /init as init process
INIT: version 2.97 booting
Starting udev
[ 4.272204] udevd[247]: starting version 3.2.9
[ 4.277149] random: udevd: uninitialized urandom read (16 bytes read)
[ 4.283673] random: udevd: uninitialized urandom read (16 bytes read)
[ 4.290229] random: udevd: uninitialized urandom read (16 bytes read)
[ 4.301693] udevd[248]: starting eudev-3.2.9
bootlogd: /dev/ttyPS0Fri Mar 9 12:34:56 UTC 2018
chmod: /var/log/wtmp: No such file or directory
Failed to set mode -0664- for -/var/log/wtmp-.
Configuring packages on first boot....
(This may take several minutes. Please do not power off the machine.)
Running postinst /etc/rpm-postinsts/100-sysvinit-inittab...
update-rc.d: /etc/init.d/run-postinsts exists during rc.d purge (continuing)
Removing any system startup links for run-postinsts ...
INIT: Entering runlevel: 5
Configuring network interfaces... ip: SIOCGIFFLAGS: No such device
Starting haveged: haveged: command socket is listening at fd 3
haveged: haveged starting up
Starting Dropbear SSH server: Waiting for kernel randomness to be initialised...
haveged: haveged: ver: 1.9.13; arch: generic; vend: ; build: (gcc 10.2.0 CTV); collect: 128K
haveged: haveged: cpu: (VC); data: 16K (D); inst: 16K (D); idx: 11/40; sz: 15456/64452
haveged: haveged: tot tests(BA8): A:1/1 B:1/1 continuous tests(B): last entropy estimate 8.00055
haveged: haveged: fills: 0, generated: 0
[ 5.858380] random: crng init done
[ 5.861822] random: 5 urandom warning(s) missed due to ratelimiting
Generating 2048 bit rsa key, this may take a while...
Public key portion is:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCPTQMJLWYryu7leVSU3jAj4UfusmI76pWEJn9zmlA2sVq9S3C+iJpEoNU/HJ7SYWluVEm4XwYkRLdwdfs7DcHcB4GtnEBAFz8l9bnDI+sEyhJGfgAvnXb/KoQorFwKVjY+eytATV+EPNUHLhEq1rIjVG5Nh9J4dd5mR58nYkNszn6dGftGSo/qPk37dKBScZr/fDaCRH6lywr6qXpuaFG4Pno9bXUNUSAoOJKKu9aRp4M0TI7PfvoXtMvQTWWABifK5TZIFahTGJzNgAYOFVBUKGn7r6lb71RSfM2JV+IbxneGjX1jHxHaYzkc6UtNxbFb8GWVf9bl2DFw0fszEI8v root@petalinux_img
Fingerprint: sha1!! e0:a2:b8:39:66:f5:22:69:c9:fd:a0:52:99:2f:b8:70:eb:44:c2:5e
dropbear.
Starting internet superserver: inetd.
Starting syslogd/klogd: done
Starting tcf-agent: OK
root@petalinux_img:~#
Automating the tool flow:
I very strongly believe in automating the tool flow as it is more efficient and good for version control. I use the GUI flow only to do only analysis of the design. Below I provide some details on how I automate my hardware build process using Makefile and tcl scripts.
I have the top level Makefile that will call the build_hw target that can create the block design and run the synthesis, implementation, generate bitstream and export xsa file.
all: clean build_hw
build_hw:
vivado -mode batch -source create_bd.tcl
vivado -mode batch -nolog -nojournal -source build_hw.tcl
An example create_bd.tcl can be found below. Take particular note about how the wrapper file is generated and added to the top of the deisgn.
################################################################
# This is a generated script based on design: system
#
# Though there are limitations about the generated script,
# the main purpose of this utility is to make learning
# IP Integrator Tcl commands easier.
################################################################
namespace eval _tcl {
proc get_script_folder {} {
set script_path [file normalize [info script]]
set script_folder [file dirname $script_path]
return $script_folder
}
}
variable script_folder
set script_folder [_tcl::get_script_folder]
################################################################
# Check if script is running in correct Vivado version.
################################################################
set scripts_vivado_version 2021.2
set current_vivado_version [version -short]
if { [string first $scripts_vivado_version $current_vivado_version] == -1 } {
puts ""
catch {common::send_gid_msg -ssname BD::TCL -id 2041 -severity "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."}
return 1
}
################################################################
# START
################################################################
# To test this script, run the following commands from Vivado Tcl console:
# source system_script.tcl
# If there is no project opened, this script will create a
# project, but make sure you do not have an existing project
# <./system/system.xpr> in the current working folder.
set list_projs [get_projects -quiet]
if { $list_projs eq "" } {
create_project system system -part xczu3eg-sbva484-2-i
}
# CHANGE DESIGN NAME HERE
variable design_name
set design_name system
# If you do not already have an existing IP Integrator design open,
# you can create a design using the following command:
# create_bd_design $design_name
# Creating design if needed
set errMsg ""
set nRet 0
set cur_design [current_bd_design -quiet]
set list_cells [get_bd_cells -quiet]
if { ${design_name} eq "" } {
# USE CASES:
# 1) Design_name not set
set errMsg "Please set the variable <design_name> to a non-empty value."
set nRet 1
} elseif { ${cur_design} ne "" && ${list_cells} eq "" } {
# USE CASES:
# 2): Current design opened AND is empty AND names same.
# 3): Current design opened AND is empty AND names diff; design_name NOT in project.
# 4): Current design opened AND is empty AND names diff; design_name exists in project.
if { $cur_design ne $design_name } {
common::send_gid_msg -ssname BD::TCL -id 2001 -severity "INFO" "Changing value of <design_name> from <$design_name> to <$cur_design> since current design is empty."
set design_name [get_property NAME $cur_design]
}
common::send_gid_msg -ssname BD::TCL -id 2002 -severity "INFO" "Constructing design in IPI design <$cur_design>..."
} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } {
# USE CASES:
# 5) Current design opened AND has components AND same names.
set errMsg "Design <$design_name> already exists in your project, please set the variable <design_name> to another value."
set nRet 1
} elseif { [get_files -quiet ${design_name}.bd] ne "" } {
# USE CASES:
# 6) Current opened design, has components, but diff names, design_name exists in project.
# 7) No opened design, design_name exists in project.
set errMsg "Design <$design_name> already exists in your project, please set the variable <design_name> to another value."
set nRet 2
} else {
# USE CASES:
# 8) No opened design, design_name not in project.
# 9) Current opened design, has components, but diff names, design_name not in project.
common::send_gid_msg -ssname BD::TCL -id 2003 -severity "INFO" "Currently there is no design <$design_name> in project, so creating one..."
create_bd_design $design_name
common::send_gid_msg -ssname BD::TCL -id 2004 -severity "INFO" "Making design <$design_name> as current_bd_design."
current_bd_design $design_name
}
common::send_gid_msg -ssname BD::TCL -id 2005 -severity "INFO" "Currently the variable <design_name> is equal to \"$design_name\"."
if { $nRet != 0 } {
catch {common::send_gid_msg -ssname BD::TCL -id 2006 -severity "ERROR" $errMsg}
return $nRet
}
set bCheckIPsPassed 1
##################################################################
# CHECK IPs
##################################################################
set bCheckIPs 1
if { $bCheckIPs == 1 } {
set list_check_ips "\
xilinx.com:ip:zynq_ultra_ps_e:3.3\
"
set list_ips_missing ""
common::send_gid_msg -ssname BD::TCL -id 2011 -severity "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ."
foreach ip_vlnv $list_check_ips {
set ip_obj [get_ipdefs -all $ip_vlnv]
if { $ip_obj eq "" } {
lappend list_ips_missing $ip_vlnv
}
}
if { $list_ips_missing ne "" } {
catch {common::send_gid_msg -ssname BD::TCL -id 2012 -severity "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." }
set bCheckIPsPassed 0
}
}
if { $bCheckIPsPassed != 1 } {
common::send_gid_msg -ssname BD::TCL -id 2023 -severity "WARNING" "Will not continue with creation of design due to the error(s) above."
return 3
}
##################################################################
# DESIGN PROCs
##################################################################
# Procedure to create entire design; Provide argument to make
# procedure reusable. If parentCell is "", will use root.
proc create_root_design { parentCell } {
variable script_folder
variable design_name
if { $parentCell eq "" } {
set parentCell [get_bd_cells /]
}
# Get object for parentCell
set parentObj [get_bd_cells $parentCell]
if { $parentObj == "" } {
catch {common::send_gid_msg -ssname BD::TCL -id 2090 -severity "ERROR" "Unable to find parent cell <$parentCell>!"}
return
}
# Make sure parentObj is hier blk
set parentType [get_property TYPE $parentObj]
if { $parentType ne "hier" } {
catch {common::send_gid_msg -ssname BD::TCL -id 2091 -severity "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be <hier>."}
return
}
# Save current instance; Restore later
set oldCurInst [current_bd_instance .]
# Set parent object as current
current_bd_instance $parentObj
# Create interface ports
# Create ports
# Create instance: zynq_ultra_ps_e_0, and set properties
set zynq_ultra_ps_e_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.3 zynq_ultra_ps_e_0 ]
# Create port connections
connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins zynq_ultra_ps_e_0/maxihpm0_lpd_aclk] [get_bd_pins zynq_ultra_ps_e_0/pl_clk0]
# Create address segments
# Restore current instance
current_bd_instance $oldCurInst
save_bd_design
validate_bd_design
make_wrapper -files [get_files /{my_path_location}/system/system.srcs/sources_1/bd/system/system.bd] -top
exec cat {my_path_location}/system/system.gen/sources_1/bd/system/hdl/system_wrapper.v > system_wrapper.v
import_files -force -norecurse system_wrapper.v
}
# End of create_root_design()
##################################################################
# MAIN FLOW
##################################################################
create_root_design ""
common::send_gid_msg -ssname BD::TCL -id 2053 -severity "WARNING" "This Tcl script was generated from a block design that has not been validated. It is possible that design <$design_name> may result in errors during validation."
My build_hw.tcl is as follows
open_project system/system.xpr
launch_runs synth_1 -jobs 4
wait_on_run synth_1
launch_runs impl_1 -to_step write_bitstream -jobs 4
wait_on_run impl_1
write_hw_platform -fixed -include_bit -force -file system.xsa
Thanks for reading.