淘先锋技术网

首页 1 2 3 4 5 6 7

边沿检测

在这里插入图片描述

代码

module edge_detection(
	input 		sys_clk,
	input 		sys_rst_n,
	input 		signal_in,
	
	output 		edge_rise,
	output 		edge_down
);
	//存储上一个时钟周期的输入信号
	reg signal_in_prev;
	
	always @(posedge sys_clk or negedge sys_rst_n) begin
		if(!sys_rst_n)
			signal_in_prev <= 0;
		else begin
			signal_in_prev <= signal_in;	//两个信号相差一个时钟周期
		end
	end
	//上升沿检测:signal_in_prev为0,signal_in为1
	assign edge_rise = signal_in & ~signal_in_prev;
	assign edge_down = ~signal_in & signal_in_prev;
endmodule

若为下降沿检测,则为:

assign edge_detected = ~signal_in & signal_in_prev;

TB文件

`timescale 1ns/1ps

module tb_top();

//接口声明
reg sys_clk;
reg sys_rst_n;
reg signal_in;

wire edge_rise;
wire edge_down;

//对被测的设计进行例化

edge_detection	u_edge_detection(
	.sys_clk	    (sys_clk),
	.sys_rst_n	    (sys_rst_n),
	.signal_in		(signal_in),
	
	.edge_rise		(edge_rise),
	.edge_down		(edge_down)
);

//产生时钟
initial sys_clk = 1;
always #10 sys_clk = ~sys_clk;


//测试激励产生
initial begin
	sys_rst_n = 0;
	signal_in = 0;
	#117;
	sys_rst_n = 1;
	signal_in = 1;
	#217;
	signal_in = 0;
	#317;
	signal_in = 1;
	#517;
	signal_in = 0;
	#317;
	signal_in = 1;
	#737;

	signal_in = 1;
	#519;
	signal_in = 0;
	#817;
	signal_in = 1;
	#417;
	signal_in = 0;
	#107;
	signal_in = 1;
	#300;
end

endmodule

注意,若TB文件中输入信号signal_in的上升\下降沿和sys_clk同步,则检测不出边沿。所以我将输入信号的持续时间都设定为随机数字,来和sys_clk产生区别

仿真波形

在这里插入图片描述


改进

若出现不定值x或高阻值z,则检测不准确。

可以改进为:

assign edge_detected = ((a & ~signal_in_prev)===1)?1:0;//上升沿检测

assign edge_detected = ((~a & signal_in_prev)===1)?1:0;//下降沿检测

解释:

  • ==!==称为逻辑等式运算符,其结果由两个操作数的值决定。真值表如下:
==01xz
010xx
101xx
xxxxx
zxxxx
  • ===!===常用于case表达式的判别,所以又称为case等式运算符。它是对操作数进行按位比较,两个操作数必须完全一致,结果才为1。若两个操作数对应位都出现不定值x或高阻值z,则也可认为是相同的。真值表如下:
===01xz
01000
10100
x0010
z0001

参考

(201条消息) Verilog 相等运算符之相等和全等_verilog 全等_蒋楼丶的博客-CSDN博客