本文主要演示针对Petalinux 基础功能的 Vivado 硬件工程搭建
- 此章节内容适用于Lemon ZYNQ主板,如是其他板子请看对应板子目录
- 本文在 vivado2018.3 以及 Petalinux2018.3 版本上进行演示
Lemon Zynq的Petalinux 的基础硬件工程将不再细分每一个功能模块,而是将Petalinux 可能用到的基础功能包括 UART,千兆网络NET,USB HOST,SD,FLASH,LED 和按键等基础功能都一并进行添加,来方便大家在最短的时间内将Petalinux的基础功能跑起来。 等熟悉这个流程后,大家就可以在这个工程的基础上再进行其他功能的二次开发了。
本次基础工程将添加下列硬件功能:
- 512MB DDR设置
- QSPI FLASH
- SD
- USB
- UART
- Emio X8 (LED X4 , KEY X4)
- NET
一、Vivado工程创建
1)打开Vivado 新建一个项目, 新建一个VIVADO 工程,打开软件 选中Create Project, 如下图所示

2)点击NEXT ,在出现的第二个对话框“Project name”中输入工程名;在“Project location”中选择保存路径;勾选“Create project subdirectory”(默认),最后点击“Next” 备注,所有的路径均不能出现中文名称

3)点击 RTL PROJECT 选项,点击NEXT

4) 第四步Add Sources 选项直接留空,NEXT
5)第五步Add Constraints 选项直接留空,NEXT
6) 选择芯片型号 板子的芯片型号为 XC7Z020 封装是CLG484 所以型号我们选择 xc7z020clg400-1 (如果是XA7Z020的车规级芯片版本,这里也选xc7z020clg400-1)

7)确认所选信息 点击“Finish”,完成vivado的工程创建

之后 工程就新建好了, vivado 进入到开发界面

二、创建一个BLOCK设计
1)IP INTEGRATOR→Create Block Design,在弹出的对话框中输入设计名,最后点击“OK”,如下图所示

2) 在右侧的窗口里 ,点击加号,在选择框里搜索ZYNQ,并找到ZYNQ7 PROCESSING SYSTEM ,双击并打开

3)软件自动生成了一个 zynq的block 如下图所示,接下来要做一些相应的设置,双击下图中的ZYNQ核

4)依次在弹窗里找到DDR Configuration→DDR Controller Configuration→DDR3,在Memory Part下拉菜单中根据自己板子上的DDR来选择相应的DDR3,本实验所用到型号:MT41K256M16RE-125,数据位宽选择16bit 最后点击“OK”,如下图所示。

5)因为Lemon ZYNQ主板的PS时钟是50M的晶振输入的,所以这里需要把默认的PS输入时钟33.33M改成50M

6)使能QSPI的功能 如下图所示(当QSPI 时钟大于40MHZ的时候 就需要勾选Feedback clk)

7) 因为我们Lemon ZYNQ 的USB功能,SD功能,和网络功能都是接在芯片的BANK501上的,而bank501在硬件上接的1.8Vbank电压,所以这里我们需要手动对ZYNQ的BANK1(501) I/O 电压设置成LVCMOS 1.8V。 重要

8)使能SD 0的功能 MIO40-45

9) 使能 ENET0 和 MDIO 功能, ENET0对应MIO 16-27 MDIO对应 MIO52-53

网络部分还有个Reset 信号,电路上是接在MIO9的,需要先使能GPIO MIO功能,再对ENET0 reset脚进行设置。

MIO的网络还要检查时钟,以免最后不能访问网络,这里ENET0 的Clock Source 一定要是IO PLL

10)使能zynq的USB0功能

另外 由于我们的USB PHY的信号是接在mio的46脚上 所以这里同样需要使能 MIO的USB RST信号(系统同时会默认勾选I2C复位 ,可以关闭)

11) 使能UART 0 选择MIO方式,下拉菜单里选择MIO14-15

12) 到这里,ZYNQ内核就已经按照我们的预设配置好了,接下来按照我们的预期添加8个IO口,用于4个LED灯,和4个按键,作实验用。

13 )因为工程暂时用不到 AXI功能,所以可以先禁用AXI功能

14)之后按下OK键完成ZYNQ的配置。回到BD界面
15) 按下 Run Block Automation ,并按下OK键

16) 将我们的EMIO GPIO 通过 External 的方式映射出来,右键 External


17)source→Design Source ,右键我们创建的BLOCK工程,点击create HDL wrapper如下图所示。

18)在弹出的对话框里保持默认

19)软件自动为我们生成HDL文件

至此,Block Design 部分已经设置完成。
三、添加我们的FPGA部分顶层TOP_module代码,并例化ZYNQ模块
其实这里我们不增加顶层模块,直接编译综合也是可以,但是考虑到我们的工程后续可能会添加PL部分(即FPGA)的代码,所以这里我们还是增加了顶层模块。
1)在主界面点击左侧 Add Sources ,点击 复选框的Add or create design sources 选项 并点击NEXT

2)在出现的Add Sources 中 选择创建新文件 Create FILE 如下图所示,并在弹出的窗口中 选择类别为Verilog ,在FILE name中填写文件的名称,这里用TopModule代替,点击OK 并点击FINISH
3)在跳出的窗口中可以填写模块的输入输出信号,由于这部分工作在代码中可以完成,所以这里直接点OK 完成VERILOG 文件的创建。
4)双击打开刚才创建的TopModule文件 ,这里我们可以添加我们的FPGA代码,如点灯代码等,这里我们暂时不在工程中添加任何其他功能,所以我们只需要对刚刚定义的Block design中创建的ZYNQ模块进行例化即可。
5) 在TopModule程序中例化ZYNQ模块
打开刚才的TopModule.v,并在 endmodule的 上方添加ZYNQ_CORE 例化的代码,以及在模块定义上添加一个output信号 led_emio,用于引出ZYNQ模块的EMIO脚。
ZYNQ_CORE_wrapper zynq_u(
.GPIO_0_0_tri_io(GPIO_EMIO)
);
肯定有人会问 ZYNQ_CORE 里明明有那么多信号,为啥我都留空了只保留了GPIO_0_0_tri_io信号,其实这里我也偷懒了,因为本章中ZYNQ只添加了一个EMIO外设,而剩下诸如DDR FIX_IO这种信号线因为本身是硬件连接的,所以即使程序例化的时候留空,这些信号线仍然是硬件同外部连接的。当然你也可以将所有的信号添加全。(备注 如果有其他的EMIO 或者AXI 等涉及到和FPGA通讯或者映射的信号,则这里例化的时候必须添加信号上去)
这样我们就在TopModule.v中增加了ZYNQ部分了。 (这里容易产生误区,ZYNQ模块是硬件存在的,并不是实例化凭空出现的,只是通过例化这种方式将PS和顶层模块PL两部分结合在一起了)
完整代码如下:(你也可以根据需求在TopModule中增加自己的内容)
`timescale 1ns / 1ps
module TopModule(
inout [7:0]GPIO_EMIO
);
ZYNQ_CORE_wrapper zynq_u(
.GPIO_0_0_tri_io(GPIO_EMIO)
);
endmodule
四、创建约束文件,并定义管脚
1)Add Source → Add or create constraints 点Next

因为这个项目没有创建过约束文件 所以这里创建一个约束文件,并在File name 里设置约束文件的名称,并且点击FINISH 完成约束文件的创建

2)Sources → Constraints 里找到刚才创建的约束文件 双击并打开该XDC约束文件

在约束文件里面复制下面代码来对输出的GPIO进行管脚。
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_EMIO[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_EMIO[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_EMIO[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_EMIO[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_EMIO[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_EMIO[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_EMIO[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_EMIO[0]}]
set_property PACKAGE_PIN M14 [get_ports {GPIO_EMIO[3]}]
set_property PACKAGE_PIN N16 [get_ports {GPIO_EMIO[2]}]
set_property PACKAGE_PIN P14 [get_ports {GPIO_EMIO[1]}]
set_property PACKAGE_PIN R14 [get_ports {GPIO_EMIO[0]}]
set_property PACKAGE_PIN L19 [get_ports {GPIO_EMIO[7]}]
set_property PACKAGE_PIN L20 [get_ports {GPIO_EMIO[6]}]
set_property PACKAGE_PIN D20 [get_ports {GPIO_EMIO[5]}]
set_property PACKAGE_PIN D19 [get_ports {GPIO_EMIO[4]}]
约束中,我们将GPIO_EMIO3-0 分别对应LED3-LED0 。 GPIO_EMIO7-4 对应按键的BTN3-BTN0。 后续实验中我们将会用到。
五、编译综合,并导出hdf文件
1)按下绿色箭头对工程进行编译

2)按下Generate Bitstream 完成综合以及生成bit文件 (需要等待很久)

3)File→Export→Export hardware…在弹出的对话框中勾选“include bitstream”,点击“OK”确认,如下图所示。


4)File→Lauch SDK,在弹出的对话框中,保存默认,点击“OK”,如下图所示。

5) 系统将自动打开SDK开发环境

其中SDK工程platform 下的hdf文件就是我们需要的系统硬件描述文件,这个需要交给petalinux 进行交叉编译用。(可以在这个界面下直接右键system.hdf进行复制)

备注:如果不打开SDK工程文件我们仍能找到这个hdf文件。一般在 下列路径中
<project_name>.sdk<project_name>_wrapper.hdf
其中<project_name>为你在Vivado中所命名的工程名

至此我们的硬件工程的准备工作已经完成了。
- 本文的完整工程下载:01_PetaLinuxSystem
- VIVADO的版本:2018.3
- 工程创建目录:E:\Lemon_ZYNQ\PETALINUX\01_PetaLinuxSystem