题解 | #边沿检测#
边沿检测
http://www.nowcoder.com/practice/fed4247d5ef64ac68c20283ebace11f4
边沿检测
使用一个tmp寄存器存储a上一周期的值(为什么是上一周期),然后当前a与tmp作比较,比较结果会在下一周期中体现出来。我在vivadio中跑的结果如下:
结合图示更加清晰,也可以直接运行下文代码
- a为随机数,仿真产生 1 bit 随机数的代码如下所示:
always @(posedge clk or negedge rst_n)
if(!rst_n) a = 0;
else a <= {$random}%2;
- tmp采集a信号,落后a一个周期;
- rise dowm 信号输入脉冲信号,同样在下一周期显示
下面包含设计代码和仿真代码,可直接在vivadio中运行
module edge_detect(
input clk,
input rst_n,
input a,
output reg rise,
output reg down
);
reg tmp;
always @(posedge clk or negedge rst_n)
if(!rst_n)
tmp <= 0;
else
tmp <= a;
always @(posedge clk or negedge rst_n)
if(!rst_n) begin
rise <= 1'b0;
down <= 1'b0;
end
else if(a && ~tmp) begin
rise <= 1'b1;
down <= 1'b0;
end
else if(~a && tmp) begin
rise <= 1'b0;
down <= 1'b1;
end
else begin
rise <= 1'b0;
down <= 1'b0;
end
endmodule
`timescale 1ns/1ns
module tb_detect();
reg a;
reg clk,rst_n;
wire rise,down;
initial begin
clk = 0;
rst_n = 0;
#20
rst_n = 'b1;
end
always #10 clk = ~clk;
always @(posedge clk or negedge rst_n)
if(!rst_n) a = 0;
else a <= {$random}%2;
edge_detect dut(
.clk(clk),
.rst_n(rst_n),
.a(a),
.rise(rise),
.down(down)
);
endmodule