【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash

本教程以米联客XC7A35T FGG484-2开发板为例,详细讲解一下用Xilinx Vivado 2020.1创建MicroBlaze软核工程,然后再用Xilinx Vitis 2020.1建立Hello World C程序工程的完整操作步骤。最后程序运行起来后,还要在Vitis里面将程序固化到SPI Flash中,断电再开机后也能启动运行。

(关于带外部DDR3内存的工程的建法,请参阅https://blog.csdn.net/ZLK1214/article/details/113201726)

米联客开发板自带的那个PDF教程(名字叫Artix-7修炼秘籍)里面,讲MicroBlaze的时候用到了DDR3内存,最后C程序是跑在DDR3内存里面的。固化的时候,需要多固化一个SREC SPI Bootloader工程。bootloader的作用是开机的时候将SPI Flash里面存的C语言程序加载到外部DDR3内存上,然后跳转过去执行,这个过程(对helloworld程序来讲)需要半分钟的时间,这使得开机启动非常慢。

实际上MicroBlaze的运行根本就不需要DDR3内存,在FPGA片内的BRAM中运行就可以了。没了DDR3内存,Vivado block design会变得简单很多。没有了SREC SPI Bootloader,Vitis里面固化程序也变得非常非常简单,开机也能瞬间启动,不会等上半分钟串口才能输出个Hello World。

开发板上的晶振频率为50MHz,是接到FPGA的V4引脚上的。FPGA片内BRAM内存的容量为225KB(手册上写的是1800b,除以8就得到了225KB)。存储程序用的外部SPI Flash型号为MT25QL128。

ALINX基于Vivado的MicroBlaze基础教程.pdf:https://pan.baidu.com/s/1q3wgbaq2OX0pozCyTo2faQ(提取码:m6zg)

在Vivado 2020.1里面建好一个空白的工程后,首先新建一个Block Design,名称可保持默认:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第1张图片

然后,添加MicroBlaze IP核:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第2张图片

点击Run Block Automation:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第3张图片

MicroBlaze运行内存选择128KB:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第4张图片

Run Block Automation自动生成了很多外设出来。其中就有clk_wiz_1倍频器,但时钟输入端是差分输入,还带有一个reset复位输入。我们板子上的50MHz晶振时钟输出只有1个引脚。所以双击这个IP修改一下设置。

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第5张图片

输入的时钟改为50MHz,单端输入:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第6张图片

输出的时钟为100MHz,作为MicroBlaze的运行时钟。下面要把reset复选框去掉,使Clocking Wizard没有复位输入引脚。

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第7张图片

然后,在clk_in1的右键菜单上选择Make External命令,引出clk_in1引脚。后面需要在xdc文件里面将这个引脚和FPGA上连接外部晶振的V4引脚绑定。

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第8张图片

Clocking Wizard输出的locked信号代表倍频是否成功。locked=0时说明倍频还未成功,locked=1时说明倍频已成功,时钟输出已稳定。因此这个locked引脚可以作为MicroBlaze的复位引脚,在Block Design里面手动连线到rst_clk_wiz_1_100M的ext_reset_in引脚上,低电平时复位。

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第9张图片

接下来,添加AXI Uartlite串口IP核,用于程序中printf打印和scanf输入:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第10张图片

将串口的波特率改为115200:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第11张图片

点击Run Connection Automation,自动连线:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第12张图片

最终的Block Design连线如下图所示。没有了DDR3内存,整个Block Design是非常简单的。

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第13张图片

在Address Editor选项卡上可以看到片内BRAM内存的地址范围,以及Uartlite的寄存器地址范围:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第14张图片

点击Generate Block Design:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第15张图片

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第16张图片

然后,点击Create HDL Wrapper,根据Block Design创建Verilog顶层模块:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第17张图片

有了生成的Verilog模块代码(design_1_wrapper.v),就可以点Synthesis综合了:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第18张图片

等待Generate Block Design和Run Synthesis完毕:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第19张图片

综合完毕后,选择Open Synthesized Design,点击OK,接下来我们要绑定FPGA管脚。

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第20张图片

需要配置的引脚就三个:50MHz晶振时钟输入引脚、串口接收引脚和串口发送引脚。是不是很简单?

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第21张图片

将引脚配置保存为pins.xdc文件,然后打开这个xdc文件,我们要加一段代码,使板子开机启动的时候,用4线QSPI方式加载SPI Flash中保存的程序。

set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE Yes [current_design]

这个步骤非常关键!!!!不添加这段代码的话,开机的时候就是1线启动,那就要花好几秒的时间才能启动成功,才打印的出来Hello World 。
而且这个地方一旦忘了这个步骤,建好Vitis工程后,再来添加这段代码,就只有把整个Vitis workspace删了重建,新的设置才能生效!!!
所以千万不能忘了!!!!!!!!

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第22张图片

点击Generate Bitstream,生成Vivado工程的bit文件:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第23张图片

bit文件生成成功后,点击Export Hardware,导出xsa文件:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第24张图片

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第25张图片

这里要选择Include bitstream:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第26张图片

注意一下xsa文件的保存路径。

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第27张图片

有了xsa文件,就可以启动Vitis 2020.1了。

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第28张图片

这里选择Vitis workspace的存放位置,单独再找一个文件夹来存放Vitis工程:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第29张图片

进去后,先建立Platform Project:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第30张图片

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第31张图片

选择刚才Vivado导出的xsa文件:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第32张图片

选择完之后要Build一下Platform工程:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第33张图片

再建立一个Application Project,用来写C语言代码:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第34张图片

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第35张图片

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第36张图片

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第37张图片

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第38张图片

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第39张图片

直接用里面现成的代码Build一下:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第40张图片

然后点击运行:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第41张图片

提示正在将程序下载到FPGA中:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第42张图片

下载完了之后,就可以看到串口里面输出了Hello World了。

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第43张图片

但是这个程序掉电就会丢失,我们需要将这个程序固化到SPI Flash里面,让开发板断电后一开机就能运行这个程序,打印出Hello World。

固化的方法非常简单,只需要两步。

第一步是在Program FPGA对话框里面,将Vivado工程的Verilog代码生成的design_1_wrapper.bit文件Vitis工程的C代码生成的hello_world.elf文件合并成一个download.bit文件

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第44张图片

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第45张图片

第二步就是在Program Flash对话框中,把合并后的download.bit文件烧写到SPI Flash里面:

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第46张图片

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第47张图片

注意选择SPI Flash的型号。Offset可以不用填,默认就是0。

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第48张图片

【教程】Xilinx Vivado/Vitis 2020.1创建最简单的MicroBlaze工程运行Hello World C语言程序(不使用外部DDR3内存),并固化到SPI Flash_第49张图片

这个时候就固化成功了。开发板断电之后,程序也能启动运行。并且是瞬间就启动成功,在串口中打印出Hello World。

 

如果发现microblaze程序固化后,开机启动很慢,要好几秒之后串口才能打印出Hello World。
那肯定是忘了往Vivado工程里面的xdc文件添加SPI 4位模式的配置了。
这个时候要回到Vivado工程改xdc文件,然后generate bitstream,然后export hardware。
然后,整个Vitis工程都必须删了重建!!!!!!
重新建立Platform工程,Build一下,再重新建立Application工程,再Build一下
点Program FPGA生成download.bit,再点Program Flash把download.bit固化到flash
开发板断电,再上电,瞬间就打印出了hello world。

切记,一旦忘了改xdc文件导致fpga microblaze开机启动很慢,vitis工程就必须重建。仅仅update hardware specification,clean一下再build一下platform工程,是没有用的。

 

工程里面没有配置gpio模块,如果在c代码中加入gpio的代码,会提示找不到头文件,以及XGpio_Initialize、XGpio_DiscreteWrite等函数,代码编译失败。

14:17:00 **** Incremental Build of configuration Debug for project hello_world ****
make all 
'Building file: ../src/helloworld.c'
'Invoking: MicroBlaze gcc compiler'
mb-gcc -Wall -O0 -g3 -c -fmessage-length=0 -MT"src/helloworld.o" -IE:/fpga_projects/test4/microblaze_test3/microblaze_test3/export/microblaze_test3/sw/microblaze_test3/standalone_domain/bspinclude/include -mlittle-endian -mcpu=v11.0 -mxl-soft-mul -Wl,--no-relax -ffunction-sections -fdata-sections -MMD -MP -MF"src/helloworld.d" -MT"src/helloworld.o" -o "src/helloworld.o" "../src/helloworld.c"
../src/helloworld.c:50:10: fatal error: xgpio.h: No such file or directory
   50 | #include 
      |          ^~~~~~~~~
compilation terminated.
'Finished building: ../src/helloworld.c'
' '

14:17:00 Build Finished (took 314ms)

这时应该:
(1)回到vivado工程的block design里面,把AXI GPIO模块加进去,按ctrl+s键保存,然后generate block design
(2)run synthesis,在schematic里面配置gpio管脚,然后generate bitstream,再export hardware
(3)回到vitis工程里面,这个时候就不需要删了重建vitis工程了,只需在(Assistant窗格)platform工程上update hardware specification(注意xsa文件的路径对不对,有可能是错的,要手动改过来),然后build一下platform工程
(4)这个时候,含有gpio代码的application工程就能编译通过了,能够找到xgpio.h和gpio的函数了

你可能感兴趣的:(FPGA,FPGA,Xilinx,MicroBlaze,Vitis,固化)