レジスタ仕様の書き方
大抵のFPGAにはS/Wからアクセスできるレジスタが存在し、そのレジスタへライト・リードすることによってデジタル回路を制御したり状態を監視したりする。
◇
レジスタ仕様を書くときの必須項目には次のようなものがある。
(1) アドレス (ベース+オフセット,バイトアドレスで書く)
(2) レジスタ名称
(3) R/Wの区別
(4) リセット値
(5) ライト後に有効になるタイミング
(6) 各ビット/フィールドの説明
仕様書には、これらを表で書くとよい。
BASE: A[19:16]=h5 |
||||||
A[15:0] |
名称 |
R/W |
bit |
リセット |
タイミング |
説明 |
h1000 |
送信データ |
R/W |
15:0 |
0 |
即時 |
送信するデータ値 |
h1002 |
送信コマンド |
R/W |
0 |
0 |
1ms周期 |
送信データレジスタ値を次の1ms周期に送信する |
h1004 |
(reserved) |
|
|
|
|
|
レジスタ仕様というと、ビット・イメージをそのまま図示しているものをよく見るが、ビット/フィールド位置を示すには[n:m]と書けば十分で、図にすると情報量の割にスペースを取るのでよくない。
× ビット・イメージをそのまま図示した例
◇◇
上記の「R/Wの区別」とはそのレジスタがS/Wからライト・リード可能なのかを示す項目であり、次の5パターンにまとめられると思う。
R/W |
説明 |
例 |
R/W |
S/Wだけがリードライトできる |
普通 |
R |
H/Wがライトして、S/Wはリードだけできる |
H/Wステータス |
R/W1 |
S/Wが1をライトするとH/Wの動作が起動して、完了するとH/Wが0クリアする(0をライトしたときは何も起きない) S/Wでリードできる |
H/Wの起動フラグ |
R/W1C |
H/Wが1をセットして、S/Wが1をライトするとそのビットだけ0クリアされる(0をライトしたビットは変化しない) S/Wでリードできる |
割り込みフラグ |
RC |
H/Wが1セットして、S/Wがリードしたときに0クリアする |
割り込みフラグ |
このうちRCは、他と違ってリードしただけで値が変わってしまうので、なるべく使わない方がよい。ただし、「S/Wがリードとクリアの2回アクセスをする間にH/Wにより再セットされたときに、そのセットを取りこぼさないようにしたい」というような場合にはRCを使うしかない。
◇◇◇
レジスタ仕様を決めるとき、S/Wから単純なライト・リードテストができた方がよいので、次の原則を守るとよい。
(1) ライトとリードと両方できる(R/W)ようにする
ライトオンリー(W)やリードオンリー(R)のレジスタは作らない方がよい。ただし次の場合は例外である。
・H/Wのステータスは必然的にR
・アドレスが足りないため同一アドレスにWとRのレジスタを割り当てる
(2) ライト直後にその値がリードできるようにする
例えば「ライトした値が別のタイミング信号で有効になり、現在有効な値がリードできる」という仕様にすると、1をライトした直後にリードすると0が読めてしまい不都合なので、1をライトしたらすぐに1になるようにした方がよい。
例)送信要求をライトしてから送信開始するまでに時間が空く場合
(3) レジスタ間でアクセス順に依存関係がないようにする
例えば「レジスタ(A)の値が示すアドレスにレジスタ(D)へライトした値が書かれる」という仕様とすると、レジスタ(A)と(D)はアクセス順に依存関係ができてしまうので避けた方がよい。
また、S/Wでのアクセス順どうりにデバイスへのアクセスが実行されるとは限らないことに注意。例えば、異なるアドレスへのライトとリードの順番は逆転することがある。これはCPUとデバイスの間にあるバスブリッジにリードFIFOとライトFIFOがあって、リードFIFOの実行が優先されるからである。