1. 程式人生 > >RTL基本知識:使用枚舉類型表示狀態機進入死循環

RTL基本知識:使用枚舉類型表示狀態機進入死循環

sys 解決方法 其中 代碼 遞增 tro 跳轉 集合 enter

在定義狀態機中的狀態時,除了可以使用宏(define)或者參數(parameter)聲明定義外,還可以使用枚舉類型,但是如果對於枚舉類型使用不正確的話,極易出現編譯仿真均沒有報錯,但是仿真時狀態機跳轉異常的情況.本文將針對這種情況進行示例說明並給出解決方法.

1 數據類型

在Verilog中所有的變量和線網都是4值數據類型,但在SystemVerilog中,對信號類型和數據類型進行了詳細的區分,其中信號類型保持與Verilog一樣,主要分為變量和線網類型,但是數據類型分為了2值類型(0和1)和4值類型(0,1,x和z),對信號的數據類型進行了擴展,但是保持了線網類型原有的數據類型,在默認狀態下,4值數據類型的默認值為x,2值類型的默認值為0.同時SystemVerilog結合C語言的特性,引入了其他一些類型,例如枚舉類型等,通過多種類型的引入,極大地豐富了SystemVerilog進行程序設計的靈活性.

技術分享圖片

2 枚舉類型

用戶可以通過枚舉類型定義特定的常量值的集合.

格式:

技術分享圖片

使用方式如下:

技術分享圖片

枚舉常量代表該枚舉類型的變量的可能取值的列表,編譯系統為每個枚舉常量指定一個數值,缺省狀態下這個數值從0開始,且數據類型為int,即2值型的整型.

3 問題描述

對下述代碼進行仿真時,狀態跳轉執行異常,核心代碼如下:

技術分享圖片

當上述狀態機運行時,狀態機將一直處於WAIT狀態,狀態執行異常.

4 問題分析

這裏需要註意到,枚舉常量列表中的枚舉常量在缺省狀態下,枚舉常量的數值是從0開始遞增.且2值數據類型變量的初始值為0.所以在此例中,state_e和nstate_e的初始狀態都為0,即WAIT.當復位撤銷後,state_e和nstate_e都為WAIT,那麽組合邏輯部分always@(state_e)的敏感信號列表中的state_e將一直保持在WAIT狀態,所以該部分組合邏輯將不會被執行,從而導致nstate_e狀態不會被更新,因此,狀態既不能推進,將一直保持在初始的WAIT狀態.

5 解決方法

出現上述問題主要是因為代碼中組合邏輯部分的敏感信號列表中的變量沒有發生變化,從而沒有出發進程的執行導致的,因此,解決方法主要是實現組合邏輯部分的有效執行,實現nstate_e的變化.

5.1 使用always_comb結構

always_comb在仿真開始的0時刻會自動調用一次,從而可以實現nstate_e狀態的更新,將組合結構中的always@(state_e)替換為always_comb即可.

5.2 將枚舉變量的數據類型指定為4值類型,如下所示:

技術分享圖片

在仿真開始時,因為枚舉類型的數據類型為logic型,所以變量state_e和nstate_e的默認狀態都為x態,那麽在復位階段state_e被初始化為WAIT時,組合邏輯部分的always@(state_e

中的敏感信號state_e狀態從x態變化到了WAIT,即狀態發生變化,觸發組合邏輯部分進程的執行,nstate_e會被更新為LOAD,從而可以實現狀態機的推進.

5.3 指定枚舉常量的初始值

枚舉列表中的枚舉常量列表中的第一個常量,默認初始值為0-,其後常量數值依次遞增,但是這個起始值也可以在枚舉類型聲明定義時指定為其他值,從而可以使2值型枚舉變量的初始狀態-與枚舉變量列表中的常量起始值不一樣,在復位階段state_e被更新為非零值時,更新後的值與類型的默認值0不一樣,從而也可以實現組合邏輯部分敏感信號列表中信號的變化,從而使組合邏輯中的nstate_e狀態可以被更新,推進狀態機的運行,示例如下:

技術分享圖片

更多資訊,請關註個人公眾號:芯光燦爛

技術分享圖片

RTL基本知識:使用枚舉類型表示狀態機進入死循環