FPGA中输入信号的上升沿与下降沿采集方法

一、问题描述

        假设现在想解决的问题是通过按触摸按键来控制LED灯的亮灭。触摸按键的信号波形如下图中的touch_key所示,当未按下时,touch_key处于高电平的状态,当按下时,处于低电平的状态。而对于我们输出小灯的功能而言,并不是想让led灯的信号与touch_key的信号相同,而是想检测到按了,就亮,再检测到又按了的时候小灯灭。

        根据描述的功能我们知道,我们可以通过检测touch_key下降沿的方式来控制led灯的反转即可。这样也就引入了输入信号上升下降沿如何检测这个问题。

二、解决方案

        我们可以通过打节拍的方式捕捉上升或下降沿,首先定义一个寄存器变量touch_key_1将touch_key信号与系统时钟同步,再将touch_key1延迟一个节拍保存在新的寄存器变量touch_key_2中。然后可以采用组合逻辑判断如果touch_key_1为0且touch_key_2为1时赋值给标志位,这样,便产生了正好一个时钟周期的下降沿标志信号,最后,若标志位为高电平,使得小灯的状态反转即可。同理,捕捉上升沿也可以采用以上的方式(具体可以通过以下代码进一步理解)。

三、功能模块代码

module chumokey(
	input  clk,
	input  reset,
	input  touch_key,
	output reg led
);
	reg touch_key1;
	reg touch_key2;
	wire touch_flag;//使用组合逻辑,没有延迟一拍
	//边沿检测的方式
	always@(posedge clk or negedge reset)
	begin
	if(!reset)
		touch_key1 <= 1'b1;
	else
		touch_key1 <= touch_key;//将触摸信号同步到系统时钟下
	end
	
	always@(posedge clk or negedge reset)
	begin
	if(!reset)
		touch_key2 <= 1'b1;
	else
		touch_key2 <= touch_key1;//将同步后的触摸信号延迟一个时钟周期
	end
	
	assign touch_flag = ((touch_key1 == 1'b0)&&(touch_key2 == 1'b1));
	
	//输出信号
	
	always@(posedge clk or negedge reset)
	begin
		if(!reset)
			led <= 1'b1;
		else if(touch_flag == 1'b1)
			led <= ~led;
		else
			led <= led;
	end

endmodule

四、测试代码

`timescale 1ns/1ns
module chumokey_tb();
	reg clk;
	reg reset;
	reg touch_key;
	wire led;
	
	initial 
	begin
	clk = 1'b1;
	reset <= 1'b0;
	touch_key <= 1'b1;
	#20
	reset <= 1'b1;
	#200
	touch_key <= 1'b0;
	#1000
	touch_key <= 1'b1;
	#2000
	touch_key <= 1'b0;
	#3000
	touch_key <= 1'b1;
	end
	
	always #10 clk = ~clk;
	
	chumokey u1(//实例化模块
	  .clk(clk),
	  .reset(reset),
	  .touch_key(touch_key),
	  .led(led)
);
	
	
endmodule

五、ModelSim仿真波形

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值