HDLBits (98) — 雙邊觸發(fā)器
本題鏈接:
https://hdlbits.01xz.net/wiki/Dualedge
現(xiàn)在我們已經(jīng)熟悉了觸發(fā)器,它們會在時鐘的上升沿或時鐘的下降沿被觸發(fā)。而雙邊觸發(fā)器會在時鐘的上升沿和下降沿上觸發(fā)。但是,F(xiàn)PGA中沒有雙邊緣觸發(fā)的觸發(fā)器,并且always @(posedge clk or negedge clk)并不被認(rèn)為是合法的敏感列表。
請構(gòu)建一個功能類似于雙邊觸發(fā)器的電路:

(注意: 這不一定是完全等價的: 觸發(fā)器的輸出沒有報(bào)錯,但是對于更大的仿真組合電路中執(zhí)行此操作可能會報(bào)錯。不過在這里我們可以忽略這些細(xì)節(jié)。)

題目
提示:
不能在FPGA中創(chuàng)建雙邊觸發(fā)器。但是可以分別創(chuàng)建上升沿觸發(fā)器和下降沿觸發(fā)器。
這個問題是一個中等難度的電路設(shè)計(jì)問題,但只需要基本的Verilog語言功底就可以完成。(這是電路設(shè)計(jì)問題,不是編程問題。)在嘗試編程之前,先手繪電路圖可能會有所幫助。

答案

輸出波形


過程結(jié)構(gòu)語句有 2 種,initial 與 always 語句。它們是行為級建模的 2 種基本語句。
一個模塊中可以包含多個 initial 和 always 語句,但 2 種語句不能嵌套使用。
這些語句在模塊間并行執(zhí)行,與其在模塊的前后順序沒有關(guān)系。
但是 initial 語句或 always 語句內(nèi)部可以理解為是順序執(zhí)行的(非阻塞賦值除外)。
每個 initial 語句或 always 語句都會產(chǎn)生一個獨(dú)立的控制流,執(zhí)行時間都是從 0 時刻開始。
always 語句是重復(fù)執(zhí)行的。always 語句塊從 0 時刻開始執(zhí)行其中的行為語句;當(dāng)執(zhí)行完最后一條語句后,便再次執(zhí)行語句塊中的第一條語句,如此循環(huán)反復(fù)。
由于循環(huán)執(zhí)行的特點(diǎn),always 語句多用于仿真時鐘的產(chǎn)生,信號行為的檢測等。
在 Verilog 中,事件是指某一個 reg 或 wire 型變量發(fā)生了值的變化。
基于事件觸發(fā)的時序控制又主要分為以下幾種。
一般事件控制
事件控制用符號?@?表示。
語句執(zhí)行的條件是信號的值發(fā)生特定的變化。
關(guān)鍵字 posedge 指信號發(fā)生邊沿正向跳變,negedge 指信號發(fā)生負(fù)向邊沿跳變,未指明跳變方向時,則 2 種情況的邊沿變化都會觸發(fā)相關(guān)事件。例如:
命名事件控制
用戶可以聲明 event(事件)類型的變量,并觸發(fā)該變量來識別該事件是否發(fā)生。命名事件用關(guān)鍵字 event 來聲明,觸發(fā)信號用?->?表示。例如:
敏感列表
當(dāng)多個信號或事件中任意一個發(fā)生變化都能夠觸發(fā)語句的執(zhí)行時,Verilog 中使用"或"表達(dá)式來描述這種情況,用關(guān)鍵字?or?連接多個事件或信號。這些事件或信號組成的列表稱為"敏感列表"。當(dāng)然,or 也可以用逗號?,?來代替。例如:
當(dāng)組合邏輯輸入變量很多時,那么編寫敏感列表會很繁瑣。此時,更為簡潔的寫法是?@*?或?@(*),表示對語句塊中的所有輸入變量的變化都是敏感的。例如:
參考內(nèi)容:
4.1 Verilog 過程結(jié)構(gòu)?| 菜鳥教程:
https://www.runoob.com/w3cnote/verilog-process-structure.html
4.3 Verilog 時序控制?| 菜鳥教程:
https://www.runoob.com/w3cnote/verilog-timing-control.html