按键按下一次控制灯的状态发生变化
按键按下是低电平
module touch_key(
input wire sys_clk,
input wire rst_n,
input wire touch_key,
output reg led
);
reg touch_key_1;
reg touch_key_2;
wire touch_flag;
///touch_key在系统时钟的控制下的边沿触发
///方式一
//always@(posedge sys_clk or negedge rst_n) //利用系统时钟控制touch_key
// if (~rst_n)
// touch_key_1 <= 1'b1;
// else if (touch_key == 1'b0) //其中用不上else if 不都是相当于touch_key是啥,touch_key_1就是啥,就只是为了让touch_key接收系统时钟控制
// touch_key_1 <= 1'b0;
// else
// touch_key_1 <= 1'b1;
//
//always@(posedge sys_clk or negedge rst_n) //将touch_key_1延迟一个时钟周期有了touch_key_2
// if (~rst_n)
// touch_key_2 <=1'b1;
// else if (touch_key_1==1'b0)
// touch_key_2 <= 1'b0;
// else
// touch_key_2 <=1'b1;
//方式2
//always@(posedge sys_clk or negedge rst_n) //利用系统时钟控制touch_key
// if (~rst_n)
// touch_key_1 <= 1'b1;
// else //相当于touch_key是啥,touch_key_1就是啥,就只是为了让touch_key接收系统时钟控制
// touch_key_1 <= touch_key;
//
//always@(posedge sys_clk or negedge rst_n) //将touch_key_1延迟一个时钟周期有了touch_key_2
// if (~rst_n)
// touch_key_2 <=1'b1;
// else
// touch_key_2 <= touch_key_1;
方式3 利用begin...end 语句写在一起,和方式一相同
always@(posedge sys_clk or negedge rst_n) //begin......end 中的语句是顺序执行的
if (~rst_n)
begin
touch_key_1 <=1'b1;
touch_key_2 <=1'b1;
end
else
begin
touch_key_1 <= touch_key; //解释:当时钟上升沿时刻,将touch_key上一时钟周期状态赋给当前时钟周期touch_key_1,将touch_key_1上一时钟周期状态赋给当前时钟周期touch_key_2,
touch_key_2 <= touch_key_1;
end
assign touch_flag = touch_key_2 & (~touch_key_1); //组合逻辑形式计算,避免时序原因使touch_key延迟一个时钟周期
always @(posedge sys_clk or negedge rst_n)
if (~rst_n)
led <=0;
else if (touch_flag == 1)
led <= ~led;
else
led <= led;
endmodule
module vtf_touch_key;
// Inputs
reg sys_clk;
reg rst_n;
reg touch_key;
// Outputs
wire led;
// Instantiate the Unit Under Test (UUT)
touch_key uut (
.sys_clk(sys_clk),
.rst_n(rst_n),
.touch_key(touch_key),
.led(led)
);
initial begin
// Initialize Inputs
sys_clk = 0;
rst_n = 0;
touch_key = 0;
// Wait 100 ns for global reset to finish
#100;
rst_n <=1'b1;
// Add stimulus here
end
always #10 sys_clk=~sys_clk;
always #35 touch_key <= {$random}%2;
endmodule