边沿检测电路是 Verilog 数字电路设计中较为常用的电路,主要作用是在 clk 的驱使下,检测另一个信号的上升/下降沿电路;
检测的原理是记录指定信号前一个时钟和当前时钟的信号,并做对比,看看是否存在 1->0 或者是 0->1 的变化;
所以,实现的时候,需要两个触发器,一个用于记录当前 clk 时钟来临的时候,指定信号的数据,另一个记录上个时钟周期指定信号的数据;
代码如下:
module edge_detect(
input clk,
input n_rst,
input data_in,
output pos_edge,
output neg_edge,
output both_edge
);
reg data_in_0;
reg data_in_1;
always @ (posedge clk or negedge n_rst)
if (!n_rst) begin
data_in_0 <= 1'b0;
data_in_1 <= 1'b0;
end
else begin
data_in_0 <= data_in;
data_in_1 <= data_in_0;
end
assign pos_edge = data_in_0 & (~data_in_1);
assign neg_edge = data_in_1 & (~data_in_0);
assign both_edge = data_in_0 ^ ( data_in_1);
endmodule
每个时钟周期,首先将上一次的触发器数据打入 将数据打入 data_in_1 触发器,同时将当前输入的 data_in 打入 data_in_0;
时刻对比 data_in_0 和 data_in_1 ;查看位的变化:
1、如果从 0->1 说明是上升沿,那么 data_in_1 此刻是 0,data_in_0 此刻是 1,得出来 pos_edge 为 1,并且维持一个时钟周期
2、如果从 1->0 说明是下降沿,那么 data_in_1 此刻是 1,data_in_0 此刻是 0,得出来 neg_edge 为 1,并且维持一个时钟周期
3、上升沿,下降沿同时检测,也是一样的。不再多说,还是维持一个时钟周期;
仿真文件 testbench 为:
module tb;
// Inputs
reg clk;
reg n_rst;
reg data_in;
// Outputs
wire pos_edge;
wire neg_edge;
wire both_edge;
// Instantiate the Unit Under Test (UUT)
edge_detect uut (
.clk(clk),
.n_rst(n_rst),
.data_in(data_in),
.pos_edge(pos_edge),
.neg_edge(neg_edge),
.both_edge(both_edge)
);
always #20 clk = ~clk;
initial begin
// Initialize Inputs
clk = 0;
n_rst = 0;
data_in = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
n_rst = 1;
#60;
data_in = 1'b1;
#60;
data_in = 1'b0;
#60;
data_in = 1'b1;
#60;
data_in = 1'b0;
#60;
data_in = 1'b1;
#60;
data_in = 1'b0;
#60;
data_in = 1'b1;
#60;
data_in = 1'b0;
#60;
data_in = 1'b1;
#60;
data_in = 1'b0;
#60;
data_in = 1'b1;
#60;
data_in = 1'b0;
end
endmodule
仿真波形: