(1)边沿检测
-
描述:有一个缓慢变化的1bit信号a,编写一个程序检测a信号的上升沿给出指示信号rise,当a信号出现下降沿时给出指示信号down。
注:rise,down应为单脉冲信号,在相应边沿出现时的下一个时钟为高,之后恢复到0,一直到再一次出现相应的边沿。 -
思路:检测一个输入信号的边沿,我们必须根据此信号的前一时刻值和后一时刻值来判断。假如此信号前一时刻为0,后一时刻为1,那么肯定出现了上升沿;若信号前一时刻为1,后一时刻为0,那么肯定出现了下降沿。因此,我们需要将输入信号a打一拍进行寄存,与当前a结合来判断边沿情况。
上升沿、下降沿和双边沿
- 边沿检测分为上升沿、下降沿和双边沿三种。这三种的思路都是一样的,掌握其中一种即可写出其他两种。
信号描述 - (1)clk:系统时钟信号;rst_n:系统复位信号;
- (2)a:输入信号;a_tmp1:将a打了一拍的信号;a_tmp2:将a打了两拍的信号;
- (3)rise:上升沿指示信号;down:下降沿指示信号;
上升沿
- 当a前一时刻为0(
a_tmp1==0
),当前时刻为1(a==1
)时为上升沿。但要注意边沿指示信号须在边沿出现的下一个时钟为高,且只持续一个时钟周期,所以,如果采用a和a_tmp来判断的话需要在时序逻辑中进行判断。这里可以注意到,a_tmp2信号是a打了两拍的结果,如果使用a_tmp1和a_tmp2来判断的话就可以在组合逻辑中进行判断。
下降沿
- 当a前一时刻为1(
a_tmp1==1
),当前时刻为0(a==0
)时为下降沿。
双边沿
- 双边沿实际上就是上升沿指示信号rise与下降沿指示信号相或的结果,或者可以认为是
a^a_tmp
。
代码实现
(1)时序逻辑判断边沿
module edge_detect(
input clk,
input rst_n,
input a,
output reg rise,
output reg down
);
reg a_tmp1; // 将a打一拍
always@(posedge clk, negedge rst_n)begin
if(~rst_n)begin
a_tmp1 <= 0;
end
else begin
a_tmp1 <= a;
end
end
always@(posedge clk, negedge rst_n)begin
if(~rst_n)begin
rise <= 0;
down <= 0;
end
else begin
case({a_tmp1, a})
2'b01: {rise, down} <= 2'b10;
2'b10: {rise, down} <= 2'b01;
default: {rise, down} <= 2'b00;
endcase
end
end
endmodule
(2)组合逻辑判断边沿
module edge_detect(
input clk,
input rst_n,
input a,
output reg rise,
output reg down
);
reg a_tmp1;
reg a_tmp2; // 将a打两拍
always@(posedge clk, negedge rst_n)begin
if(~rst_n)begin
a_tmp1 <= 0;
a_tmp2 <= 0;
end
else begin
a_tmp1 <= a;
a_tmp2 <= a_tmp1;
end
end
always@(*)begin
case({a_tmp2, a_tmp1})
2'b01: {rise, down} = 2'b10;
2'b10: {rise, down} = 2'b01;
default: {rise, down} = 2'b00;
endcase
end
endmodule