HDLBITS笔记26:边沿检测(正边沿、任意边沿,边沿捕获寄存器、双边沿触发触发器)

在做接下来的题目前,首先需要理解什么是边沿检测。
**边沿检测:**边沿指的是上升沿或者下降沿,检测指的是检测输入信号的变化,或者FPGA内部电路逻辑信号的跳变。在做边沿检测时,应该注意到复位信号,如果复位信号有效的话,边沿检测是检测不到信号的跳变是上升沿跳变还是下降沿跳变的。

  • 上升沿:当前一时刻t0为低电平、t1时刻为高电平时,此时为上升沿。
  • 下降沿:当前一时刻t0为高电平、t1时刻为低电平时,此时为下降沿。
    注意:
    在使用Verilog对信号的边沿进行检测时,应当设置一个中间变量作为暂存器,通过中间变量与下一时刻的变量进行对比,判断时上升沿还是下降沿。

题目1:edge detect(检测正边沿)

对于 8 位矢量中的每个位,检测输入信号何时从一个时钟周期中的 0 变为下一个时钟周期中的 1(类似于正边沿检测)。输出位应设置为0到1转换发生后的周期。

下面是一些示例。为清楚起见,in[1]和pedge[1]分别显示。
在这里插入图片描述
模块声明
module top_module (
input clk,
input [7:0] in,
output [7:0] pedge
);

**分析:**该题目要求检测的是正边沿,即上升沿检测。通过定义中间变量temp,与下一时刻的信号作逻辑与,即可完成上升沿检测。
由于题目所给的输入信号并没有包括置位信号,因此在这题的代码编写如下:

module top_module (
    input clk,
    input [7:0] in,
    output [7:0] pedge
);
    reg [7:0]temp;
    always @(posedge clk)
        begin
            temp <= in;//记住前一时刻的时钟状态
            pedge <= ~temp&in;
        end
 endmodule

仿真结果:
在这里插入图片描述

题目2:edge detect(检测任意边沿)

对于 8 位矢量中的每个位,检测输入信号何时从一个时钟周期更改为下一个时钟周期(检测任何边沿)。输出位应设置为0到1转换发生后的周期。

下面是一些示例。为清楚起见,in[1] 和 anyedge[1] 分别显示
在这里插入图片描述
模块声明
module top_module (
input clk,
input [7:0] in,
output [7:0] anyedge
);
**分析:题目2要求检测任意边沿。
**
检测正边沿为前一时刻的信号取反与后一时刻的信号进行逻辑与,保证输出为1,即为上升沿检测;检测下降沿为前一时刻的信号与取反后的后一时刻的信号进行逻辑与,保证输出信号为,即为下降沿检测。

由此可得代码编写如下:

module top_module (
    input clk,
    input [7:0] in,
    output [7:0] anyedge
);
    reg [7:0]temp;
    always @(posedge clk)
      begin
          temp <= in;
          anyedge <= (~temp&in) | (temp&~in);
      end
endmodule

仿真输出结果如下:

在这里插入图片描述

题目3:edge capture(边沿捕获寄存器)

对于 32 位矢量中的每个位,当输入信号从一个时钟周期中的 1 变为下一个时钟周期中的 0 时,请进行捕获。“捕获”意味着输出将保持1,直到寄存器复位(同步复位)。

每个输出位的行为类似于 SR 触发器:在发生 1 到 0 转换后的周期内,应将输出位设置为(设置为 1)。当复位为高电平时,输出位应在正时钟沿处复位(至0)。如果上述两个事件同时发生,则重置具有优先权。在下面示例波形的最后 4 个周期中,“复位”事件比“设置”事件早一个周期发生,因此此处没有冲突。

在下面的示例波形中,为清楚起见,复位、输入[1]和输出[1]再次单独显示

在这里插入图片描述
模块声明
module top_module (
input clk,
input reset,
input [31:0] in,
output [31:0] out
);

通过阅读题意可知:

  • 当输入信号从一个时钟周期中的 1 变为下一个时钟周期中的 0 时,请进行捕获:即下降沿检测。
  • 捕获”意味着输出将保持1,直到寄存器复位(同步复位):使用同步复位。且复位信号高电平有效,同时如果寄存器不复位,则输出一直保持在1。
  • 如果上述两个事件同时发生,则重置具有优先权:重置为0的优先等级最高。

由此可得代码编写如下:

module top_module (
    input clk,
    input reset,
    input [31:0] in,
    output [31:0] out
);
    reg [31:0] temp;
    always @(posedge clk)
        begin
            temp <= in;
            if(reset)
                out <= 32'b0;
            else
                out <= temp & ~in | out;
        end
endmodule

题目4:双边触发触发器

您熟悉在时钟正边或时钟负边触发的触发器。双边沿触发触发触发器在时钟的两个边沿触发。但是,FPGA没有双边触发触发器,并且始终@(posedge clk或negedge clk)不被接受为法律敏感性列表。

构建一个功能性类似于双边触发触发器的电路:
在这里插入图片描述
注意:它不一定完全等效:触发器的输出没有毛刺,但模拟这种行为的更大的组合电路可能会。但我们在这里忽略这个细节。

模块声明
module top_module (
input clk,
input d,
output q
);

题目提示:
您 不能 在 FPGA 上 创建 双 边 触发 器。但是,您可以创建正边触发触发和负边触发触发器。
这个问题是一个中等难度的电路设计问题,但只需要基本的Verilog语言功能。(这是电路设计问题,不是编码问题。在尝试编写电路代码之前,首先手工绘制电路草图可能会有所帮助。

分析:题目要求创建的触发器类似与双边沿触发器。但是由于FPGA中没有双边沿触发器,没有办法使用always @(posedge clk or negedge clk)语句进行创建。由此可以联想到并行处理,即使用两个always语句块分别创建上升沿触发和下降沿触发即可。

代码编写如下:

module top_module (
    input clk,
    input d,
    output q
);
    reg temp1,temp2;
    always @(posedge clk)//创建上升沿
        begin
            temp1 <=  d ;
        end
    always @(negedge clk)//创建下降沿
        begin
            temp2 <= d;
        end
   assign q = clk?temp1:temp2; 
endmodule

仿真结果如下:
在这里插入图片描述

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值