1 FPGA ZYBO Xilinx 按键控制LED灯 key_led

视频教程:第11.1讲 按键控制LED灯实验原理讲解_哔哩哔哩_bilibili

约束文件:digilent-xdc/Zybo-Master.xdc at master · Digilent/digilent-xdc (github.com)

原理图:Zybo Z7 - Digilent Reference B

实验任务

使用ZYBO上的PL端按键,分别控制两个PL端的LED,按下不同的按键时, 两个LED显示不同效果:

按键状态LED显示效果
无按键按下两个LED全亮
按下KEY0两个LED交替闪烁
按下KEY1两个LED同时闪烁

不同效果下两个LED灯led[0]和led[1]状态的变化:

无按键按下:led=11,11,11,11,…

按下key[0]: led=10,01,10,01,…

按下key[1]: led=11,00,11,00,…

程序设计

在这里插入图片描述
时钟频率50MHz =》时钟周期20ns

当key按下后每0.5s LED灯变化一次,计数器一个周期累加一次,所以计数器从0累加到25M=2500_0000后归零

key_led.v

module key_led(
    input   sys_clk,
    input   sys_rst_n,
    input   [1:0] key,
    output reg [1:0] led
);

reg [24:0] cnt;
reg led_controller;

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        cnt <= 25'd0;
    else if(cnt < 2500_0000)
        cnt <= cnt + 1'b1;
    else 
        cnt <= 25'd0;
end

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        led_controller <= 1'b0;
    else if(cnt == 2500_0000)
        led_controller <= ~led_controller; 
end

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        led<=2'b11;
    else case (key)
        2'b01: 
            if(led_controller == 1'b0)
                led <= 2'b10;
            else 
                led<= 2'b01;
        2'b10:
            if(led_controller == 1'b0)
                led <= 2'b11;
            else 
                led<= 2'b00;
        default: ;
    endcase 
end
endmodule

testbench: tb_key_led.v

首先定义要输入的信号,然后对其初始化,在initial模块里对时序进行控制

  • 初始时钟为0,复位为0,按键全安
  • 60ns,三个周期后,复位为高电平
  • 40ns,两个周期后,按下按键0, key = 10, led灯交替闪烁
  • 交替闪烁2000ns后,按键全按下,key=11
  • 100ns后,按键1按下,key=01, led灯同时闪烁
  • 同时闪烁2000ns后,按键全按下

例化key_led模块

时钟周期为20ns,所以每10ns取反

`timescale 1ns/1ps

module tb_key_led ();

reg sys_clk;
reg sys_rst_n;

reg [1:0] key;
wire [1:0] led;

initial begin
    sys_clk = 1'b0;
    sys_rst_n = 1'b0;
    key = 2'b11;

    #60
    sys_rst_n = 1'b1;

    #40
    key = 2'b10;

    #2000
    key = 2'b11;

    #100
    key = 2'b01;

    #2000
    key = 2'b11;
end


key_led u_key_led(
    .sys_clk(sys_clk),
    .sys_rst_n(sys_rst_n),

    .key(key),
    .led(led)
);

always #10 sys_clk <= ~sys_clk;
endmodule

ModelSim仿真

改变工作目录:File->Change Directory,添加verilog文件 -> Compile ->Compile All

在这里插入图片描述

开始仿真:Simulate->start simulate,添加设计文件 tb_key_led.v,取消使能优化enable optimization

在这里插入图片描述

添加需要查看波形图的信号:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8vlLol5q-1669973218216)(https://gitee.com/xiongyuqing/PicGo-bed/raw/master/img/image-20221202165245981.png)]

由于每0.5s也就是cnt计数到25M后led变化一次时间太长,改为25后保存,重新编译仿真

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tw6nKjDN-1669973218216)(https://gitee.com/xiongyuqing/PicGo-bed/raw/master/img/image-20221202165744123.png)]

设置运行时间100ms,点击运行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F7v5kp2A-1669973218216)(https://gitee.com/xiongyuqing/PicGo-bed/raw/master/img/image-20221202165421158.png)]

放缩到合适的尺度[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Itfiq3mI-1669973218216)(https://gitee.com/xiongyuqing/PicGo-bed/raw/master/img/image-20221202170053438.png)]

三周期系统复位,再两周期后 按下按键0:key=10:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8DihJQBn-1669973218216)(https://gitee.com/xiongyuqing/PicGo-bed/raw/master/img/image-20221202170211334.png)]

两个led灯交替闪烁:10,01,10,01

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lrwm2pcF-1669973218217)(https://gitee.com/xiongyuqing/PicGo-bed/raw/master/img/image-20221202170647472.png)]

2100ns后,key变为11

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bZY1xkMZ-1669973218217)(https://gitee.com/xiongyuqing/PicGo-bed/raw/master/img/image-20221202170827119.png)]

2200ns后,按键1被按下,key=01:两个led灯同时闪烁:11,00,11,00

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uSDrVGue-1669973218217)(https://gitee.com/xiongyuqing/PicGo-bed/raw/master/img/image-20221202171003896.png)]

vivado下载验证

添加

修改:

  • 将cnt计数改为25M
  • zybo没有复位按键,将按键3 btn[2] 变为复位按钮
    • 按钮是按下变成高电平有效,不安下是低电平,所以sys_rst_n前面的 ! 要去掉
    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zDyrDE4i-1669973218217)(https://gitee.com/xiongyuqing/PicGo-bed/raw/master/img/image-20221202171734633.png)]
module key_led(
    input   sys_clk,
    input   sys_rst_n,
    input   [1:0] key,
    output reg [1:0] led
);

reg [24:0] cnt;
reg led_controller;

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n)
        cnt <= 25'd0;
    else if(cnt < 2500_0000)
        cnt <= cnt + 1'b1;
    else 
        cnt <= 25'd0;
end

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n)
        led_controller <= 1'b0;
    else if(cnt == 2500_0000)
        led_controller <= ~led_controller; 
end

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n)
        led<=2'b11;
    else case (key)
        2'b10: 
            if(led_controller == 1'b0)
                led <= 2'b10;
            else 
                led<= 2'b01;
        2'b01:
            if(led_controller == 1'b0)
                led <= 2'b11;
            else 
                led<= 2'b00;
        default: ;
    endcase 
end
endmodule

取消需要接口的注释,并更改端口名称与程序对应:

## This file is a general .xdc for the ZYBO Rev B board
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used signals according to the project


##Clock signal
set_property -dict { PACKAGE_PIN L16   IOSTANDARD LVCMOS33 } [get_ports { sys_clk }]; #IO_L11P_T1_SRCC_35 Sch=sysclk
#create_clock -add -name sys_clk_pin -period 8.00 -waveform {0 4} [get_ports { clk }];


##Switches
#set_property -dict { PACKAGE_PIN G15   IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L19N_T3_VREF_35 Sch=SW0
#set_property -dict { PACKAGE_PIN P15   IOSTANDARD LVCMOS33 } [get_ports { sw[1] }];  #IO_L24P_T3_34 Sch=SW1
#set_property -dict { PACKAGE_PIN W13   IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L4N_T0_34 Sch=SW2
#set_property -dict { PACKAGE_PIN T16   IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L9P_T1_DQS_34 Sch=SW3


##Buttons
set_property -dict { PACKAGE_PIN R18   IOSTANDARD LVCMOS33 } [get_ports { key[0] }]; #IO_L20N_T3_34 Sch=BTN0
set_property -dict { PACKAGE_PIN P16   IOSTANDARD LVCMOS33 } [get_ports { key[1] }]; #IO_L24N_T3_34 Sch=BTN1
set_property -dict { PACKAGE_PIN V16   IOSTANDARD LVCMOS33 } [get_ports { sys_rst_n }]; #IO_L18P_T2_34 Sch=BTN2
#set_property -dict { PACKAGE_PIN Y16   IOSTANDARD LVCMOS33 } [get_ports { btn[3] }]; #IO_L7P_T1_34 Sch=BTN3


##LEDs
set_property -dict { PACKAGE_PIN M14   IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L23P_T3_35 Sch=LED0
set_property -dict { PACKAGE_PIN M15   IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L23N_T3_35 Sch=LED1
#set_property -dict { PACKAGE_PIN G14   IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_0_35=Sch=LED2
#set_property -dict { PACKAGE_PIN D18   IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L3N_T0_DQS_AD1N_35 Sch=LED3

生成bitstream

连接开发板->Open Hardware Manager->Open Target->Program Device:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ph26lhTD-1669973218217)(https://gitee.com/xiongyuqing/PicGo-bed/raw/master/img/image-20221202172334166.png)]

在开发板上测试

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值