边沿检测电路设计verilog

时间:2021-01-05 20:09:22

Abstract

边沿检测电路(edge detection circuit)是个常用的基本电路。

Introduction

所谓边沿检测就是对前一个clock状态和目前clock状态的比较,如果是由0变为1,能够检测到上升沿,则称为上升沿检测电路(posedge edge detection circuit),若是由1变为0,能够检测到下降沿,则被称为下降沿检测电路(negedge edge dttection circuit),能够同时检测上升沿与下降沿的电路称为双沿检测电路(double edge detection)。

上升沿检测电路

Method 1:  使用两个reg

边沿检测电路设计verilog

r_data_in0与r_data_in1为DFF,分别hold住上一个与目前clock的i_data_in,当i_data_in由1变为0时,则

r_data_in0    1  1  1  0  0  0

r_data_in1        1  1  1  0  0  0   //对r_data_in0取反相与

o_rising_edge得到一个时钟周期的高电平。

Posedge detection.v / verilog

边沿检测电路设计verilog
 1 module posedge_detection (
2 input clk,
3 input rst_n,
4 input i_data_in,
5 output o_rising_edge
6 );
7
8 reg r_data_in0;
9 reg r_data_in1;
10
11 assign o_rising_edge = ~r_data_in0 & r_data_in1;
12
13 always@(posedge clk, negedge rst_n) begin
14 if (!rst_n) begin
15 r_data_in0 <= 0;
16 r_data_in1 <= 0;
17 end
18 else begin
19 r_data_in0 <= r_data_in1;
20 r_data_in1 <= i_data_in;
21 end
22 end
23
24 endmodule
边沿检测电路设计verilog

这种写法经过综合后RTL为一个两位的DFF与一个AND。

边沿检测电路设计verilog

Methord 2: 使用一个reg

posedge_detection2.v / verilog 

边沿检测电路设计verilog
module posedge_detection2(
input clk,
input rst_n,
input i_data_in,
output reg o_rising_edge
); reg r_data_in0; always@(posedge clk or negedge rst_n) begin
if(!rst_n)
r_data_in0 <= 0;
else begin
r_data_in0 <= i_data_in;
if({r_data_in0,i_data_in} == 2'b01)
o_rising_edge <= 1;
else
o_rising_edge <= 0; end end
endmodule
边沿检测电路设计verilog

这种写法综合成RTL之后只有一个D-FF和一个Equal,右边的o_rising_edge 的D-FF主要是因为always过程块内的reg。

边沿检测电路设计verilog

Vwf仿真图形如下

边沿检测电路设计verilog

下降沿检测与上升沿相似,不在叙述

双沿检测电路(double edge detection)

边沿检测电路设计verilog

r_data_in0与r_data_in1位reg,分别hold住上一个clock和目前的clock得i_data_in,就是i_data_in由1变0,或者由0变1,也就是r_data_in1为1,r_data_in0为0,或者是r_data_in1为0,r_data_in0为1,因此用异或(xor)连接两个寄存器。

Method1 : 使用两个reg

Double_edge_detection.v/ verilog

边沿检测电路设计verilog
 module doubleedge_detection (
input clk,
input rst_n,
input i_data_in,
output o_double_edge
); reg r_data_in0;
reg r_data_in1; assign o_double_edge = r_data_in0 ^ r_data_in1; always@(posedge clk, negedge rst_n) begin
if (!rst_n) begin
r_data_in0 <= 0;
r_data_in1 <= 0;
end
else begin
r_data_in0 <= r_data_in1;
r_data_in1 <= i_data_in;
end
end endmodule
边沿检测电路设计verilog

Method2 :使用一个reg

Double_edge_detection2.v/verilog

边沿检测电路设计verilog
 module doubleedge_detection2 (
input clk,
input rst_n,
input i_data_in,
output reg o_double_edge
); reg r_data_in0; always@(posedge clk, negedge rst_n) begin
if (!rst_n)
r_data_in0 <= 0;
else begin
r_data_in0 <= i_data_in; if ({r_data_in0, i_data_in} == 2'b10)
o_double_edge <= 1;
else if ({r_data_in0, i_data_in} == 2'b01)
o_double_edge <= 1;
else
o_double_edge <= 0; // another method
// o_double_edge <= r_data_in0 ^ i_data_in;
end
end endmodule
边沿检测电路设计verilog

Conclusion

什么时候使用这种电路呢?当input是非同步信号时,为了要让input与同步的FSM一起处理,必须先经过边沿检测,使之与clock同步,然后才能跟FSM一起运作。