FPGA學習筆記二:輸入電路的各種邊沿檢測(內含Verilog代碼)

 

一、邊沿檢測的簡述

我們通常會把邊沿檢測用在按鍵輸入的檢測,這一檢測手段並不唯一(單片機也可以實現)。按鍵按下時,輸入信號key出現一個下降沿,擡起後又變爲一個上升沿。如果輸入信號是不存在毛刺和抖動的理想信號,邊沿檢測就顯得尤爲重要,當然能夠濾除毛刺與抖動的優化的檢測電路也在本篇博客的討論範圍之內。

二、上升沿與雙邊沿的檢測方法

1.上升沿的檢測方法(下降沿方法自行類比)

(1)設計思路

 *******檢測電路其側重電路的設計而非代碼的書寫能力*******
  • 1

我們的設計目標是能夠在一個時鐘週期內(兩個上升沿之間)檢測到輸入信號的上升沿(即由0到1的跳變)。因此要明確:電路中至少要有時序邏輯電路的存在才讓輸入的前後狀態實現比較。設計步驟如下:

  1. 先用一個D觸發器來記錄之前的輸入的狀態(last_state);

  2. 把之前輸入的狀態和當前的狀態(current_state)進行組合邏輯來實現在last_state == 0&& current_state == 1時電路的輸出positive_edge=1;畫出真值表可以發現:這一組合邏輯電路通過:assign positive_edge=~last_state&current_state
    這一條連續賦值語句就可以達到我們的目標(可參考以下真值表);

  3. 到現在爲止,理論上,我們已經可以檢測到一個週期內的邊沿變化;

(2)實現與功能評估

根據上述思路編寫代碼。編寫時注意:上述思路中的last_state就是下述代碼片中的din;current_state對應的就是代碼片中的輸入端口in。代碼如下::

module top_module (
    input clk,
    input [7:0] in,
    output [7:0] positive_edge
);
    reg  [7:0]din;
    always @(posedge clk) begin
       din<= in;
    end
    assign positive_edge=~din&in;
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

波形仿真結果(爲了便於便於直觀體現輸出特性,筆者在粘貼代碼時對輸出端口的命名進行了修改,代碼中的positive_edge端口就是下圖波形仿真圖中的pedge):
initial waveform
由上圖仿真波形可以看出,此時的邊沿檢測,代碼部分輸出通過連續賦值語句實現,因此輸出會被兩個輸入信號驅動,分別爲聲明的reg寄存器型變量din和輸入信號in。也就是說輸出信號pedge不會等待時鐘的到來,而是會在檢測到一個第一個上升沿後立刻發生響應。 事實上這種響應方式是不嚴謹的。
原因是: 聯繫波形仿真圖還有RTL仿真圖,如果這一段代碼應用於純電路設計,那似乎是可以滿足要求,但試想我們使用邊沿檢測的場合通常是按鍵檢測,現實生活中的按鍵其簧片在按下後會伴隨着一段時間的抖動,因此這種使用連續賦值語句的組合邏輯輸出自然會讓檢測結果帶上毛刺。或者我們可以這樣理解:雖然我們對於輸入信號做了延時處理(通過一個D觸發器來實現),但是在最終的2輸入與門的其中一個輸入端是輸入信號in,in在一個非常小的時間段內的任意電平變化都會在assign語句所表徵的組合邏輯電路的輸出即刻體現,讓之前的D觸發器延遲效果徹底失效。因此我們需要讓最終的positive_edge輸出能夠穩定地檢測到一段在很短時間內(通常是小於半個時鐘週期)存在毛刺或者抖動的邊沿信號。

(3)改進與代碼實現

  • 改進的思路:在組合邏輯電路的後端再加上一個時序邏輯電路模塊,在此處依舊是通過簡單的D觸發器來實現。這樣問題就被簡單化了:只要在兩個時鐘中間出現了上升沿(無論中間發生了多少次抖動),上升沿檢測輸出端口positive_edge都會在第二個時鐘同步地發出檢測信號,並且經過一個時鐘後回零。改進後的代碼如下:
module top_module(
	input clk,
	input [7:0] in,
	output reg [7:0] positive_edge);	
	reg [7:0] din;				
	always @(posedge clk) begin
		din <= in;			
		positive_edge <= in & ~din;	
	end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 波形仿真結果(爲了便於便於直觀體現輸出特性,筆者依舊是對輸出端口的命名進行了修改,代碼中的positive_edge端口就是下圖波形仿真圖中的pedge):
    在這裏插入圖片描述

2.雙邊沿的檢測方法

(1)設計思路

有了單邊沿檢測的思路作爲借鑑,雙邊沿的檢測其設計思路基本相同。比較它與前者的功能與波形區別:雙邊沿需要在上升沿和下降沿時都讓輸出爲1,因此只需要改變其組合電路部分的真值表(真值表如下)即可,時序電路部分不需要做出改變。

last_state (din) current_state(in) positive_edge
0 0 0
0 1 1
1 0 1
1 1 0

根據真值表可寫出其邏輯表達式:assign anyedge= last_state^current_state; 同樣,爲了讓電路能夠容忍毛刺的存在,在組合電路輸出再加上一個D觸發器實現一個時鐘的延遲。

(2)代碼實現

module top_module (
    input clk,
    input [7:0] in,
    output [7:0] anyedge
);
    reg [7:0]din;
    always @(posedge clk) begin
    	din<=in;
        anyedge<=din^in;
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

波形仿真見下圖:
在這裏插入圖片描述
如上圖所示,在in[1]的第一個上升沿到來時,anyedge[1]在隨後的第二個時鐘上升沿置一併在第三個時鐘上升沿變爲零(說明檢測到了最低位的一個邊沿變化)。隨後的一個in[1]的一對雙沿變化(先是下降沿然後是上升沿),隨後anyedge[1]檢測信號持續了兩個時鐘,說明兩個邊沿變化都被檢測到了。
在這裏插入圖片描述

三、邊沿捕捉電路

首先說明一點:這一部分的電路基於筆者在HDLBits上碰到的一道題目,解決是碰到了一些困惑,因此一併歸入了邊沿檢測電路的部分進行整理、總結和分享。先上題目傳送門:HDLBits:邊沿捕捉電路。按照題目的所提出的要求, 邊沿捕捉與邊沿檢測的區別在於,邊沿捕捉是在檢測到輸入信號的邊沿變化之後輸出變爲高電平,而“捕捉”的特點就是這個高電平會一直保持直到復位信號reset被置一有效!!!

  • 此題要求檢測輸入信號中的下降沿,同時根據捕捉的定義,檢測到的輸出結果out會一直保持直到reset清零復位。

1.設計思路

我們可以把對於題目要求分割爲兩個部分來實現:一是能夠檢測到下降沿;二是下降沿需要一直保持直到reset有效將其復位。 那麼解題就簡單化了:
(1) 第一個部分是對本博客之前討論過的上升沿檢測的變形,只要修改其中的組合邏輯電路部分就可以實現: assign capture=~in&temp;//capture用來儲存捕捉結果.
(2) 第二個部分即需要在後邊一個觸發器(這裏說的比較籠統,讀者可參考前文的設計思路應該能體會到後邊的觸發器是哪個)加上時序電路的復位信號,同時還需要對組合電路部分進行改進,讓輸出信號out在置高後一直保持輸出☞: assign out=out|capture;//將捕捉結果保持.

-根據設計思路可以在大腦中大致綜合出如下電路圖(爲了方便理解,暫時將代碼改成了三位輸入和輸出,但各個位上的邊沿捕捉原理相同):
在這裏插入圖片描述

2.代碼實現

module top_module (clk,reset,in,out);
    input clk;
    input reset;
    input [31:0] in;
    output [31:0] out;
    reg [31:0] temp;
    wire [31:0] capture;

    assign capture = ~in & temp;//檢測到上升沿之後,來確定我們的輸出
    always @ (posedge clk)
        begin
            temp <= in;
            if(reset)
                out <= 32'b0;
            else
                out<=out|capture;
        end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

最終計算機給出的綜合波形圖如下:
在這裏插入圖片描述

四、總結

本文主要介紹了邊沿檢測與邊沿捕捉的原理與設計思路。實際上,後者可以基於前者的設計思路進行完善和設計。無論是邊沿檢測還是捕捉,都需要通過寄存器來抓住其last_state和current_state(即前後態)的變化,通過畫出真值表找出對應的組合邏輯,並且爲了排除毛刺和抖動的影響通過延遲輸出來提高響應與檢測精度。其它的邊沿檢測問題基本都可以基於這一思路根據所需功能進行改進,但改進的核心部分還是着重於組合電路模塊。

五、其它補充

本次博客主要是本人在HDLBits中碰到的幾個問題和自己完成題目後的個人理解及對波形的分析。如有錯誤歡迎讀者在評論區或者私信留言指正,之後如果再碰到類似於邊沿檢測或捕捉的其它問題都會及時地更新。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章