HDLBits (157) — 完整的計時器
本題鏈接:
https://hdlbits.01xz.net/wiki/Exams/review2015_fancytimer
這是一系列五個練習中的第五部分,這些練習由幾個較小的電路構建一個復雜的計數器。 你可能會需要先做前面的四個練習?(counter、sequence recognizer FSM、?FSM delay和?combined FSM)。
我們想創(chuàng)建帶有一個輸入的計時器:
當檢測到特定輸入模式 (1101) 時啟動,
?再移 4 位以確定延遲的持續(xù)時間,
?等待計數器完成計數,并且
?通知用戶并等待用戶確認計時器。
串行數據在數據輸入引腳上可用。 當接收到模式 1101 時,電路必須移入接下來的 4 位,首先是最高有效位。 這 4 位決定了定時器延遲的持續(xù)時間。 我將此稱為延遲[3:0]。
之后,狀態(tài)機斷言其計數輸出以指示它正在計數。 狀態(tài)機必須精確計數?(delay[3:0] + 1) * 1000 個時鐘周期。 例如,delay=0 表示計數 1000 個周期,delay=5 表示計數 6000 個周期。 同時輸出當前剩余時間。 這應該等于delay 個 1000 個周期,然后 delay-1?個 1000 個周期,依此類推,直到 0 再 1000 個周期。 當電路不計數時,count[3:0] 輸出是無關緊要的(設置任何值都可實現)。
此時,電路必須斷言 done 以通知用戶計時器已超時,并等待輸入 ack 為 1,然后再復位以查找下一次出現的啟動序列 (1101)。
電路應復位為開始搜索輸入序列 1101 的狀態(tài)。
這是預期輸入和輸出的示例。? 'x' 狀態(tài)看起來可能有點混亂。 它們表明有限狀態(tài)機不應該關心該周期中的特定輸入信號。 例如,一旦讀取了 1101 和 delay[3:0],電路就不再查看數據輸入,直到在其他所有操作完成后恢復搜索。 在本例中,電路計數 2000 個時鐘周期,因為 delay[3:0] 值為 4'b0001。 最后幾個周期以 delay[3:0] = 4'b1110 開始另一個計數,它將計數 15000 個周期。


題目
提示:
硬件應該類似與?Exams/review2015_fsm 中的有限狀態(tài)機、Exams/review2015_count1k 中的計數器和 Exams/review2015_shiftcount 中的移位寄存器+計數器的組合。?在此基礎上你可能需要加入更多的比較器。
如果組件位于它們自己的 always 塊中,則可以將所有代碼放在單個模塊中,只要清楚哪個代碼塊對應于哪個硬件塊即可。 不要將多個 always 塊合并在一起,因為這會導致閱讀困難并且容易出錯。

答案

非阻塞賦值屬于并行執(zhí)行語句,即下一條語句的執(zhí)行和當前語句的執(zhí)行是同時進行的,它不會阻塞位于同一個語句塊中后面語句的執(zhí)行。非阻塞賦值語句使用小于等于號?<=?作為賦值符。
條件(if)語句用于控制執(zhí)行語句要根據條件判斷來確定是否執(zhí)行。條件語句用關鍵字 if 和 else 來聲明,條件表達式必須在圓括號中。如果?if 條件每次執(zhí)行的語句只有一條,那么可以不使用 begin 與 end 關鍵字。但如果是 if-if-else 的形式,即便執(zhí)行語句只有一條,不使用 begin 與 end 關鍵字也會引起歧義。當然,編譯器一般按照就近原則,使 else 與最近的一個 if(例子中第二個 if)相對應。但顯然這樣的寫法是不規(guī)范且不安全的。所以條件語句中加入 begin 與 and 關鍵字就是一個很好的習慣。
case 語句是一種多路條件分支的形式,可以解決 if 語句中有多個條件選項時使用不方便的問題。case 語句支持嵌套使用。case 語句中的條件選項表單式不必都是常量,也可以是 x 值或 z 值。當多個條件選項下需要執(zhí)行相同的語句時,多個條件選項可以用逗號分開,放在同一個語句塊的候選項中。但是 case 語句中的 x 或 z 的比較邏輯是不可綜合的,所以一般不建議在 case 語句中使用 x 或 z 作為比較值。
同步復位是指復位信號在時鐘有效邊沿到來時有效。如果沒有時鐘,無論復位信號怎樣變化,電路也不執(zhí)行復位操作。
該描述代碼常常會被綜合成如下電路:

同步復位的優(yōu)點:信號間是同步的,能濾除復位信號中的毛刺,有利于時序分析。
同步復位的缺點:大多數觸發(fā)器單元是沒有同步復位端的,采用同步復位會多消耗部分邏輯資源。且復位信號的寬度必須大于一個時鐘周期,否則可能會漏掉復位信號。
有限狀態(tài)機(Finite-State Machine,FSM),簡稱狀態(tài)機,是表示有限個狀態(tài)以及在這些狀態(tài)之間的轉移和動作等行為的數學模型。狀態(tài)機不僅是一種電路的描述工具,而且也是一種思想方法,在電路設計的系統級和 RTL 級有著廣泛的應用。
Verilog 中狀態(tài)機主要用于同步時序邏輯的設計,能夠在有限個狀態(tài)之間按一定要求和規(guī)律切換時序電路的狀態(tài)。狀態(tài)的切換方向不但取決于各個輸入值,還取決于當前所在狀態(tài)。狀態(tài)機可分為 2 類:Moore?狀態(tài)機和?Mealy?狀態(tài)機。
參考內容:
4.2 Verilog 過程賦值 | 菜鳥教程:
https://www.runoob.com/w3cnote/verilog-process-assign.html
4.5 Verilog 條件語句 | 菜鳥教程:
https://www.runoob.com/w3cnote/verilog-condition-statement.html
4.6 Verilog 多路分支語句 | 菜鳥教程:
https://www.runoob.com/w3cnote/verilog-case.html
5.1 Verilog 復位簡介 | 菜鳥教程:
https://www.runoob.com/w3cnote/verilog2-reset.html
6.3 Verilog 狀態(tài)機?| 菜鳥教程:
https://www.runoob.com/w3cnote/verilog-fsm.html