题解 | #边沿检测#
边沿检测
https://www.nowcoder.com/practice/fed4247d5ef64ac68c20283ebace11f4
边沿检测
本文所有思路根据FPGA探索者的思路仿真模拟的
本题解题思路只有一拍,相对实际应用而言,可能会有毛刺会让一拍判断失误。所以考虑两排来判断是否为上升沿或者下降沿。
其中,对data_r1记录为时钟上升沿时,data_r1 = a。而将 #clk data_r2 = ->a用来表示将data_r2延迟一个clk进行打拍。
通过手绘波形图分析,在data_r1=1,data_r2 = 0时对应的为上升沿,当data_r1 = 0, data_r2 = 1时为下降沿,因为data_r1和data_r2之间存在一个clk的时延,则记录下的上升信号与下降信号的波形宽度至少为一个clk,可以保证对信号更好的判断,减少判断失误。
最后贴一下代码。(该代码使用其他仿真工具验证的,并不适用该题)
module部分
`timescale 1ns/1ns module edge_detect( input clk, input rst_n, input a, output reg num, output reg rise, output reg down ); reg data_r1,data_r2; always @(posedge clk or negedge rst_n) if(!rst_n) begin data_r1 <= 1'b0; data_r2 <= 1'b0; end else begin #1 data_r1 <= a; data_r2 <= data_r1; end always @(posedge clk or negedge rst_n) if(!rst_n) begin rise <= 1'b0; down <= 1'b0;num <= 1'b0; end else if(data_r1==1'b1 && data_r2==1'b0) begin rise <=1'b1;down <=1'b0;num <= 1'b1; end else if(data_r1==1'b0 && data_r2==1'b1) begin down <=1'b1;rise <=1'b0;num <= 1'b1; end else begin rise <= 1'b0;down <= 1'b0;num <=1'b0; end endmoduletestbech部分
`timescale 1ns/1ns module testbench(); reg a; reg clk,rst_n; wire rise,down,num; initial begin clk = 0; rst_n = 0; end initial begin clk = 1'b0; rst_n = 1'b0; #20 rst_n = 1'b1; end always #10 clk <= !clk; always @(posedge clk or negedge rst_n) if(!rst_n) a <= 1'b0; else #3 a <= {$random}%2; edge_detect dut( .clk(clk), .rst_n(rst_n), .a(a), .num(num), .rise(rise), .down(down) ); endmodule仿真波形