lcytms 发表于 2016-11-7 11:53:06

FPGA初级课程第七讲 边沿检测

FPGA初级课程
第七讲 边沿检测

Hi,大家好!我是至芯科技的李老师。
今天讲课的题目是:边沿检测。
本节课我先简要地介绍一下边沿检测的物理原理,然后进行边沿检测的架构设计,再实际演示一下边沿检测的建模与仿真,通过仿真查看边沿检测的效果。

lcytms 发表于 2016-11-7 11:55:33

我们打开《21至芯科技奋斗的小孩之altera 系列 第二十一篇 边沿检测.pdf》文件。


对于每一个的小实验,我们都可以把它看作是一个小项目,逐步的去分析,设计,调试,最后完成功能。下面我们就开始我们的“小项目”。

项目名称:边沿检测
具体要求:检测输入信号,或者FPGA内部逻辑信号的跳变,即上升沿或者下降沿的检测,当检测到边沿后,发出高脉冲。

通过分析上述的“项目名称”和“具体要求”,我们可以设计出如下的电路:

lcytms 发表于 2016-11-7 11:56:11

由于寄存器可以使信号延时一个时钟周期,我们可以利用这点,来完成信号的边沿检测。

我们先分析下降沿检测信号neg_flag。
假设初始状态时signal一直为高电平,则buffer1和buffer2的输出都是高电平,我们将buffer1的输出值取反(低电平)和buffer2的输出(高电平)相与得到低电平;
当signal变成低电平时,buffer1的输出先变成低电平,我们将buffer1的输出值取反(高电平)和buffer2的输出(高电平)相与得到neg_flag(高电平);
下一个周期时,buffer2的输出也变成了低电平,buffer1的输出值取反(高电平)和buffer2的输出(低电平)相与得到低电平。
故而neg_flag只是输出了一个时钟周期的高脉冲。

上升沿检测信号pos_flag可以同理分析。
假设初始状态时signal一直为低电平,则buffer1和buffer2的输出都是低电平,我们将buffer1的输出(低电平)和buffer2的输出值取反(高电平)相与得到低电平;
当signal变成高电平时,buffer1的输出先变成高电平,我们将buffer1的输出(高电平)和buffer2的输出值取反(高电平)相与得到pos_flag(高电平);
下一个周期时,buffer2的输出也变成了高电平,buffer1的输出(高电平)和buffer2的输出值取反(低电平)相与得到低电平。
故而pos_flag只是输出了一个时钟周期的高脉冲。

lcytms 发表于 2016-11-7 11:58:58

架构图如下图所示。

其中,
        signal:被检测信号
        pos_flag:检测出上升沿后发出的高脉冲
        neg_flag:检测出下降沿后发出的高脉冲

lcytms 发表于 2016-11-7 16:26:59

本帖最后由 lcytms 于 2016-11-7 16:31 编辑

系统设计:
1. 工程的名称:ckeck_edge。

建立新工程文件夹ckeck_edge。
新建ckeck_edge.v文件,进行建模。
设计代码如下:
module check_edge (clk, rst_n, signal, neg_flag, pos_flag);

        input clk, rst_n;
        input signal;
       
        output neg_flag, pos_flag;
       
        reg buffer1, buffer2;
       
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        buffer1 <= signal;
                                        buffer2 <= signal;
                                end
                        else
                                begin
                                        buffer1 <= signal;
                                        buffer2 <= buffer1;
                                end
                end

        assign neg_flag = buffer2 && ~buffer1;
        assign pos_flag = ~buffer2 && buffer1;

endmodule

lcytms 发表于 2016-11-7 16:27:34

解析:
在模块复位时,笔者将buffer1和buffer2的输出设置成和输入信号相同的电平值,原因如下:
如果设置成高电平,而输入信号在复位器件为低电平,那么在复位结束后就会产生一个我们不想要的neg_flag(分析方法同设计方法)。
另一种情况读者可以自己分析,方法是相同的。

lcytms 发表于 2016-11-7 16:32:11

本帖最后由 lcytms 于 2016-11-7 16:37 编辑

编写Testbench。

新建模块ckeck_edge_tb.v文件。
`timescale 1ns/1ps

module check_edge_tb;

        reg clk, rst_n;
        reg signal;
       
        wire neg_flag, pos_flag;
       
        check_edge dut (
                        .clk(clk),
                        .rst_n(rst_n),
                        .signal(signal),
                        .neg_flag(neg_flag),
                        .pos_flag(pos_flag)
                );
               
        initial
                begin
                        clk = 1;
                        rst_n = 0;
                        signal = 1;
                        #200.1
                        rst_n = 1;
                       
                        #200
                        signal = 0;
                        #200
                        signal = 1;
                        #200
                       
                        $stop;
                end
               
        always #10 clk = ~clk;

endmodule

lcytms 发表于 2016-11-7 16:51:00

设置好仿真。
检查仿真波形。
当输入信号有下降沿时,neg_flag输出了高脉冲,输入信号有上升沿时,pos_flag输出了高脉冲。
检测边沿是用寄存器来完成的,所以脉冲的输出会晚一个时钟输出,在高频率时钟对低频率信号检测中,没有影响。
经检查认为设计正确。

lcytms 发表于 2016-11-7 16:52:12

好了,今天的课程就讲到这里。
通过今天的课程,我们学习了边沿检测的基本原理,并对边沿检测电路进行了建模和仿真检查。
希望大家建立对边沿检测的理解,并熟练运用Verilog语言编写驱动逻辑。
更复杂的知识和技巧我们将逐步通过后面的课程展现给大家。

课程到此结束,谢谢大家的关注!

zxopen08 发表于 2016-11-9 15:23:54

FPGA初级课程第七讲 边沿检测
页: [1] 2
查看完整版本: FPGA初级课程第七讲 边沿检测