2019/08/28

mermaidによるステートマシン設計

ステートマシン描きたい.

FPGAを設計するときにステートマシンを描くことはよくあるものの, 自分の中でツールや描き方が確立できていない. ということでmermaid[1]を使ってステートマシンを描いてみる. mermaidはテキスト形式で図を描くことのできるツール. Typora[2]やMarkdown Preview Enhanced(MPE)[3]などで描画できる(ちなみにMPEではmermaid.css"theme": "default"を追記しないと残念なことになる). 詳しくは参考を見ていただきたい.

テンプレート

まずは簡単な例で示す.

graph TB
Idle((Idle)) --> |Condition A| StateA
Idle --> |Condition B| StateB
StateA(StateA) --> StateC
StateC --> StateB
StateB --> TurnAround
TurnAround(TurnAround) --> Idle

Condition A

Condition B

Idle

StateA

StateB

StateC

TurnAround

上の例では初期状態のステート(Idle)を丸で示している. また遷移条件を持たないステートつまり次のクロックサイクルで別のステートに遷移するもの(StateA, TurnAround)を角丸の四角形. 遷移条件を持つステート(StateB, StateC)を四角で示した. また通常の遷移条件は記載せず, ステート遷移が分岐する場合に条件(Condition A, Condition B)を記載した.

I2Cバスアクセスのステートマシン

より具体的な例としてI2Cバス(I2Cと書くとI2C警察がやってくる)にアクセスするステートマシンを描いてみる. バスアクセスは以下のライトとリードを想定する.

ライトアクセス

  1. スタートコンディション
  2. デバイスアドレス
  3. レジスタアドレス
  4. データ書き込み
  5. ストップコンディション

リードアクセス

  1. スタートコンディション
  2. デバイスアドレス
  3. レジスタアドレス
  4. リスタートコンディション
  5. デバイスアドレス
  6. データ読み出し
  7. ストップコンディション

よくあるI2Cバスアクセスはこんなもんだと思う. M24のE2Pとかこんな感じ.

描いたのが以下の通り. リスタートコンディションをスタートコンディションへの折返しで表現している(そもそもリスタートコンディションというものはない).

graph TB
Idle((Idle)) --> StartCondition
StartCondition --> DeviceAddress
DeviceAddress --> |Register write| RegisterAddress
RegisterAddress --> WriteData
WriteData --> StopCondition
DeviceAddress --> |Read| ReadData
ReadData --> StopCondition
RegisterAddress --> StartCondition
StopCondition --> TurnAround
TurnAround(TurnAround) --> Idle

Register write

Read

Idle

StartCondition

DeviceAddress

RegisterAddress

WriteData

StopCondition

ReadData

TurnAround

ここで注意したいのが, 記述の順序によって図の位置が変化するということである. DeviceAddress --> |Read| ReadDataの行を上にもっていくと下のように図が変化する.

graph TB
Idle((Idle)) --> StartCondition
StartCondition --> DeviceAddress
DeviceAddress --> |Register write| RegisterAddress
RegisterAddress --> WriteData
WriteData --> StopCondition
DeviceAddress --> |Read| ReadData
ReadData --> StopCondition
RegisterAddress --> StartCondition
StopCondition --> TurnAround
TurnAround(TurnAround) --> Idle

Read

Register write

Idle

StartCondition

DeviceAddress

WriteData

StopCondition

ReadData

RegisterAddress

TurnAround

この例では分岐が少ないためあまり変化しないが, 分岐が増えて横に広がると順序によってはめちゃめちゃになるので注意してほしい.

すばやくステートマシンをスケッチできるのでざっくり考えて頭の中を整理するのには使えそう.

参考

[1] Flowcharts - mermaid
[2] Typoraでシーケンス図、フローチャート、ガントチャートを描くための書き方まとめ - Qiita
[3] Diagrams - Markdown Preview Enhanced

0 件のコメント:

コメントを投稿