ハードウェアの気になるあれこれ

技術的に興味のあることを調べて書いてくブログ。主にハードウェアがネタ。

Chiselで作るNIC - (1)- 仕様について

スポンサーリンク

ちょっとパラメタライズのやり方を検討したかったので、ものすごく簡単なデータ用のインターコネクト的なやつをChiselで書いてみたのでそれについてをまとめておく。 今回の記事は全体の仕様について。

NICの仕様

自分で作ったRISC-VにメモリとUARTを繋いで動かしたいなーと考えた時に、なんかしらの形でメモリアクセス要求を捌かなあかん!!ということに気づいたのでNICを作ってみようと考えた。

手始めにChiselの文法とか後はutilのモジュールとかを使ってどんな感じにすればいいかを試そうと思う。

今回のネタで作ったモジュールは「パラメタライズでどれくらいのことが出来そうか」という部分に重きをおいてます。モジュールのソースコード自体は全部載せる気でいますが、基本的な試験しかしてないのでどっかしらバグってるかも。

「こんな感じに作れるのかー」くらいな気持ちでご一読ください。(後ほど後自分のgithubリポジトリには動作確認のテスト込みで公開します)

バスの仕様

実際に作ろうとしているのは「接続したMasterからのアドレスに応じて、適切なスレーブにデータアクセスを流す」という処理なのだが、ひとまずどんなことが出来そうかを把握したかったので、以下のような仕様のバスを定義してみた。

信号名 ビット幅 方向 説明
valid 1 Output アクセス要求を示す信号。Highで要求あり
ready 1 Input スレーブ側の状態を示す信号。Highで要求を処理可能
dst 可変 Output 宛先を示す信号(いわゆるアドレス、名前アドレスにしとけばよかった)
data 32 Output 転送データ

上記の表を書いてから思ったけど、要はread-validのハンドシェイクを使ったライトだけ出来るバスって感じ。

波形書くのが面倒だったので、実際に動かした際の波形を。下記の波形は4入力-3出力で動かしたもの。twitterに載っけたやつなので見た人いるかも。

NIC_INPUTと書いたブロックが入力側の処理要求で、各々入力ポートが4回処理要求を出しています。その4回の処理要求は出力側の0-3にそれぞれ一回ずつ流れていく感じでそれがNIC_OUTPUTと書いたブロック以下の信号です。

f:id:diningyo-kpuku-jougeki:20190721211122p:plain

パラメタライズについて

とりあえず以下の部分はいじれるようにしておこうと思う。

  • Masterポートの数
  • Slaveポートの数
  • タイミングケアのためのレジスタスライスの挿入の可否

ブロック図

パラメタライズ可能にするので、きちんとは決まらないが何となく図にすると以下のような感じになる。

f:id:diningyo-kpuku-jougeki:20190721211443p:plain
ブロック図

Decoder

もう単純にデコーダーで、やることは以下のひとつのみ。

  • ready-validのハンドシェイクが成立した時のdstの示すSlvaeポートにアクセスを転送する

一応、入力部分にレジスタスライスを入れて、パラメータでON/OFFが出来る仕組みを入れてみる。

Arbiter

こちらもやることはシンプル。

  • Masterからの送信要求に従って、選択した一つのアクセス要求を出力ポートに転送
    • 要求が競合した場合はインデックスの小さいポートが優先

Top

NICの最上位階層モジュール。書いてないけど、上記図の外側の四角がこれに相当するもの。この階層でパラメータのMasterポート数分のDecoder/Slaveポート数分のArbiterをインスタンスして、DecoderとAribter間を適切に接続する。

仕様の説明だけでかなり薄味だけど、ひとまずここで区切ります。