边沿检测原理
边沿检测大致分为:上升沿检测,下降沿检测和,双沿检测。原理都是通过比输入信号快很多的时钟去采集信号,当出现两个连续的采集值不等的时候就是边沿产生处。
图1为边沿采集图,clk为采集时钟,sig为被采集信号,现在需要知道什么时候sig的跳边沿到来,于是有了一个sig_buf的2bit信号用来存储被采集的sig信号,当前值被放在低位,高位时是上一个时刻的值。也就是
sig_buf[1:0] <= {sig_buf[0],sig};
从图中可以看出,sig_buf为2’01的时候正好是上升沿出现之后,2’b10正是下降沿出现之后。所以正好可以利用这两个信号的出现来判断上升沿还是下降沿。这样也就实现了边沿检测。
重点
这种边沿检测方法一定要有clk周期小于sig高电平脉宽的条件,不然无法保证能够每次采集到sig的边沿。
图1. 边沿采集示意图
边沿采集代码讲解
源码下载地址:
edge_catch.v
tb_edge_catch.v
此代码可以修改sig_buf的长度,也就是 不用一个0和一个1判断,而是多个0和多个1,但是宽度变了以后对sig的脉宽要求也就更宽,这点一定要牢记,不然很可能出现检测边沿无法实现。
很多人反映tb写不来,不知道tb要写什么,要怎么写。这里顺便说下怎么写,就以边沿检测tb为例。
仿真目的:产生符合自己要求的激励信号,测试此时的输出是否和预想一致,一致则通过,否则失败。
仿真步骤:根据仿真目的也很容易可以抽象出来仿真的步骤分为2步,第一步,产生激励,第二步,查看被测试模块输出。
激励产生:
周期信号产生always begin #5 clk=0; #5 clk=1; end //时钟信号
只在最开始产生某种特殊波形:initial begin rst = 1 ; #10 rst = 0; end
上述两种信号都是关于时间的函数f(t),这种函数特点决定了可以用延时命令#xx去产生。
需要结合当前状态的信号:这种波形不仅仅时间的函数,还和某个信号相关,比如分频模块,分频值在不停变,那么这个时候不如直接调用一个已经写好的分频模块,分频系数可以外部状态机控制,这样就可以解决。换句话说,tb只是产生理想激励,所以需要你不择手段的去产生自己想要的东西,不管是可综合还是不可综合语句。
tb文件的一般代码结构:
-
module定义
-
reg和wire定义,需要被你主动控制的信号定义为reg,有赋值来源的信号定义为wire,比如模块输入定义为reg,方便自己产生各种波形,输出定义为wire。
-
initial begin end语句,产生初始化激励,比如复位,使能。initial语句可以写多个,效果上两个initial都是同时执行的,仿真的时候你感受不出差别。
-
特殊激励产生,比如时钟,状态机等
-
被测试模块调用
-
被测试模块输出结果合格检测,这一步如果不会可以忽略,自己看波形。对于复杂设计看波形会非常累,所以建议慢慢养成习惯
仿真结果展示
上升沿检测波形,mode=0,当输入信号被检测到上升沿的时候,信号the_edge就会有一个高脉冲:
图2. 上升沿检测
下降沿检测波形,mode=1,当输入信号被检测到下降沿的时候,信号the_edge就会有一个高脉冲:
图3. 下降沿检测
双沿检测波形,mode=2,当输入信号被检测到上升沿或者下降沿的时候,信号the_edge就会有一个高脉冲:
图4. 双沿检测
没有回复内容