ZYNQ——PL端流水灯的实现

文章目录

  • 一、介绍
  • 二、代码编写
  • 三、引脚分配
  • 四、仿真分析
  • 五、添加 ILA IP
  • 六、板上验证


一、介绍

本文介绍的是在ZYNQ 7020黑金开发板上实现PL端流水灯的例子,开发板上PL端的LED灯总共有4个,在原理图中找到 PL LED 如下图所示,通过看图可知,给 LED 置低电平时灯才亮。
在这里插入图片描述
这里预想的实验结果是:在1秒钟内,4个LED各亮0.25秒,看起来就像流水灯一样。
LED:4个,赋值为0时即点亮。
时钟:50MHz。
复位:低电平有效,按键设为开发板上的 PL KEY1。
计数:电平每变化一次就加1,加到49999999后重新置为0。


二、代码编写

工程的创建这里不再过多介绍,之前的文章已经介绍过了。
下面的代码就是在计数到0,0.25,0.5,0.75秒这些时刻时,点亮对应的1个LED灯。

`timescale 1ns / 1ps

module led(
    input sys_clk,
    input rst_n,
    output reg[3:0] led
    );
    
reg[31:0] timer_counter;

always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
    begin
        led <= 4'b1111;  //置0时灯才亮
        timer_counter <= 32'd0;
    end
    else if(timer_counter == 32'd0)
    begin
        led <= 4'b1110;
        timer_counter <= timer_counter +32'd1;
    end
    else if(timer_counter == 32'd12_500_000)
    begin
        led <= 4'b1101;
        timer_counter <= timer_counter +32'd1;
    end
    else if(timer_counter == 32'd25_000_000)
    begin
        led <= 4'b1011;
        timer_counter <= timer_counter +32'd1;
    end
    else if(timer_counter == 32'd37_500_000)
    begin
        led <= 4'b0111;
        timer_counter <= timer_counter +32'd1;
    end
    else if(timer_counter == 32'd49_999_999)
    begin
        timer_counter <= 32'd0;
    end
    else
    begin
        led <= led;
        timer_counter <= timer_counter +32'd1;
    end
end
endmodule

下面代码实现的功能与上面代码一致,其中引入了case语句。

`timescale 1ns / 1ps

module led(
    input sys_clk,
    input rst_n,
    output reg[3:0] led
    );
    
reg[31:0] timer_counter;

always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
    begin
        led <= 4'b1111;
        timer_counter <= 32'd0;
    end
    else if(timer_counter == 32'd49_999_999)
//  else if(timer_counter == 32'd19)  //用于测试
        begin
            timer_counter <= 32'd0;
        end
    else
    begin
        case(timer_counter)
            32'd0          : led <= 4'b1110;
            32'd12_500_000 : led <= 4'b1101;
            32'd25_000_000 : led <= 4'b1011;
            32'd37_500_000 : led <= 4'b0111;
//            32'd0  : led <= 4'b1110;  //用于测试
//            32'd5  : led <= 4'b1101;
//            32'd10 : led <= 4'b1011;
//            32'd15 : led <= 4'b0111;
        endcase
        timer_counter <= timer_counter + 32'd1;
    end
end
endmodule

代码编写完成后系统会自动保存,注意看右侧边栏处是绿色还是红色,是绿色就说明代码没有错误,把鼠标放在绿色框上面就会显示下面的信息。
ZYNQ——PL端流水灯的实现_第1张图片
如果是红色就说明代码中有错误,代码出错的地方也会有红色的波浪线,如下图所示。
ZYNQ——PL端流水灯的实现_第2张图片
顺便提一下,这个Vivado默认的代码字体太小了,在菜单栏点击Tools——>Settings打开设置窗口,找到Text Editor——>Fonts and Colors,在右侧就可以设置代码的字体大小了。
ZYNQ——PL端流水灯的实现_第3张图片


三、引脚分配

在左侧 RTL ANALYSIS 下点击 Open Elaborated Design 查看原理图,如下图所示。
ZYNQ——PL端流水灯的实现_第4张图片
如果在底部没有 I/O Ports 可以点击顶部菜单栏 Window 下的 I/O Ports 选项调出。
ZYNQ——PL端流水灯的实现_第5张图片
然后就要参考原理图给这些端口分配引脚。
复位是低电平有效的,将其和开发板上PL的一个按键进行绑定,如下图所示,选择开发板上的第四个实体键 PL KEY1(前三个分别是复位和两个PS端的按键),对应的原理图引脚是KEY1。
ZYNQ——PL端流水灯的实现_第6张图片
开发板上的PL端实体按键如下图所示。
ZYNQ——PL端流水灯的实现_第7张图片
四个 LED 和按键 KEY1 对应的引脚如下图所示。
ZYNQ——PL端流水灯的实现_第8张图片
时钟选择的是 50MHz,在原理图中找到相应的名称,如下图。
ZYNQ——PL端流水灯的实现_第9张图片
然后找到该名称对应的引脚是U18,如下图所示。
ZYNQ——PL端流水灯的实现_第10张图片
其中顶部的VCC3V3代表3.3V,因此将其VCC设置为LVCMOS33*,如下图所示就分配完成了。
ZYNQ——PL端流水灯的实现_第11张图片
命名并保存该文件,该文件是后缀为xdc的约束文件,打开后如下图所示。
ZYNQ——PL端流水灯的实现_第12张图片
后续也可以通过编辑该文件实现引脚的分配或者修改。
接下来运行综合,完成后打开约束向导面板,设置系统时钟为50MHz。
ZYNQ——PL端流水灯的实现_第13张图片
这时候约束文件中也会多一行代码,如下图所示。
ZYNQ——PL端流水灯的实现_第14张图片


四、仿真分析

在下载比特流文件到开发板之前,之所以先在Vivado软件中仿真,是因为生成比特流的过程太慢了,如果你每改动一次就在板子上验证一下实在是太费时间了,所以提前在仿真中调试好代码,有把握后到开发板上验证即可。
上面提供的代码中,用于测试的代码可以将计数量缩小,这样在仿真中就可以缩短仿真时间,这对整体的功能实现没有任何影响,不过要在生成比特流文件时记得将代码改过来。
在 Simulation Settings下可以设置仿真的运行时长,这里根据需要设置。
ZYNQ——PL端流水灯的实现_第15张图片
新建一个用于仿真的源文件,如下图。
ZYNQ——PL端流水灯的实现_第16张图片
完成后在文件中写入下面的仿真测试代码。

`timescale 1ns / 1ps

module sim_led();
reg sys_clk; 
reg rst_n;
wire [3:0] led;

initial 
begin 
sys_clk = 1; 
rst_n = 0 ; 
#100;  //延迟100ns
rst_n = 1; 
end 

//Create clock 
always #10 sys_clk = ~ sys_clk; //时钟频率为50MHZ,周期为20ns,因此每延迟10ns,时钟翻转一次

// Instantiate the Unit Under Test (UUT) 例化待测设计
led  uut_led(
	.sys_clk (sys_clk),
	.rst_n (rst_n),
	.led (led)
	);
	
endmodule

先用Vivado自带的仿真工具进行简单的行为仿真,得到的结果如下图所示。仿真这部分的操作如果不太熟悉可以参考文章:Vivado中Simulator仿真软件的使用。
ZYNQ——PL端流水灯的实现_第17张图片
通过上述仿真,其结果与代码中预设的一致,那下面就可以到开发板上验证了。如果仿真结果与自己的预想不一致,就要修改代码,重新仿真,直到结果与自己的预期相符,然后再到开发板上验证。


五、添加 ILA IP

ILA(Integrated Logic Analyzer),即集成逻辑分析仪,这里添加两个探针,分别设置为4位和32位,对应代码中的 led 和 timer_counter。这一部分的详细介绍可以参考文章:使用Vivado软件进行硬件调试。
ZYNQ——PL端流水灯的实现_第18张图片
生成后打开ila_0文件,复制84-90行的内容,注意有多个探针时的位数设置,在代码中不要搞错。
ZYNQ——PL端流水灯的实现_第19张图片
在led.v文件的endmodule前添加下面的代码。
ZYNQ——PL端流水灯的实现_第20张图片
ILA 就添加完成了。


六、板上验证

接下来点击生成比特流(Generate Bitstream),这个时间会比较长,完成后弹出下面对话框,选择Open Hardware Manager。
ZYNQ——PL端流水灯的实现_第21张图片
连接好开发板的JTAG接口,给开发板上电,然后下载比特流文件到开发板。
ZYNQ——PL端流水灯的实现_第22张图片
添加ILA后Debug probes file这里也会有文件。
ZYNQ——PL端流水灯的实现_第23张图片
下载进度条满了之后就说明下载成功了,PL端流水灯的演示如下动图所示。

使用集成逻辑分析仪查看,给其设置一个触发值25000000,可以看到,从25000001开始,LED的值发生了变化,如下图所示。
ZYNQ——PL端流水灯的实现_第24张图片
当然,在12500000和37500000处,LED的值也会发生变化。通过仿真、开发板上LED的动图以及ILA分析,其结果是按照代码中设置的那样输出的。


以上就是 ZYNQ——PL端流水灯的实现的全部内容了!
参考资料:
ZYNQ 开发平台 FPGA 教程 AX7020

你可能感兴趣的:(zynq,zynq,Vivado)