ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验

前言

目标 :每秒翻转一次LED


我会在前言中记录自己通过本实验学到的东西

  1. ZYNQ-7000的PL部分使用的时钟是200M的差分时钟,通过有源晶振提供(有源:一上电就产生时钟信号),而PS部分使用的也是有源时钟,但是是50M的单端时钟
  2. 由于PL部分的200M差分时钟,因此需要使用 IBUFDS将差分时钟转为单端时钟,如下图
    ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验_第1张图片

正文

一、点灯设计程序

要实现1秒翻转,就需要一个1秒的计数器,而使用的时钟是200M,那么就是1秒变化200_000_000次,于是计数器计到199_999_999即可翻转灯,并且清零计数器

`timescale 1ns / 1ps 
module led(
//Differential system clock
    input sys_clk_p,
    input sys_clk_n,
    input rst_n,
(* MARK_DEBUG="true" *)    output reg  led
    );
    
(* MARK_DEBUG="true" *)reg[31:0] timer_cnt;
wire sys_clk ;

IBUFDS IBUFDS_inst (//差分输入缓冲器
      .O(sys_clk),   // 1-bit output: Buffer output
      .I(sys_clk_p),   // 1-bit input: Diff_p buffer input (connect directly to top-level port)
      .IB(sys_clk_n)  // 1-bit input: Diff_n buffer input (connect directly to top-level port)
   );

always@(posedge sys_clk)
begin
    if (!rst_n)
    begin
      led <= 1'b0 ;
      timer_cnt <= 32'd0 ;
    end
    else if(timer_cnt >= 32'd199_999_999)   //1 second counter, 200M-1=199_999_999
    begin
        led <= ~led;
        timer_cnt <= 32'd0;
    end
    else
    begin
        led <= led;
        timer_cnt <= timer_cnt + 32'd1;
    end
    
end
//Instantiate ila in source file
//ila ila_inst(
//  .clk(sys_clk),
//  .probe0(timer_cnt),
//  .probe1(led)
//  );

endmodule

二、管脚约束:xdc文件

目的:将 .v 程序中的输入输出端口分配到 FPGA 的真实管脚上
对管脚进行约束,其实就是要得到xdc文件(一个 TCL 脚本)即可,那得到这个xdc文件有2种方式

2.1 管脚约束:方法一

该方法的关键是,打开开发板的用户手册,查询需要约束的输入输出在FPGA上的对应管脚是多少
如,这里是控制PL端的LED,于是查到对应的管脚号为:AE15
ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验_第2张图片
ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验_第3张图片
ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验_第4张图片
从下面图中可以看出,图上有3个输入,在管脚约束时只有2个输入约束,这是因为:
在芯片设计时,会将p和n这对差分信号搭配,只要约束了一端,另一个也会被约束,Neg Diff Pair负差分对是sys_clk_n
ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验_第5张图片
ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验_第6张图片
ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验_第7张图片

2.1 管脚约束:方法二

了解tcl脚本语法,自己编写xdc文件
选择“Add or create constraints”选项,点击“Next”——点击“Create File”按钮——在弹出的对话框里选择 File type 是 XDC,“File name”为“led”, 点击 OK 按钮
重点:要明确端口在FPGA所在Bank中的电压值

// 约束引脚号
set_property PACKAGE_PIN AE5 [get_ports sys_clk_p]
set_property PACKAGE_PIN AE14 [get_ports rst_n]
set_property PACKAGE_PIN AE15 [get_ports led]

// 约束电压
set_property IOSTANDARD LVCMOS33 [get_ports led]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property IOSTANDARD DIFF_SSTL12 [get_ports sys_clk_p]
XDC 编写的语法

约束引脚号:set_property PACKAGE_PIN " 引脚编号 " [ get_ports “端口名称”]
约束电压: set_property IOSTANDARD " 电平标准 " [ get_ports “端口名称” ]

三、添加时序约束

步骤:点击“Run Synthesis”开始综合——弹出对话框点击“OK”——综合完成以后点击“Cancel”——点击“Constraints Wizard”
ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验_第8张图片
时序约束向导分析出设计中的时钟,这里把“sys_clk_p”频率设置为 200Mhz,然后点击“Skip to Finish”结束时序约束向导
ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验_第9张图片
弹出的窗口中点击“OK”——点击“Finish”——这个时候 led.xdc 文件已经更新,点击“Reload”重新加载文件,并保存文件

四、添加激励文件

首先设计仿真时长:右击 SIMULATION 中 Simulation Settings
ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验_第10张图片
然后将下面的激励代码加入到工程中
注意,只有sys_clk_p是输入赋值,sys_clk_n直接对sys_clk_p取反得到

`timescale 1ns / 1ps
//
// Module Name: vtf_led_test
//

module vtf_led_test;
// Inputs
reg sys_clk_p;
reg rst_n ;
wire sys_clk_n;
// Outputs
wire led;

// Instantiate the Unit Under Test (UUT)
led uut (
    .sys_clk_p(sys_clk_p),  
    .sys_clk_n(sys_clk_n),     
    .rst_n(rst_n),
    .led(led)
 );

initial 
begin
// Initialize Inputs
    sys_clk_p = 0;
    rst_n = 0;
// Wait for global reset to finish
	#1000;
    rst_n = 1; 
end
//Create clock
always #2.5 sys_clk_p = ~ sys_clk_p;  
assign  sys_clk_n = ~sys_clk_p ;

endmodule 

五、仿真

点击 Run Simulation 按钮,再选择 Run Behavioral Simulation。这里做一下行为级的仿真就可以了
ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验_第11张图片

六、生成bit文件

如果仿真结果无误,就可以生成比特流文件
ALINX_ZYNQ_MPSoC开发平台FPGA教程:PL的点灯实验_第12张图片

七、ILA(逻辑分析仪)在线调试

ILA:用于在线观察内部信号的变化

你可能感兴趣的:(#,▶FPGA入门例程,fpga开发)