用verilog实现边沿检测(上升沿,下降沿,双边)

不是很难却困扰过我的一个问题

边沿检测?不是可以直接把待检测的信号写在always块里吗?

其实不是的,这个题目的本意是在同步电路中实现这样的功能,如果把待检测的信号写在always块里面,相当于把输入信号接到了触发器的clk上,这样电路就变成异步的了,后面还需要把信号同步,得不偿失。

正解是使用两个触发器,再通过逻辑组合判断边沿。

边沿检测代码:

module edge_detector(input clk, rst_n, din, output raising_edge_detect,falling_edge_detect,double_edge_detect);

reg q0,q1;

assign raising_edge_detect = q0 & (~q1);
assign falling_edge_detect = ~q0 & q1;
assign double_edge_detect = q0 ^ q1;

always@(posedge clk, negedge rst_n)
begin
	if(!rst_n)
	begin
		q0 <= 0;
		q1 <= 0;
	end
	else
	begin
		q0 <= din;
		q1 <= q0;
	end
end

endmodule

testbench:

`timescale 1ns/1ns

module edge_detector_tb;

reg CLK,RST_N,DIN;
wire RAISING_EDGE_DETECT,FALLING_EDGE_DETECT,DOUBLE_EDGE_DETECT;
reg i,j;

edge_detector U_edge_detector(
.clk(CLK), 
.rst_n(RST_N), 
.din(DIN), 
.raising_edge_detect(RAISING_EDGE_DETECT), 
.falling_edge_detect(FALLING_EDGE_DETECT), 
.double_edge_detect(DOUBLE_EDGE_DETECT)
);

initial
begin
	CLK = 0 ;
	for(i = 0 ; i<10000; i=i+1)
	begin
		#1 CLK = ~CLK;
	end
end

initial
begin
	DIN = 0 ;
	for(j = 0 ; j<100; j=j+1)
	begin
		#10 DIN = 0;
		#10 DIN = 1;
		#10 DIN = 1;
		#10 DIN = 1;
		#10 DIN = 0;
		#10 DIN = 0;
		#10 DIN = 1;
		#10 DIN = 0;
		#10 DIN = 1;
		#10 DIN = 0;
	end
end

initial
begin
	RST_N = 1;
	#5 RST_N = 0;
	#5 RST_N = 1;
end

endmodule

 仿真结果:

《用verilog实现边沿检测(上升沿,下降沿,双边)》

    原文作者:summer_awn
    原文地址: https://blog.csdn.net/summer_awn/article/details/107104324
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞