边沿检测Verilog实现(包含上升沿,下降沿,双边沿)

思路:设计两个或多个一位的寄存器,用来接收被检测的信号,系统时钟来一次记一次输入信号,如果用了两个寄存器直接异或就可以了;使用高频的时钟对信号进行采样,因此要实现上升沿检测,时钟频率至少要在信号最高频率的2倍以上,否则就可能出现漏检测。具体请参见下面代码:

module edge_detect(clk,rst,signal,pos_edge,neg_edge,both_edge);
 input clk;
 input rst;
 input signal;
 output pos_edge;
 output neg_edge;
 output both_edge;
 
 reg sig_r0,sig_r1;//状态寄存器
 always @(posedge clk)
  begin
      if(rst)
	    begin
		   sig_r0 <= 1'b0;
		   sig_r1 <= 1'b0;
		end
	  else
	    begin
		   sig_r0 <= signal;
		   sig_r1 <= sig_r0;
		end
  end
 
 assign pos_edge = ~sig_r1 & sig_r0;
 assign neg_edge = sig_r1 & ~sig_r0;
 assign both_edge = sig_r0 ^ sig_r1;
endmodule

RTL仿真结果:

边沿检测Verilog实现(包含上升沿,下降沿,双边沿)_第1张图片

从RTL视图中可以看出,电路是通过一个同复位的D触发器实现的; 

 或者上面的Verilog代码还可以换一种写法,效率上差不了太多;

module edge_detect(clk, rst_n, signal, pos_edge, neg_edge, both_edge);

input clk;
input rst_n;
input signal;
output pos_edge;
output neg_edge;
output both_edge;

reg [1:0]sig_fifo;
reg sig_r0, sig_r1;  // 状态寄存器
always @ (posedge clk or negedge rst_n)
    if (!rst_n) begin 
        sig_fifo <= 2'b0;
    end else begin 
        sig_fifo <= {sig_fifo[0], signal};
    end 

assign pos_edge = (sig_fifo == 2'b01);
assign neg_edge = (sig_fifo == 2'b10);  
assign both_edge = sig_fifo[0] ^ sig_fifo[1];  // 双边沿检测,或pos_edge|neg_edge

endmodule 

 

你可能感兴趣的:(verilog基础)