ステートの決め方

[] [] []


極端に言うと小さなカウンタでもFPGA全体でもステートマシンと見なせてしまうので、どこをステートマシンとして区切るかは設計者の主観によってしまうが、ステートを決める際の指針になりそうなものを考えてみる。

ステートの決め方の原則は、制御信号を決めている記憶素子(FF)はすべてステート、入力信号を遷移条件と分けることだが、FFとしてステートとは別にカウンタとかフラグを設けてそれを遷移条件とした方がよいこともある。

1単にNクロック待つ処理は、ステート内でカウンタを回して待つとよい。

Nが小さければ1クロックに1ステート割り当てるのが簡単であるが

Nが長ければ1つのステート内でカウンタを回して既定回数になったら次に進むようにした方が見通しがよい

◇◇

2) 複数の要求元から要求パルス受けて逐次処理する場合は、パルスをフラグで受けてそれを遷移条件にするとよい。

簡単のため、次のような2つのイベント間の排他制御を考える:

・要求元A,Bから非同期に要求パルス(reqa,reqb)が来る

・要求パルスが来たら要求元に応じて処理Aか処理Bを行う

・要求元は自分の処理が終わるまで次の要求パルスは出さない前提とする

まず、要求パルスが来たことを覚えておくフラグ(flga,flgb)を設ける。

このフラグを遷移条件として処理を開始すればよい。フラグは処理の最後にクリアする。

こうすれば、一方の処理中に他方の要求パルスが来ても取りこぼさないことは明らかで、また処理は1つのステートマシンでやっているので排他的であることも明らかである。

処理A,Bが同じシーケンス(1つの同じリソースを使うなど)の場合は、A,Bの区別をステートとは別にIDとして設けてもよい。

この例のように、複数の非同期イベントを排他制御するケースはよくあるが、一般に時間軸方向の組合せはシミュレーションによる検証が難しい。力ずくで、イベント間の間隔を1クロックづつずらしてシミュレーションするとしても、イベント数が多くなると現実的でなく、できればソースコード・レビューで検証できるようにした方がよい。そのため、多数のフラグやカウンタが複雑に絡み合ったロジックでなく、排他制御の部分だけフラグにして、他はステートマシンに分離するとシンプルになってよい

◇◇◇

ちなみに、上記の例でフラグをステートに含めてしまうと、

IDLEは、(flga,flgb)=(0,0),(1,0),(0,1)3状態

SA0からSA2までは、flgb=0,12状態

SB0からSB1までは、flga=0,12状態

2倍以上の状態数に分かれてしまい、見通しが悪くなるのでよくない。


[] [] []