本文介绍一种通过PS共享时钟的方式 ,为PL提供逻辑时钟的方法,此方法在工程上比较常用,可以省略一个有源晶振的物料
本文也将作为 Tiny ZYNQ 系列工程里 第一个 PS和PL联动的工程
本文在 vivado2018.3版本上 演示, 其他版本请自行研究
创建工程
1)新建一个项目,芯片型号选择 XC7Z010CLG400-1
2) 创建一个BLOCK设计
a.IP INTEGRATOR→Create Block Design,在弹出的对话框中输入设计名,最后点击“OK”,如下图所示
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-12.png)
2)在右侧的窗口里 ,点击加号,在选择框里搜索ZYNQ,并找到ZYNQ7 PROCESSING SYSTEM ,双击并打开
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-2.png)
3)软件自动生成了一个 zynq的block 如下图所示,接下来要做一些相应的设置,双击下图中的ZYNQ核
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-3.png)
4) 在ZYNQ中设置时钟功能 :
找到 设置项目中的 Clock Configuration 选项, 在PL Fabric Clocks 设置自己需要的时钟频率,这里一共有4种频率可以设置 类似于我们的PLL功能。这里我们设置50M时钟
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-50.png)
5) 在zynq中设置DDR功能 :
依次在弹窗里找到DDR Configuration→DDR Controller Configuration→DDR3,在Memory Part下拉菜单中根据自己板子上的DDR来选择相应的DDR3,本实验所用到型号:MT41K128M16JT 125,数据位宽选择16bit 最后点击“OK”,如下图所示。
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-5.png)
5)完成上述操作后, 点击“Run Block Automation”如下图所示
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-13.png)
在弹出的选项中保持默认,点击“OK”,即可完成对ZYNQ7 Processing System的配置,得到如下所示
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-51.png)
6)右键 FCLK_CLK0右边的线 ,然后点击Make External 将PS的时钟拉出,如下图所示
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-14.png)
引出后 如下图所示
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-15.png)
7)在FCLK_CLK0与 M_AXI_GP0_ACLK之间连接一根线,来为PS提供时钟(不连接会报错)
最终得到下图所示
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-16.png)
上面已经完成了ZYNQ PS部分的设置,接下来设计自己的PL模块代码和与ZYNQ PS部分连接
此时可以检查 block design 是否有设计错误 ,如果没有报错 正面设计是正确的
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-17.png)
7)创建硬件描述,source→Design Source ,右键我们创建的BLOCK工程,点击create HDL wrapper如下图所示(这一步的作用相当于将图纸转换成对应的硬件描述语言的功能)
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-12.png)
在弹出的对话框里保持默认
生成的wrapper文件会自动被设置为顶层
7)新建一个.v文件,本文命名为LED 并且将工程一中的代码 复制过来(具体可以看工程一内容)
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-18.png)
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-19.png)
复制以下代码到 LED.V中
module LED( input clk, output led ); parameter T1MS = 26'd50_000_000 ; //50M晶振时钟 reg [25:0]time_count;//时钟计数器 reg led_r; always@(posedge clk) if(time_count>=T1MS)begin time_count<=26'd0; led_r<=~led_r; end else time_count<=time_count+1'b1; assign led=led_r; endmodule
8)现在我们拥有了 时钟(ZYNQ 的PS模块),也拥有了 FPGA的LED模块,接下来要将两个模块结合起来,这里我们可以创建一个顶层TOP.V 模块然后在该顶层模块中例化ZYNQ 和LED模块(创建TOP.v的方式和上面创建LED.V的方式一致)
复制以下代码到 TOP.V
`timescale 1ns / 1ps module TOP( output led ); wire clk; LED u_1( .clk(clk), .led(led) ); zynq_wrapper u_2( .FCLK_CLK0_0(clk) ); endmodule
仔细观察发现 除了对LED 和ZYNQ 模块进行例化外,代码里还 通过 线clk 将 led模块的时钟和zynq模块的时钟输出连接在一起了
9) 对程序进行综合
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-20.png)
综合后可以看到程序的拓扑结构改变了,TOP变成顶层模块了
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-21.png)
10) 在Source 窗口中,创建一个约束文件
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-22.png)
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-23.png)
打开刚才创建的约束文件
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-24.png)
并增加以下代码来分配LED管脚
set_property PACKAGE_PIN D18 [get_ports led] set_property IOSTANDARD LVCMOS33 [get_ports led]
12)完成后点击Generate Bitstream(布线并生成二进制文件) 的操作(会提醒是否保存约束文件,点确认就好)
以上操作后,硬件PL以及PS的设置和布局已经完成,但是因为时钟是由PS端产生的,PS端的ARM运行时才能给PL提供时钟信号。直接将bit流文件下载到ZYNQ中,PS端并不会工作,也不会输出时钟给PL
想要让PS端工作,就需要在SDK创建一个工程,哪怕是个空工程也可以
以下是创建一个PS空工程的过程,详细的图文教程可以参考项目6
1)vivado中 选File→Export→Export hardware…,在弹出的对话框中勾选“include bitstream”,点击“OK”确认
2)File→Lauch SDK,在弹出的对话框中,保存默认,点击“OK”, 系统将打开SDK工程
3)新建一个工程 file→new→Application Project,来新建一个“Application Project”,在新建工程中输入自己的工程名,并选择Empty Application(空应用)
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-25.png)
并且在空应用中创建一个main.c文件
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-26.png)
![](http://www.hellofpga.com/wp-content/uploads/2022/04/image-6.png)
并在里面复制以下代码(相当于创建了个while(1)空循环的程序)
#include "xparameters.h" #include "xplatform_info.h" int main(void){ return 0; }
然后点保存。
4)用之前生成的二进制文件对FPGA进行编程,Xilinx Tools
-> Program FPGA
然后点击 “Program” (此时 DONE 灯被点亮,代表FPGA被配置完成)
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-57.png)
5)当FPGA编程成功后,我们需要初始化zynq中的处理器,右键点击刚才创建的空工程,选择Run As
-> Launch on Hardware (System Debugger)
或者 Launch on Hardware (GDB).
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-56.png)
经过以上操作,可以看到LED灯在有规律的进行闪烁,证明我们的PS已经正常向PL输出时钟了
完整工程:
您好,我在学习的时候发现分配led管脚这里代码有误:
set_property PACKAGE_PIN D18 [get_ports led_0]
set_property IOSTANDARD LVCMOS33 [get_ports led_0]
生成bitstream报错:
[DRC NSTD-1] Unspecified I/O Standard: 1 out of 1 logical ports use I/O standard (IOSTANDARD) value ‘DEFAULT’, instead of a user assigned specific value. This may cause I/O contention or incompatibility with the board power or connectivity affecting performance, signal integrity or in extreme cases cause damage to the device or the components to which it is connected. To correct this violation, specify all I/O standards. This design will fail to generate a bitstream unless all logical ports have a user specified I/O standard value defined. To allow bitstream creation with unspecified I/O standard values (not recommended), use this command: set_property SEVERITY {Warning} [get_drc_checks NSTD-1]. NOTE: When using the Vivado Runs infrastructure (e.g. launch_runs Tcl command), add this command to a .tcl file and add that file as a pre-hook for write_bitstream step for the implementation run. Problem ports: led.
[DRC UCIO-1] Unconstrained Logical Port: 1 out of 1 logical ports have no user assigned specific location constraint (LOC). This may cause I/O contention or incompatibility with the board power or connectivity affecting performance, signal integrity or in extreme cases cause damage to the device or the components to which it is connected. To correct this violation, specify all pin locations. This design will fail to generate a bitstream unless all logical ports have a user specified site LOC constraint defined. To allow bitstream creation with unspecified pin locations (not recommended), use this command: set_property SEVERITY {Warning} [get_drc_checks UCIO-1]. NOTE: When using the Vivado Runs infrastructure (e.g. launch_runs Tcl command), add this command to a .tcl file and add that file as a pre-hook for write_bitstream step for the implementation run. Problem ports: led.
原因是引脚绑定有误,应该改成
set_property PACKAGE_PIN D18 [get_ports led]
set_property IOSTANDARD LVCMOS33 [get_ports led]
就不会报错了
哦哦,可能是我 程序上调试后面出现错误了,然后程序里改过来了, 文字内容上忘记调整了。 感谢提醒,我待会检查下 修改回去