代码
作为按键模块,加入了松手检测,通过判断按键的值来检测是否松手
使用模块需要输入key 和输出led
module key_led(
//input
input sys_clk,
input sys_rst_n,
input [3:0] key,
//output
output reg [3:0] led
);
//参数
//parameter CNT_MAX = 25'd5000000;
parameter CNT_MAX = 25'd2000;
//reg define
reg [24:0] cnt0;
reg [24:0] cnt1;
reg [24:0] cnt2;
reg [24:0] cnt3;
reg [3:0] key_reg ;
reg [3:0] flag_time;
reg flag0;
reg flag1;
reg flag2;
reg flag3;
initial led <= 4'b0000 ;
//*****************************************************
//** main code
//*****************************************************
//按键持续0.1s
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)begin
cnt0 <= 25'b0;
cnt1 <= 25'b0;
cnt2 <= 25'b0;
cnt3 <= 25'b0;
led <= 4'b0000 ;
end
else begin
key_reg<= key ;
if(key_reg[0]==0)begin
cnt0 <= cnt0 + 25'b1 ;
if(cnt0 > (CNT_MAX-25'b1))begin
cnt0 <= 25'b0 ;
flag0 <= 1'b1 ;
// led[1]<=~led[1] ;
end
end
else begin
if(flag0==1'b1)begin
led[0]<=~led[0] ;
flag0 <= 1'b0 ;
end
else
cnt0 <= 25'b0 ;
end
if(key_reg[1]==0)begin
cnt1 <= cnt1 + 25'b1 ;
if(cnt1 > (CNT_MAX-25'b1))begin
cnt1 <= 25'b0 ;
flag1 <= 1'b1 ;
end
end
else begin
if(flag1==1'b1)begin
led[1]<=~led[1] ;
flag1 <= 1'b0 ;
end
else
cnt1 <= 25'b0 ;
end
if(key_reg[2]==0)begin
cnt2 <= cnt2 + 25'b1 ;
if(cnt2 > (CNT_MAX-25'b1))begin
cnt2 <= 25'b0 ;
flag2 <= 1'b1 ;
end
end
else begin
if(flag2==1'b1)begin
led[2]<=~led[2] ;
flag2 <= 1'b0 ;
end
else
cnt2 <= 25'b0 ;
end
if(key_reg[3]==0)begin
cnt3 <= cnt3 + 25'b1 ;
if(cnt3 > (CNT_MAX-25'b1))begin
cnt3 <= 25'b0 ;
flag3 <= 1'b1 ;
end
end
else begin
if(flag3==1'b1)begin
led[3]<=~led[3] ;
flag3 <= 1'b0 ;
end
else
cnt3 <= 25'b0 ;
end
end
end
endmodule
管脚约束
#时序约束
create_clock -period 20.000 -name sys_clk [get_ports sys_clk]
#IO管脚约束
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN U2 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
set_property -dict {PACKAGE_PIN T1 IOSTANDARD LVCMOS33} [get_ports {key[0]}]
set_property -dict {PACKAGE_PIN U1 IOSTANDARD LVCMOS33} [get_ports {key[1]}]
set_property -dict {PACKAGE_PIN R2 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN R3 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property PACKAGE_PIN W2 [get_ports {key[2]}]
set_property PACKAGE_PIN T3 [get_ports {key[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key[3]}]
set_property PACKAGE_PIN V2 [get_ports {led[2]}]
set_property PACKAGE_PIN Y2 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
固化文件
# 固化文件原语
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE Yes [current_design]
问题
如果按照两个always语句来写,会出现问题。
以下代码仿真没问题,实际上上板操作,灯不会亮。
module key_led(
//input
input sys_clk,
input sys_rst_n,
input [3:0] key,
//output
output reg [3:0] led
);
//参数
parameter CNT_MAX = 25'd2000;
reg [24:0] cnt;
reg [3:0] key_reg;
reg [3:0] flag_time;
reg flag0;
initial led <= 4'b1001;
//按键持续0.1s
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n) begin
cnt <= 25'b0;
flag0 <= 1'b0;
end
else begin
key_reg <= key;
if(key_reg[1] == 0) begin
cnt <= cnt + 25'b1;
if(cnt > (CNT_MAX-25'b1)) begin
cnt <= 25'b0;
flag0 <= 1'b1;
end
end else begin
cnt <= 25'b0;
end
end
end
//在flag0为1时改变led的值,同时将flag0重置为0
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n) begin
flag0 <= 1'b0;
led <=4'b0000;
end
else if(flag0 == 1'b1) begin
led <= 4'b1111;
end
end
endmodule