不是很难却困扰过我的一个问题
边沿检测?不是可以直接把待检测的信号写在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
仿真结果: