以2018.2版Debian GNU/Linux为例对UltraZed进行FPGA配置

首先

我们在下面的文章中构建了适用于UltraZed的Debian GNU / Linux(v2018.2版)。

    • 「UltraZed 向け Debian GNU/Linux (v2018.2版) の構築(イントロ編)」@Qiita

 

    • 「UltraZed 向け Debian GNU/Linux (v2018.2版) の構築(Boot Loader編)」@Qiita

 

    • 「UltraZed 向け Debian GNU/Linux (v2018.2版) の構築(Linux Kernel編)」@Qiita

 

    「UltraZed 向け Debian GNU/Linux (v2018.2版) の構築(Debian9 Root File System編)」@Qiita

另外,在下一篇文章中,我们介绍了在上一篇文章中搭建的系统的形象。

    「UltraZed 向け Debian GNU/Linux (v2018.2版) ブートイメージの提供」@Qiita

本文将使用上一篇文章中构建的系统,展示了如何使用Linux配置FPGA的例子。本文介绍的FPGA设计和程序已在以下URL公开发布。

    https://github.com/ikwzm/ZynqMP-FPGA-Linux-Example-0-UltraZed

样例FPGA设计

这次将使用在下一篇文章中所介绍的电路来对FPGA进行配置。

    「UltraZed 向け Debian GNU/Linux (v2017.3版) の構築(Sample FPGA Design編)」@Qiita

设计图表如下。

Fig.1 ZynqMP Sample Design

图1:ZynqMP样例设计

为了在UltraZed上加载FPGA,需要将Bitstream文件转换为二进制文件。转换为二进制文件需要准备一个类似下面的bif文件,并使用Vivado-SDK v2018.2的bootgen命令。

all:
{
    [destination_device = pl] design_1_wrapper.bit
}
vivado% bootgen -image design_1_wrapper.bif -arch zynqmp -w -o design_1_wrapper.bin

请参考以下网址以获取有关二进制文件创建方法的详细信息。

    http://www.wiki.xilinx.com/Solution+ZynqMP+PL+Programming

做好准备

UltraZed 的准备

请根据以下文章的指导,在UltraZed上安装Debian GNU/Linux(v2018.2版)。

    「UltraZed 向け Debian GNU/Linux (v2018.2版) ブートイメージの提供」@Qiita

使用FPGA进行登录。

一旦Linux启动后,使用用户名fpga登录。密码设置为fpga。

debian-fpga login: fpga
Password:
fpga@debian-fpga:~$

下载存储库

可以从以下的网址下载作为样本的FPGA设计和程序。

    https://github.com/ikwzm/ZynqMP-FPGA-Linux-Example-0-UltraZed

在这里,我们将将 v2018.2 版例程下载为 examples/gpio。

fpga@debian-fpga:~$ mkdir examples
fpga@debian-fpga:~$ cd examples
fpga@debian-fpga:~/examples$ git clone https://github.com/ikwzm/ZynqMP-FPGA-Linux-Example-0-UltraZed gpio
fpga@debian-fpga:~/examples$ cd gpio
fpga@debian-fpga:~/examples/gpio$ git checkout v2018.2

FPGA的配置

将二进制文件复制到/lib/firmware目录中

需要将配置文件放置在FPGA Region的/lib/firmware目录中。

fpga@debian-fpga:~/examples/gpio$ sudo cp design_1_wrapper.bin /lib/firmware

通过设备树叠加实现 FPGA 的配置

在 FPGA 区域中,我们使用设备树来配置 FPGA。因此,我们需要准备以下为设备树叠加层准备的源文件。

/dts-v1/;
/ {
    fragment@0 {
        target-path = "/fpga-full";
        __overlay__ {
            firmware-name = "design_1_wrapper.bin";
        };
    };
};

请注意目标路径(target-path)是”/fpga-full”。这是在Linux启动时从Device Tree加载的fpga-region指定的符号名称。

请按以下步骤使用设备树叠加实现FPGA配置。

    1. 使用源文件(在这里是fpga-load.dts)通过Device Tree Compiler(dtc)将其转换为dtb(在这里是fpga-load.dtb)。

 

    1. 在/config/device-tree/overlays下创建一个用于Device Tree Overlay的目录(在这里是fpga)。

 

    将步骤2中创建的dtb写入步骤1中创建的目录下的dtbo。

如果看到如下的内核消息,则表示 FPGA 配置成功。

fpga@debian-fpga:~/examples/gpio$ dtc -I dts -O dtb -o fpga-load.dtb fpga-load.dts
fpga@debian-fpga:~/examples/gpio$ sudo mkdir /config/device-tree/overlays/fpga
fpga@debian-fpga:~/examples/gpio$ sudo cp fpga-load.dtb /config/device-tree/overlays/fpga/dtbo
[ 1462.560122] fpga_manager fpga0: writing design_1_wrapper.bin to Xilinx ZynqMP FPGA Manager

FPGA时钟设置的设定

只有配置FPGA还不足以使FPGA的电路正常运行。因为时钟信号的设置还没有完成。

在这里,我们使用 fclkcfg 来设置时钟。fclkcfg 是我创建的设备驱动程序,并已在以下URL上公开。

    https://github.com/ikwzm/fclkcfg

如果已经安装了针对 UltraZed 的 Debian GNU/Linux 引导映像,那么 fclkcfg 已经被包含在其中了。

要设置时钟,准备以下的用于设备树覆盖的源文件。

/dts-v1/;/plugin/;
/ {
    fragment@0 {
        target-path = "/amba";
        __overlay__ {
            fclk0 {
                compatible    = "ikwzm,fclkcfg-0.10.a";
                clocks        = <&clk 0x47>;
                insert-rate   = "100000000";
                insert-enable = <1>;
                remove-rate   = "1000000";
                remove-enable = <0>;
            };
        };
    };
};

在这里,我们使用 clocks 来指定 ZynqMP 的 PL CLOCK[0]。其中,&clk 是时钟控制驱动程序的符号名称,0x47 是 PL CLOCK[0] 的索引号。此外,在插入该设备树时,PL CLOCK[0] 被配置为输出频率为100MHz的时钟。

另外,请注意在“针对 UltraZed 的 Debian GNU/Linux (v2017.3 版) 上对 FPGA 进行配置”中所述的 fclk0-zynqmp.dts 文件中,时钟描述的不同。在 v2017.3 版中,使用的是 <&clkc 0x47>,而在 v2018.3 版中改为了 <&clk 0x47>。

使用Device Tree Overlay,在以下步骤中进行时钟设置。

    1. 使用设备树叠加(Device Tree Overlay)的源文件(此处为fclk0-zynqmp.dts),通过设备树编译器(Device Tree Compiler,简称dtc),转换为设备树二进制文件(Device Tree Blob,简称dtb)。

 

    1. 在/config/device-tree/overlays目录下创建设备树叠加的目录(此处为fclk0)。

 

    将第1步生成的dtb写入第2步创建的目录下的dtbo中。

如果出现下列核心信息,则表示 FPGA 时钟设置成功。

fpga@debian-fpga:~/examples/gpio$ dtc -I dts -O dtb -o fclk0-zynqmp.dtb fclk0-zynqmp.dts
fpga@debian-fpga:~/examples/gpio$ sudo mkdir /config/device-tree/overlays/fclk0
fpga@debian-fpga:~/examples/gpio$ sudo cp fclk0-zynqmp.dtb /config/device-tree/overlays/fclk0/dtbo
[ 1830.238976] fclkcfg amba:fclk0: driver installed.
[ 1830.243617] fclkcfg amba:fclk0: device name    : fclk0
[ 1830.248737] fclkcfg amba:fclk0: clock  name    : pl0
[ 1830.253678] fclkcfg amba:fclk0: clock  rate    : 99999999
[ 1830.259085] fclkcfg amba:fclk0: clock  enabled : 1
[ 1830.263833] fclkcfg amba:fclk0: remove rate    : 1000000
[ 1830.269125] fclkcfg amba:fclk0: remove enable  : 0

Uio做好准备

要访问通过配置的FPGA电路,请使用UIO。为了使用UIO,需准备以下类型的设备树叠加源文件。

/dts-v1/;
/ {
    fragment@0 {
        target-path = "/amba_pl@0";
        #address-cells = <2>;
        #size-cells = <2>;

        __overlay__ {
            #address-cells = <2>;
            #size-cells = <2>;

            uio1: uio@80000000 {
                compatible = "generic-uio";
                reg = <0x0 0x80000000 0x0 0x10000>;
                    };
            uio2: uio@80010000 {
                compatible = "generic-uio";
                reg = <0x0 0x80010000 0x0 0x10000>;
                    };
            uio3: uio@80020000 {
                compatible = "generic-uio";
                reg = <0x0 0x80020000 0x0 0x10000>;
                    };
                };
    } ;
} ;

和Zynq不同,有一些注意事项。

    1. 将目标路径设置为”/amba_pl@0″。

 

    address-cells和size-cells都为2。这是因为ZynqMp地址位宽为64位。因此,在reg字段中以”<地址的高32位 地址的低32位 大小的高32位 大小的低32位>”的形式指定。

使用设备树叠加(Device Tree Overlay)按以下步骤配置Uio。

    使用设备树叠加层的源文件(在此处为 uio.dts)通过设备树编译器 (dtc) 转换为设备树二进制文件 (dtb)。在 /config/device-tree/overlays 目录下创建设备树叠加层的目录 (在此处为 uio)。将第一步创建的 dtb 文件写入第二步创建的目录的 dtbo 文件中。

如果能够成功创建/dev/uio1、/dev/uio2、/dev/uio3,那么就完成了这个任务。

fpga@debian-fpga:~/examples/gpio$ dtc -I dts -O dtb -o uio.dtb uio.dts
fpga@debian-fpga:~/examples/gpio$ sudo mkdir /config/device-tree/overlays/uio
fpga@debian-fpga:~/examples/gpio$ sudo cp uio.dtb /config/device-tree/overlays/uio/dtbo
fpga@debian-fpga:~/examples/gpio$ ls -la /dev/uio*
crw------- 1 root root 245, 0 Dec 31 10:20 /dev/uio0
crw------- 1 root root 245, 1 Dec 31 10:20 /dev/uio1
crw------- 1 root root 245, 2 Dec 31 10:20 /dev/uio2
crw------- 1 root root 245, 2 Dec 31 10:20 /dev/uio3

尝试让LED闪烁

我准备了如下的Python程序。

from uio     import Uio
import numpy as np
import time
import signal

class  LED:
    def __init__(self):
        self.uio  = Uio('uio2')
        self.regs = self.uio.regs()
        self.regs.write_word(4, 0)
        self.pattern = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02]
        self.index   = 0

    def run(self):
        self.regs.write_word(0, self.pattern[self.index])
        if self.index < len(self.pattern)-1:
            self.index = self.index + 1
        else:
            self.index = 0;

if __name__ == '__main__':
    led  = LED()

    for i in range(100):
        led.run()
        time.sleep(0.1)

在此处 import 的 uio.py 是在下一篇文章中介绍的那个。

    「Python と Numpy で UIO を制御」@Qiita

请注意,在「使用 UltraZed 上的 Debian GNU/Linux (v2017.3 版) 配置 FPGA」一文中提及的 led_on.py 文件中,指定的 uio 设备驱动程序名称有所不同。在 v2017.3 版中,使用的是 Uio(‘uio1’),而在 v2018.3 版中改为了 Uio(‘uio2’)。

如果运行上述程序并在几秒钟内LED左右闪烁,则表示成功。

fpga@debian-fpga:~/examples/gpio$ sudo python3 led_on.py

事情的结果或处理方式

玩耍完后,按照添加的顺序,通过设备树覆盖移除添加的设备树。

fpga@debian-fpga:~/examples/gpio$ sudo rmdir /config/device-tree/overlays/uio
fpga@debian-fpga:~/examples/gpio$ sudo rmdir /config/device-tree/overlays/fclk0
[ 2149.037235] fclkcfg amba:fclk0: change rate    : 992064
[ 2149.042497] fclkcfg amba:fclk0: change enable  : 0
[ 2149.047353] fclkcfg amba:fclk0: driver unloaded
fpga@debian-fpga:~/examples/gpio$ sudo rmdir /config/device-tree/overlays/fpga

请留意

关于二进制文件格式

在下面的文章中展示了 v2017.3版 的方法。

    「UltraZed 向け Debian GNU/Linux (v2017.3版) で Vivado-HLS を使って合成した回路を動かす」 @Qiita

请注意,在v2018.2版本中,二进制文件的格式已经有所不同。在v2017.3中,我们使用了名为fpga-bit-to-bin.py的Python脚本来转换二进制文件,但是从v2018.2开始,我们需要使用Vivado-SDK的bootgen来转换二进制文件。

在v2018.2版本中,要处理使用与2017.3版本相同的fpga-bit-to-bin.py转换的二进制文件,需要将fpga_manager的标记设置为0x20。

fpga@debian-fpga:~/examples/negative$ sudo echo 20 > /sys/class/fpga_manager/fpga0/flags

请参阅

    • 「UltraZed 向け Debian GNU/Linux (v2018.2版) の構築(イントロ編)」@Qiita

 

    • 「UltraZed 向け Debian GNU/Linux (v2018.2版) の構築(Boot Loader編)」@Qiita

 

    • 「UltraZed 向け Debian GNU/Linux (v2017.3版) の構築(Sample FPGA Design編)」@Qiita

 

    • 「UltraZed 向け Debian GNU/Linux (v2018.2版) の構築(Linux Kernel編)」@Qiita

 

    • 「UltraZed 向け Debian GNU/Linux (v2018.2版) の構築(Debian9 Root File System編)」@Qiita

 

    • 「UltraZed 向け Debian GNU/Linux (v2018.2版) ブートイメージの提供」@Qiita

 

    • 「UltraZed 向け Debian GNU/Linux (v2017.3版) で Vivado-HLS を使って合成した回路を動かす」 @Qiita

 

    • 「Python と Numpy で UIO を制御」@Qiita

 

    • http://www.wiki.xilinx.com/Solution+ZynqMP+PL+Programming

 

    • https://github.com/ikwzm/ZynqMP-FPGA-Linux-Example-0-UltraZed

 

    https://github.com/ikwzm/fclkcfg