以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
设计图表如下。
图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配置。
-
- 使用源文件(在这里是fpga-load.dts)通过Device Tree Compiler(dtc)将其转换为dtb(在这里是fpga-load.dtb)。
-
- 在/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,在以下步骤中进行时钟设置。
-
- 使用设备树叠加(Device Tree Overlay)的源文件(此处为fclk0-zynqmp.dts),通过设备树编译器(Device Tree Compiler,简称dtc),转换为设备树二进制文件(Device Tree Blob,简称dtb)。
-
- 在/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不同,有一些注意事项。
-
- 将目标路径设置为”/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