文章来源: OpenFPGA
在微秒内交换“硬件”:使用 AMD 的 FPGA 即可实现。该技术称为DFX(Dynamic Function Exchange)。
注意和产品设计的DFX区别:
在1982年,NCR公司开始了一个正式的计划,以在其整个业务中实施制造可生产性的设计。到1989年,该计划已被正式命名为“Design for Excellence”(DFX)。该公司将DfX描述为:
“持续改进并发产品和制造过程开发,从一开始就将开发人员的注意力集中在所有关键的产品生命周期考虑因素上,例如客户需求、质量、上市时间、拥有成本和操作复杂性。”
“Continuous improvement in concurrent product and manufacturing process development to focus developers’ attention from the beginning on all key product lifecycle considerations such as customer requirements, quality, time to market, cost of ownership, and operational complexity.’’
介绍
在典型的嵌入式系统中,硬件是固定的,运行时的功能变化由软件实现。这意味着硬件在设计初期就必须支持所有功能。与标准 SoC 不同,FPGA 仅需要实现所需的硬件(逻辑)。
DFX通过硬件时间分片进一步提高了这种灵活性。这意味着 FPGA 逻辑的一部分可以用作以太网控制器,然后在几微秒后切换到 MIPI 接口功能。
该技术具有多项优点:
更小的 FPGA 要求 简化配置管理 降低功耗 更容易进行设计更新,因为只需要更新部分比特流
在以下部分中,我们将进行 DFX 实例演示。本次使用基于ZU系列的开发板:
参考设计说明
本次的实例注重DFX流程,所以逻辑比较简单,这样可以使 DFX 流程更易于理解。在此演示中,软核从 SPI NOR FLASH启动 Linux 系统。之所以选择 Linux,是因为它包含完整的文件系统 (UBI + UBIFS) 和 TCP/IP 网络堆栈。Linux应用程序将四个部分比特流从文件系统加载到内存中(每个 DFX 分区两个)。之后,DFX 控制器每 5s 设置并触发一次。每个部分比特流包含不同的 LED 控制器,从而产生不同的 LED 闪烁。重新配置所需的时间测量后并通过 UART 打印。
Vivado 设计
下图显示了静态部分的BD设计。它包括一个 MicroBlaze 软核处理器,该处理器配置了一个 MMU 和一个缓存控制器,用于运行 Linux 系统。此外,以太网、DDR4 内存控制器和 I2C 等标准外设也是设计的一部分。
在本设计中,我们定义了两个分区:u_count和u_shift。在代码中,这些分区作为标准组件实现。启用 DFX 流程后,将显示一个名为“Partition Definition”的选项卡:
这里,不同的 HDL 模块与分区相关联。在本示例中,每个分区有两个模块,但可以根据需要定义任意数量的模块。
定义 HDL 模块后,需要为分区创建面积约束:
u_count分区内有一个ILA,所以u_count分区比u_shift分区大的原因。
下一步就是implement该设计。
implement后,将生成具有默认分区设置的完整比特流以及四个部分比特流(需要DFX的)。
使用提供的项目源重建 Vivado 设计
使用下列链接下载项目:
https://github.com/suisuisi/FPGAPROJECTS
$TRD_HOME/vivado/build/bitstreams
在此阶段,可以使用 Vivado 硬件管理器测试 DFX 比特流。top.bit、down.bit、up.bit、left.bit 和 right.bit分别对应不同LED的闪烁。
目前还不能进行DFX验证,因为top.bit 比特流不包含 MicroBlaze 的引导加载程序。
使用 Vitis 构建自定义引导加载程序
嵌入式系统的默认引导加载程序 U-Boot 对于 MicroBlaze 的内存(BRAM只有几十K)来说太大了。因此,我们使用自定义的第一阶段引导加载程序。通过使用 xsct 来实现这一点,该工具允许我们从命令行创建 Vitis 工作区并编译 FSBL 源代码。
cd $TRD_HOME/vitis
xsct
在 Xilinx 软件命令工具 shell 中,输入以下命令:
xsct% file mkdir workspace;cd workspace
xsct% source ../tcl/build.tcl
xsct% gen_app release
xsct% exit
新建的 FSBL 位于:
$TRD_HOME/vitis/workspace/bobbyb/Release/bobbyb.elf
使用 PetaLinux 构建 Linux 系统
将 PetaLinux 与定制的 Avnet-Silica Yocto Layer 来构建 Linux 镜像。
首先,我们使用 MicroBlaze 的默认模板创建 PetaLinux 项目:
mkdir -p $TRD_HOME/plnx/work
cd $TRD_HOME/plnx/work
petalinux-create --type project --template microblaze --name aup15
接下来,我们添加自定义 Yocto 层并覆盖默认值:
cd $TRD_HOME/plnx/work/aup15
ln -s $TRD_HOME/plnx/configs/meta-avs project-spec/
ln -sf $TRD_HOME/plnx/configs/config project-spec/configs/config
ln -sf $TRD_HOME/plnx/configs/rootfs_config project-spec/configs/rootfs_config
然后将 Xilinx S upport A rchive 导入到我们的项目中:
petalinux-config --get-hw-description $TRD_HOME/vivado/build/prj/ --silentconfig
接下来,将 Vivado 生成的部分比特流复制到我们的自定义根文件系统配置中。目的是将这些比特文件包含在最终的根文件系统中,以便 Linux 应用程序可以加载它们:
cp $TRD_HOME/vivado/build/bitstreams/*.bin project-spec/meta-avs/recipes-apps/dfx-demo/files/bitstreams/
此配置将.bin 文件放在最终 Linux 根文件系统的/usr/share/avs/bitstreams中。
最后,我们开始构建 PetaLinux :
petalinux-build
PetaLinux 构建完成后,所有镜像都位于此处:
$TRD_HOME/plnx/work/aup15/images/linux
使用 MicroBlaze FSBL 更新比特流并从 PetaLinux 镜像生成 MCS 镜像
cd $TRD_HOME/vivado/build/prj
vivado -mode tcl
Vivado% source ../../tcl/procedures.tcl
Vivado% gen_flash_image_fpga ../../../vitis/workspace/bobbyb/Release/bobbyb.elf
接下来,我们为其他FLASH分区创建所有镜像:
Vivado% source ../../tcl/procedures.tcl
Vivado% gen_flash_image_uboot
Vivado% gen_flash_image_kernel
Vivado% gen_flash_image_ubi
所有镜像均位于此构建文件夹中:
$TRD_HOME/ vivado/build/flash_images
通过 JTAG 下载 Flash 镜像
可以使用GUI进行下载或者使用下面命令。
Vivado% source ../../tcl/procedures.tcl
Vivado% jtag::flash ../flash_images/fpga.mcs
Vivado% jtag::flash ../flash_images/u-boot.bin.mcs
Vivado% jtag::flash ../flash_images/image.ub.mcs
Vivado% jtag::flash ../flash_images/rootfs.ubi.mcs
演示
将镜像刷入 SPI NOR FLASH后,将 UART 连接到PC上:
tio /dev/ttyUSB1 -b 115200
在 UART 终端输出:
root@avs-au15p-trd:~# dfx-demo
演示日志:
copied /usr/share/avs/bitstreams/left.bin to buffer @ 0xa7d00000 (290552 bytes)
copied /usr/share/avs/bitstreams/right.bin to buffer @ 0xa7d46ef8 (290552 bytes)
copied /usr/share/avs/bitstreams/up.bin to buffer @ 0xa7d8ddf0 (386864 bytes)
copied /usr/share/avs/bitstreams/down.bin to buffer @ 0xa7dec520 (386864 bytes)
Baseaddr: 0x48602000
Sending shutdown commands to dfx controller...
writing addresses and sizes of partial bitstreams to dfx controller...
pushing partial bitstream #0: /usr/share/avs/bitstreams/left.bin
Configuration time 600 us
pushing partial bitstream #1: /usr/share/avs/bitstreams/right.bin
Configuration time 606 us
pushing partial bitstream #2: /usr/share/avs/bitstreams/up.bin
Configuration time 719 us
pushing partial bitstream #3: /usr/share/avs/bitstreams/down.bin
Configuration time 727 us
pushing partial bitstream #0: /usr/share/avs/bitstreams/left.bin
Configuration time 606 us
结论
这个功能其实已经推出来很多年了,目前还是比较完善的,后面会出一个简易版本进行演示。下面文章是使用GUI进行DFX的官方文章:
https://adaptivesupport.amd.com/s/article/000036011?language=zh_CN
参考
AMD DFX 用户指南 UG947
代码