编程语言
首页 > 编程语言> > 详细教程:vivado2019.2 & vitis2019.2下,zynq7000系列FPGA固化PL程序到外挂flash和SD卡

详细教程:vivado2019.2 & vitis2019.2下,zynq7000系列FPGA固化PL程序到外挂flash和SD卡

作者:互联网

详细教程:vivado2019.2 & vitis2019.2下,zynq7000系列FPGA固化PL程序到外挂flash和SD卡

0.简介

xilinx的zynq系列FPGA既包含了传统的FPGA部分,又嵌入了arm的硬核,分别称为PL(Programmable Logic)和PS (Processing System)。PL部分以前在ISE,现在在vivado上编程配置,包括通用的组合逻辑资源、软IP、硬IP核(包括arm核的基本配置与调用在内),使用语言就是硬件描述语言、原理图文件、IP配置;而PS部分的编程是在vitis或者sdk上进行(2019版本后sdk被升级成vitis)。一般下载软件,vivado和vitis是配套的,一起安装,分开使用。

zynq仅仅使用PL部分固化程序到非易失性存储器(外挂flash芯片、SD卡 )也需要引入arm硬核,步骤繁琐,前不久会做没多久就有些模糊了,而且其他教程要么不全面,要么是针对sdk而非vitis的,导致浪费大量时间,因此记录一下供后续查阅参考使用。

总体必要流程包括:建立PL工程 – 添加以及配置arm核 – 创建vitis工程、生成固化的bin文件 – 下载到flash或拷贝到sd

1.建立PL项目

1.1 首先打开vivado2019 创建PL工程

在这里插入图片描述
在这里插入图片描述

1.2 创建时如果是移植已有工程,可以直接在这一步添加源文件或源文件夹,约束文件在下一步添加,也可以后面创建好后添加;没有就跳过,由于我是演示,这里就直接添加。注意:可以添加HDL硬件描述语言文件、bd原理图、ip核,直接选中对应文件夹进行,但是rom ip的初始数据文件是不会被加进去的,需要后面再手动添加进去。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3 添加约束文件,包括基本的引脚约束,以及相应的时序约束,可以添加多个文件,不同文件中不同的内容会合并,重复冲突的内容会被排在后面的覆盖,而且约束文件只对顶层文件有效。

在这里插入图片描述

1.4 选择芯片型号

在这里插入图片描述

1.5 等待工程新建完成,vivado会自动根据源文件的调用关系,建立子逻辑。可以看到相应的PL部分约束文件、源文件(包括IP也被添加进来,再强调一遍,选中IP源文件夹即可,前工程综合时不能使用global的ip生成方式),而且自动建立顶层与子模块关系。

在这里插入图片描述在这里插入图片描述

1.6 调整工程文件、IP核配置。例如,Coefficient Files 里那个文件是标红的,说明有问题,这是因为我添加了一个rom IP,这个在前工程里加载了这个初始数据文件,但是新工程下路径变了,文件就找不到了。注意移植rom时都需要重新加载一下初始文件,主要是选一下路径。

在这里插入图片描述
在这里插入图片描述

1.7 PL工程准备完毕,直接生成bitstream,下载并验证,确保PL部分功能正常,也确保下载器和器件正常,这里留意一下最终生成的PL工程消耗的资源情况

在这里插入图片描述

2. vivado内添加ARM核,配置,生成顶层管理文件,并导出hardware文件。

2.1 前面完成了PL部分的建立,要完成固化还必须添加arm硬核才行,通过原理图方式添加arm硬核比较简单。这里新建一个block design的bd文件。

在这里插入图片描述

2.2 此时工程除了前面的PL文件,还有新建的block design文件。bd 文件中添加ZYNQ的IP核,也就是PS部分,包含arm核及uart、ddr等相关控制资源。

在这里插入图片描述
双击选中后,如下:
在这里插入图片描述

2.3 双击并配置ZYNQ核:

2.3.1 添加内容,需要flash外挂芯片的就勾选QSPI flash,需要SD卡的就勾选SD卡,不勾对应的程序固化就不能用。

①QSPI flash控制器:切换到Peripheral I/O Pins – > 勾选Quad SPI Flash,引脚复用根据实际硬件板子情况选择
在这里插入图片描述

②SD卡控制器: 切换到Peripheral I/O Pins – > 勾选SD,引脚复用根据实际硬件板子情况选择
在这里插入图片描述
③ UART: Peripheral I/O Pins – > 勾选相应UART引脚。

2.3.2 修改内容:

①Bank1电压设置成 LVCMOS1.8V, 根据实际硬件bank电压,我手里是正点原子的板子。
在这里插入图片描述
②DDR内容配置修改,主要是选型,注意根据实际情况选兼容的型号
在这里插入图片描述

2.3.3删除部分内容:由于没有用到PS的相应功能,很多引脚都可以去掉,只保留FIXED_IO和DDR相关引脚即可完成下载固化过程,甚至有教程说DDR都可以取消。

①M_AXI_GP0_ACLK 和 M_AXI_GP0引脚取消勾选:
在这里插入图片描述
②FCLK_RESET0_N取消勾选:
在这里插入图片描述
③FCLK_CLK0引脚取消勾选:
在这里插入图片描述

2.4 ZYNQ内部功能配置完成,确定并退出到bd文件中继续配置,可以看到引脚只有两组,这足够我们进行程序固化了,因或者说其他引脚在固化程序上是多余的。

在这里插入图片描述

2.5 点击Run Block Automation,自动生成引脚。

在这里插入图片描述
在这里插入图片描述

2.6 IP核配置设计初步检查

在这里插入图片描述

2.7 block design 文件生成output products,这实际上是先综合ZYNQ这个IP核。

在这里插入图片描述

在这里插入图片描述

2.8 此时工程内有部分源文件,即原PL部分和新建的zynq 发block design文件。然后,在zynq的block design文件上右键,生成HDL Wrapper,此时block design被例化进Wrapper文件中去。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.9 把原PL顶层文件也例化进生成的wapper.v文件中去,看似复杂,实际就是添加几个引脚然后例化一下。注意例化时的端口引脚名称要和引脚约束文件中的名称一致,建议复制原PL引脚名称。

module ps_downloadtest_wrapper
   (DDR_addr,
    DDR_ba,
    DDR_cas_n,
    DDR_ck_n,
    DDR_ck_p,
    DDR_cke,
    DDR_cs_n,
    DDR_dm,
    DDR_dq,
    DDR_dqs_n,
    DDR_dqs_p,
    DDR_odt,
    DDR_ras_n,
    DDR_reset_n,
    DDR_we_n,
    FIXED_IO_ddr_vrn,
    FIXED_IO_ddr_vrp,
    FIXED_IO_mio,
    FIXED_IO_ps_clk,
    FIXED_IO_ps_porb,
    FIXED_IO_ps_srstb,
    
    ///自行添加的PL部分引脚    
    sys_clk    ,
    sys_rst_n  ,
    led        ,
    lcd_hs     ,
    lcd_vs     ,
    lcd_de     ,
    lcd_rgb    ,
    lcd_bl     ,
    lcd_clk    ,
    uart_rxd   ,
    uart_txd   ,
    dds_out       
    );

  //自行添加的PL部分引脚  
  input              sys_clk    ;
  input              sys_rst_n  ;
  output     [1:0]   led        ;
  output             lcd_hs     ;
  output             lcd_vs     ;
  output             lcd_de     ;
  inout      [23:0]  lcd_rgb    ;
  output             lcd_bl     ;
  output             lcd_clk    ;
  input              uart_rxd   ;
  output             uart_txd   ;
  output             dds_out    ;

  inout [14:0]DDR_addr;
  inout [2:0]DDR_ba;
  inout DDR_cas_n;
  inout DDR_ck_n;
  inout DDR_ck_p;
  inout DDR_cke;
  inout DDR_cs_n;
  inout [3:0]DDR_dm;
  inout [31:0]DDR_dq;
  inout [3:0]DDR_dqs_n;
  inout [3:0]DDR_dqs_p;
  inout DDR_odt;
  inout DDR_ras_n;
  inout DDR_reset_n;
  inout DDR_we_n;
  inout FIXED_IO_ddr_vrn;
  inout FIXED_IO_ddr_vrp;
  inout [53:0]FIXED_IO_mio;
  inout FIXED_IO_ps_clk;
  inout FIXED_IO_ps_porb;
  inout FIXED_IO_ps_srstb;

  wire [14:0]DDR_addr;
  wire [2:0]DDR_ba;
  wire DDR_cas_n;
  wire DDR_ck_n;
  wire DDR_ck_p;
  wire DDR_cke;
  wire DDR_cs_n;
  wire [3:0]DDR_dm;
  wire [31:0]DDR_dq;
  wire [3:0]DDR_dqs_n;
  wire [3:0]DDR_dqs_p;
  wire DDR_odt;
  wire DDR_ras_n;
  wire DDR_reset_n;
  wire DDR_we_n;
  wire FIXED_IO_ddr_vrn;
  wire FIXED_IO_ddr_vrp;
  wire [53:0]FIXED_IO_mio;
  wire FIXED_IO_ps_clk;
  wire FIXED_IO_ps_porb;
  wire FIXED_IO_ps_srstb;

  ps_downloadtest ps_downloadtest_i
       (.DDR_addr(DDR_addr),
        .DDR_ba(DDR_ba),
        .DDR_cas_n(DDR_cas_n),
        .DDR_ck_n(DDR_ck_n),
        .DDR_ck_p(DDR_ck_p),
        .DDR_cke(DDR_cke),
        .DDR_cs_n(DDR_cs_n),
        .DDR_dm(DDR_dm),
        .DDR_dq(DDR_dq),
        .DDR_dqs_n(DDR_dqs_n),
        .DDR_dqs_p(DDR_dqs_p),
        .DDR_odt(DDR_odt),
        .DDR_ras_n(DDR_ras_n),
        .DDR_reset_n(DDR_reset_n),
        .DDR_we_n(DDR_we_n),
        .FIXED_IO_ddr_vrn(FIXED_IO_ddr_vrn),
        .FIXED_IO_ddr_vrp(FIXED_IO_ddr_vrp),
        .FIXED_IO_mio(FIXED_IO_mio),
        .FIXED_IO_ps_clk(FIXED_IO_ps_clk),
        .FIXED_IO_ps_porb(FIXED_IO_ps_porb),
        .FIXED_IO_ps_srstb(FIXED_IO_ps_srstb));

  ///自行添加的PL例化模块
  GyroControlSystem u_GyroControlSystem(
      .sys_clk   ( sys_clk   ),
      .sys_rst_n ( sys_rst_n ),
      .led       ( led       ),
      .lcd_hs    ( lcd_hs    ),       
      .lcd_vs    ( lcd_vs    ),       
      .lcd_de    ( lcd_de    ),       
      .lcd_rgb   ( lcd_rgb   ),       
      .lcd_bl    ( lcd_bl    ),       
      .lcd_clk   ( lcd_clk   ),       
      .uart_rxd  ( uart_rxd  ),       
      .uart_txd  ( uart_txd  ),       
      .dds_out   ( dds_out   )         
    );

endmodule

2.10 例化PL顶层模块进wrapper后,整个工程就wrapper一个顶层文件,其下面包含zynq的bd部分和原PL部分。

在这里插入图片描述

2.11 以wrapper为顶层文件(‘品’字符前面就是顶层文件),重新生成bitstream。

!!! 注意,此时综合布局后的PL资源占用,应该与前面单独PL综合后差不多,最多差个几个十几个lut,如果相差太多如从5000降到200,那就是前面哪里出了问题。很可能就是生成wrapper好几次,导致工程混乱,这种情况最直接的办法就是重新建工程重来一遍。

2.12 重新生成bitstream后,导出Hardware文件,特别注意要勾选Include bitstream。

在这里插入图片描述
在这里插入图片描述

2.13 此时会默认在工程文件夹下生成.xsa的文件,这就是后面创建vitis工程需要的hardware文件。

在这里插入图片描述

3. 创建vitis工程,并生成bin文件。

3.1 打开vitis2019.2,新建工程,注意名称和路径,vitis的路径应该和vivado是独立的,然后next

在这里插入图片描述

3.2 添加第2节生成的xsa硬件模板文件,可以把刚才的xsa单独复制到特定的文件夹下管理,也可以直接在原目录下。

在这里插入图片描述

3.3 选中添加的硬件包,next

在这里插入图片描述

3.4 选中下面的生成 boot 组件配置

在这里插入图片描述

3.5 选择FSBL工程模板,等待生成完成。这个FSBL就是专用于固化下载的。

在这里插入图片描述

3.6 生成完FSBL工程后如下,左侧文件栏为两部分,硬件包的warpper.xsa解压出来的和fsbl工程。

在这里插入图片描述

3.7 编译工程:在fsbl_system项目上右键,选中build,等待编译完成。

在这里插入图片描述
编译完成,且没有报错信息
在这里插入图片描述

3.8 先直接下载程序至FPGA,看是否正常运行,注意此时程序还是掉电即消失。

另外注意,直至此时启动拨码开关都是JTAG模式。
在这里插入图片描述

3.9 下载正常,即可生成所需要的bin文件。

在这里插入图片描述

3.10 在工程上选择,软件会自动添加相应路径,直接生成就可无需其他更改,记住生成的路径:

在这里插入图片描述

4. 加载bin文件到SD卡或flash中

4.1 如果是通过sd卡启动,则直接复制刚才的bin文件到sd卡的一级目录中去就行,然后板子选择启动方式为SD,插入sd重新上电即完成。如果不行,可以尝试格式化一下sd卡再尝试。

4.2 如果格式化到qspi flash芯片则进行如下两种操作,有什么目的上的区别嘛,我目前不知道,只知道操作不一样:

首先:vitis工程创建完成后,目录下会有3个工程文件夹分别是:带有wrapper的、带有_system结尾的文件夹、原来的工程名。前两个文件夹中都有elf文件,而bin文件只在最后一个文件夹中。
在这里插入图片描述

4.2.1 下载system工程至flash,此时1选择system, 2选择system文件夹中的bin文件,3选择wrapper文件夹下的elf文件。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.2.2 下载application 至flash, 1选Application , 2选_system目录下的bin文件, 3选原名路径(不带后缀,非wrapper 和system)下的elf文件,等待flash操作完成,断电、重新选择启动拨码开关至qspi、上电。

在这里插入图片描述

5.注意事项

1. 如果显示spi speed fallback to 100khz, 可能是zynq核中忘记或者错误勾选qspi模块。
2. 如果显示flash下载成功,而且通过 run as 下载也正常,但是最后flash程序异常,很可能是vivado生成wrapper文件出现问题。
-----------2021.11.08

标签:文件,zynq7000,FPGA,DDR,flash,lcd,IO,FIXED,PL
来源: https://blog.csdn.net/qq_40011737/article/details/121213825