边沿检测
代码
module edge_detection(input sys_clk,input sys_rst_n,input signal_in,output edge_rise,output edge_down
);//存储上一个时钟周期的输入信号reg signal_in_prev;always @(posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)signal_in_prev <= 0;else beginsignal_in_prev <= signal_in; //两个信号相差一个时钟周期endend//上升沿检测:signal_in_prev为0,signal_in为1assign edge_rise = signal_in & ~signal_in_prev;assign edge_down = ~signal_in & signal_in_prev;
endmodule
若为下降沿检测,则为:
assign edge_detected = ~signal_in & signal_in_prev;
TB文件
`timescale 1ns/1psmodule tb_top();//接口声明
reg sys_clk;
reg sys_rst_n;
reg signal_in;wire edge_rise;
wire edge_down;//对被测的设计进行例化edge_detection u_edge_detection(.sys_clk (sys_clk),.sys_rst_n (sys_rst_n),.signal_in (signal_in),.edge_rise (edge_rise),.edge_down (edge_down)
);//产生时钟
initial sys_clk = 1;
always #10 sys_clk = ~sys_clk;//测试激励产生
initial beginsys_rst_n = 0;signal_in = 0;#117;sys_rst_n = 1;signal_in = 1;#217;signal_in = 0;#317;signal_in = 1;#517;signal_in = 0;#317;signal_in = 1;#737;signal_in = 1;#519;signal_in = 0;#817;signal_in = 1;#417;signal_in = 0;#107;signal_in = 1;#300;
endendmodule
注意,若TB文件中输入信号signal_in的上升\下降沿和sys_clk同步,则检测不出边沿。所以我将输入信号的持续时间都设定为随机数字,来和sys_clk产生区别
仿真波形
改进
若出现不定值x或高阻值z,则检测不准确。
可以改进为:
assign edge_detected = ((a & ~signal_in_prev)===1)?1:0;//上升沿检测assign edge_detected = ((~a & signal_in_prev)===1)?1:0;//下降沿检测
解释:
==
和!==
称为逻辑等式运算符,其结果由两个操作数的值决定。真值表如下:
== | 0 | 1 | x | z |
---|---|---|---|---|
0 | 1 | 0 | x | x |
1 | 0 | 1 | x | x |
x | x | x | x | x |
z | x | x | x | x |
===
和!===
常用于case表达式的判别,所以又称为case等式运算符。它是对操作数进行按位比较,两个操作数必须完全一致,结果才为1。若两个操作数对应位都出现不定值x或高阻值z,则也可认为是相同的。真值表如下:
=== | 0 | 1 | x | z |
---|---|---|---|---|
0 | 1 | 0 | 0 | 0 |
1 | 0 | 1 | 0 | 0 |
x | 0 | 0 | 1 | 0 |
z | 0 | 0 | 0 | 1 |
参考
(201条消息) Verilog 相等运算符之相等和全等_verilog 全等_蒋楼丶的博客-CSDN博客