ZYNQ | 可重构技术PCAP(1)——例程学习
Intro & Concept
这学期开始着手做毕设了,毕设里一个重要的组成部分是使用Zynq7020实现可重构技术,大概的目标是板子上电后,能从存储器(Flash、ROM啥啥啥的)中读取bit stream并将其下载到PL端。网上参考都是利用PS把bit stream下载到PL端。注意,这里是全局重构(Full configuration,我瞎起的名字),指的是把完整的bit stream文件下载到PL端,而与之对应的还有另外一种技术叫Partial Reconfiguration,本人暂时还妹学会,跳过。
为什么是从PS下载到PL端,而不能直接把bit stream下载到PL端呢?当然是没有参考我不会写啦。实际上这是对ZYNQ整个架构的理解问题。
ZYNQ一般被看成PS+PL,但是在下载程序时的PS与PL实际上地位不等,不能简单的认为是ARM芯片+FPGA芯片,然后中间用许多线连着。(虽然也可以这么说)参考UG585 Chapter 6 Figure 6-1,这里很明显可以看到在ZYNQ启动后(假设是从Flash启动),那么APU会先执行BootROM,然后是FSBL、SSBL,在非安全模式下(non-secure mode),PL端是在FSBL和SSBL期间被Programed。
The FSBLcode can clear, program and enable the PL.
这就意味着PL是后于PS启动。继续阅读UG585 Chapter 6,这里摘一下文档。
The PL can be configured and reconfigured by PS software in secure or non-secure mode. The PCAP path is the most commonly deployed method as it does not require that the PL be pre-programmed with a bitstream. The PL can also be configured by the TAP controller on the JTAG chain in non-secure mode. Multiplexing of the datapath is done in the PL configuration module using the devc.CTRL [PCAP_MODE] and [PCAP_PR] bits.
-- from 6.1.8 PL Configuration Paths.
这段话就表明了可重构技术是可能实现的。(废话
UG585给了总共3条路,具体参考下图:
- JTAG Debug Path
- PCAP Path
- ICAP Path
三条路都可以对PL进行配置(配置指configure,烧写比特流)。但ICAP Path
需要占用PL的逻辑,对于部署而言不友好,处于一个很尴尬的地位。那剩下的两条路,JTAG模式是在调试环境下使用,实际生产工作环境中,PS端从Flash读取启动镜像后,就会通过PCAP Path
来Program PL。因此,在启动阶段,可以把PL看成PS的一个外设,下载数据的通路即是PCAP Path。可以看到图中两个多路选择器实际上都是devc的寄存器值,所以可重构的关键就是正确配置devc的寄存器。具体编程指南参考UG585 Chapter 6,(虽然我也妹读完呐)。
理论成立,实践开始。
Start Code
Preparation
本次实验使用的是Alinx7020开发板,连接电源线、UART、JTAG。一通操作,创建Vivado工程、创建Block Design、添加ZYNQ IP核、打开MIO的QSPI(后续要用)、UART、GPIO(optional)。添加好后继续无脑操作,Auto连线、Validate验证、Wrapper、Generate,导出硬件,打开SDK,创建空工程。
另外,要提前准备一份比特流,并通过JTAG下载到PL端进行验证,记住该bit流的效果。笔者准备了一个LED闪烁的bit stream,这里记住,从PS端烧写到PL端的不是.bit
文件,而是比特流对应的.bin
文件,通过Vivado自带的工具可以进行转换。
选择Generate Memory Configuration File...
,
参数如下,该操作即将.bit
文件转换为.bin
文件。
DevC Example
打开SDK后并创建好工程后,在板级支持包中找到system.mss
,可以找到devcfg
的例程,导入轮询例程,下面截取一部分代码:
1 |
|
实际上这个函数非常简单,即初始化+DMA,XDcfg_Transfer()
函数是实际将bit流写入到PL端的函数。函数原型如下:
1 |
|
很明显,这里DMA传输的目的地为PL端,参考程序中只需要修改源地址和数据长度即可将任意bit流下载到PL端。例程中的宏定义BIT_STREAM_LOCATION
以及BIT_STREAM_SIZE_WORDS
,可以认为是一种不安全的操作,直接指定地址会造成数据的冲突。
Experiment
从DDR到PL
例程即是从DDR的某一个地址将bit文件通过DMA的方式传输到PL端。使用Xilinx SDK自带的工具将预先准备好的二进制文件
配置示例如下:
注意这里的写到DDR内存中的地址一定要注意,不能超出实际DDR的内存空间,地址也不能过低,由于运行PS端裸机代码运行过程中一般都会在较低的地址运行程序,因此需要避开低地址空间。(这也是这段例程最不好的地方,直接访问一个地址,既不安全也不可靠。)
注意,在将文件Restore进Memory之前,首先需要运行一下CPU,直接run,不管结果如何,目的是先让CPU启动。
然后将例程中的宏定义进行修改:
1 |
|
修改完后,Restore Memory,运行程序,即可观察到相应的现象。
至此从DDR3到PL的可重构实验即完成。后续介绍从Flash读取文件并将其烧写到PL端。