使用Verilog如何设计一个上升沿检测器?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Verilog如何设计一个上升沿检测器?相关的知识,希望对你有一定的参考价值。

设计一个模块:当输入信号端(位宽1位)出现上升沿跳变时,执行相应操作?请问该如何实现检测该上升沿检测?

疑问1:可以使用posedge+端口名称来实现上升沿检测吗?我看了好多程序中posedge后面都跟的是时钟?

Posedge用来作为时钟使用的。相当于触发器的时钟输入端。

要检测信号上升沿的话,可以采用以下方法:
always@(posedge clk or negedge rst)
if(!rst)
begin sign_1b <= 1'b0; sign_2b <= 1'b0; end
else
begin sign_1b <= sign; sign_2b <= sign_1b; end

always@(posedge clk or negedge rst)
if(!rst)
sign_pos <= 1'b0;
else if (sign_2b && !sign_1b)
sign_pos <= 1'b1;
else
sign_pos <= 1'b0;
参考技术A Posedge用来作为时钟使用的。相当于触发器的时钟输入端。

要检测信号上升沿的话,可以采用以下方法:
always@(posedge clk or negedge rst)
if(!rst)
begin sign_1b <= 1'b0; sign_2b <= 1'b0; end
else
begin sign_1b <= sign; sign_2b <= sign_1b; end

always@(posedge clk or negedge rst)
if(!rst)
sign_pos <= 1'b0;
else if (sign_2b && !sign_1b)
sign_pos <= 1'b1;
else
sign_pos <= 1'b0;
参考技术B 答:
  如果你是有clk的同步时序电路,那么不允许使用posedge + 端口名称的方式来生成边沿检测
电路。

  所谓边沿检测就是对前一个clock状态和目前clock状态的比较,如果是由0变为1,能够检测
到上升沿,则称为上升沿检测电路(posedge edge detection circuit),若是由1变为0,能够
检测到下降沿,则被称为下降沿检测电路(negedge edge dttection circuit),能够同时检测
上升沿与下降沿的电路称为双沿检测电路(double edge detection)。

照这个原理,下面的代码是一个上升沿检测电路,巧妙运用了非阻塞赋值自动产生寄存器的
特性。下降沿检测电路只需把 pedge <= in & ~d_last; 改为 pedge <= ~in & d_last;
即可。双沿检测电路只需把 pedge <= in & ~d_last; 改为 pedge <= in ^ d_last;
(异或)即可。

module top_module(
       input clk,
       input [7:0] in,
       output reg [7:0] pedge);
      
       reg [7:0] d_last;     
                    
       always @(posedge clk) begin
         d_last <= in; // 保存上一个状态
         pedge <= in & ~d_last; //in的数据变化后有上升沿时,pedge变1
       end
      
endmodule

边沿检测电路设计verilog

Abstract

边沿检测电路(edge detection circuit)是个常用的基本电路。

Introduction

所谓边沿检测就是对前一个clock状态和目前clock状态的比较,如果是由0变为1,能够检测到上升沿,则称为上升沿检测电路(posedge edge detection circuit),若是由1变为0,能够检测到下降沿,则被称为下降沿检测电路(negedge edge dttection circuit),能够同时检测上升沿与下降沿的电路称为双沿检测电路(double edge detection)。

上升沿检测电路

Method 1:  使用两个reg

 

r_data_in0与r_data_in1为DFF,分别hold住上一个与目前clock的i_data_in,当i_data_in由1变为0时,则

r_data_in0    1  1  1  0  0  0

r_data_in1        1  1  1  0  0  0   //对r_data_in0取反相与

o_rising_edge得到一个时钟周期的高电平。

Posedge detection.v / verilog 

复制代码
 1 module posedge_detection (
 2    input  clk,
 3    input  rst_n,
 4   input  i_data_in,
 5    output o_rising_edge
 6 );
 7  
 8  reg r_data_in0;
 9  reg r_data_in1;
10 
11  assign o_rising_edge = ~r_data_in0 & r_data_in1;
12  
13  always@(posedge clk, negedge rst_n) begin
14   if (!rst_n) begin
15      r_data_in0 <= 0;
16      r_data_in1 <= 0;
17    end
18    else begin
19     r_data_in0 <= r_data_in1;
20      r_data_in1 <= i_data_in;
21    end
22  end
23  
24  endmodule
复制代码

这种写法经过综合后RTL为一个两位的DFF与一个AND。

Methord 2: 使用一个reg

posedge_detection2.v / verilog 

复制代码
module posedge_detection2(
    input clk,
    input rst_n,
    input i_data_in,
    output reg o_rising_edge       
);

reg r_data_in0;

always@(posedge clk or negedge rst_n) begin
  if(!rst_n)
  r_data_in0 <= 0;
  else begin
   r_data_in0 <= i_data_in;
   if({r_data_in0,i_data_in} == 2\'b01)
   o_rising_edge <= 1;
   else 
   o_rising_edge <= 0;  
        
 end

end
endmodule 
复制代码

这种写法综合成RTL之后只有一个D-FF和一个Equal,右边的o_rising_edge 的D-FF主要是因为always过程块内的reg。

Vwf仿真图形如下

 

下降沿检测与上升沿相似,不在叙述

双沿检测电路(double edge detection)

r_data_in0与r_data_in1位reg,分别hold住上一个clock和目前的clock得i_data_in,就是i_data_in由1变0,或者由0变1,也就是r_data_in1为1,r_data_in0为0,或者是r_data_in1为0,r_data_in0为1,因此用异或(xor)连接两个寄存器。

Method1 : 使用两个reg

Double_edge_detection.v/ verilog

复制代码
 module doubleedge_detection (
   input  clk,
   input  rst_n,
   input  i_data_in,
   output o_double_edge
 );
 
 reg r_data_in0;
 reg r_data_in1;
 
 assign o_double_edge = r_data_in0 ^ r_data_in1;
 
 always@(posedge clk, negedge rst_n) begin
   if (!rst_n) begin
     r_data_in0 <= 0;
     r_data_in1 <= 0;
   end
  else begin
    r_data_in0 <= r_data_in1;
    r_data_in1 <= i_data_in;
   end
 end

endmodule
复制代码

Method2 :使用一个reg

Double_edge_detection2.v/verilog

复制代码
 module doubleedge_detection2 (
   input      clk,
   input      rst_n,
   input      i_data_in,
   output reg o_double_edge
 );

 reg r_data_in0;

 always@(posedge clk, negedge rst_n) begin
   if (!rst_n)
     r_data_in0 <= 0;
  else begin
    r_data_in0    <= i_data_in;
    
     if ({r_data_in0, i_data_in} == 2\'b10)
      o_double_edge <= 1;
    else if ({r_data_in0, i_data_in} == 2\'b01)
      o_double_edge <= 1;
    else
       o_double_edge <= 0;
       
     // another method
     // o_double_edge <= r_data_in0 ^ i_data_in;
  end
 end
 
 endmodule
复制代码

Conclusion

什么时候使用这种电路呢?当input是非同步信号时,为了要让input与同步的FSM一起处理,必须先经过边沿检测,使之与clock同步,然后才能跟FSM一起运作。 

以上是关于使用Verilog如何设计一个上升沿检测器?的主要内容,如果未能解决你的问题,请参考以下文章

边沿检测电路设计verilog

边沿检测电路设计verilog

verilog 中的上升沿 下升沿 延时怎样规定

Verilog实现上升下降沿检测 FPGA

Verilog实现上升下降沿检测 FPGA

verilog里可不可以同时对上升沿和下降沿计数