按钮按下控制灯下次状态的变化
按键是低电平
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