TA的每日心情 | 开心 2021-12-31 09:03 |
---|
高级会员
- 积分
- 976
|
同步边沿检测的实现
提到边沿检测,很多初学者会第一时间想到直接把待检测信号写在always块里。其实这种方法并不可取,解决这个问题的目标,在于如何在同步电路中实现这样的功能。如果把待检测信号写在always块里,相当于把输入信号接到了触发器的clk上,这样电路就变成异步的了,后面还需要把信号同步,最终得不偿失。
如何实现同步边沿检测呢?正解套路为:定义两个触发器,再通过逻辑组合判断边沿。
演示代码如下:
- module edge_detector(
- clk,
- rst_n,
- din,
- raising_edge_detect,
- falling_edge_detect,
- double_edge_detect
- );
-
- input clk;
- input rst_n;
- input din;
- output raising_edge_detect;
- output falling_edge_detect;
- output 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
复制代码
仿真代码如下:
- `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
复制代码
|
|