题目
有一个缓慢变化的1bit信号a,编写一个程序检测a信号的上升沿给出指示信号rise,当a信号出现下降沿时给出指示信号down。
注:rise,down应为单脉冲信号,在相应边沿出现时的下一个时钟为高,之后恢复到0,一直到再一次出现相应的边沿。
信号 | 类型 | 输入/输出 | 位宽 |
---|---|---|---|
clk | wire | Intput | 1 |
rst_n | wire | Intput | 1 |
a | wire | Intput | 1 |
rise | reg | Output | 1 |
down | reg | Output | 1 |
答案
错误答案
刚开始,用最常用的连续赋值语句来判断上升沿和下降沿,然后对信号打拍后得到rise信号和down信号,如下。
`timescale 1ns/1ns
module edge_detect(
input clk,
input rst_n,
input a,
output reg rise,
output reg down
);
reg r_a;
wire w_rise = 1'b0;
wire w_down = 1'b0;
always @(posedge clk or negedge rst_n)
if(!rst_n)
r_a <= 1'b0;
else
r_a <= a;
assign w_rise = a & (~r_a);
assign w_down = (~a) & r_a;
always @(posedge clk or negedge rst_n)
if(!rst_n) begin
rise <= 1'b0;
down <= 1'b0;
end
else begin
rise <= w_rise;
down <= w_down;
end
endmodule
然后,仿真一直保持,用例不通过,查看波形,原来是当a是不定态X的时候,使用连续赋值语句采集到的上升沿信号w_rise与下降沿信号w_down均为不定态X,如下图。
而采用if-else语句则可以避免该错误,因为在if-else语句中,0、X、Z均按照“假”来处理。
上面两张图分别是使用连续赋值语句和if-else获取上升沿的结果,可以看到,在复位之后,输入的单比特数据a仍然为不定态X,此时使用连续赋值语句assign获取到的上升沿信号rise为不定态X,而使用if-else语句获取到的上升沿信号rise为低电平。
正确答案
`timescale 1ns/1ns
module edge_detect(
input clk,
input rst_n,
input a,
output reg rise,
output reg down
);
reg a_dly;
always @(posedge clk or negedge rst_n)
if(!rst_n)
a_dly <= 1'b0;
else
a_dly <= a;
always @(posedge clk or negedge rst_n)
if(!rst_n) begin
rise <= 1'b0;
down <= 1'b0;
end
else begin
if(a & (~a_dly)) begin
rise <= 1'b1;
down <= 1'b0;
end
else if((~a) & a_dly) begin
rise <= 1'b0;
down <= 1'b1;
end
else begin
rise <= 1'b0;
down <= 1'b0;
end
end
endmodule