ハードウェアの気になるあれこれスマートフォン用の表示で見るハードウェアの気になるあれこれ技術的に興味のあることを調べて書いてくブログ。Verilog-HDLスポンサーリンク前回の続きでChiselの文法入門編その6今回はChiselにおける拡張型であるVecとBundleの2つについてまとめて書こうを思ったのですが、思いの外膨らんだので、Vecメインにしました。必要な場合RegInitを使う場合RegNextを使う場合レジスタファイルの例で見るVecの使い方Chisel入門編〜その6:Vec〜その2でChiselの”型”として、以下を紹介しましたが実はChiselにはまだ幾つか”型”が存在しています。今回のその6ではその残りの型の中からVecとBundleについての概要を紹介し、主にVecの使い方についてをまとめます。一言で書くとBundleとVecは共にChiselの基本の型を束ねる目的で使用される拡張型といえる存在です。Verilogで言うと、以下のようなものに置き換えることが可能です。構造体VecとBundleの位置づけこれについては以下の画像を見てもらうと分かりやすいと思います。ご覧いただいたとおりでBool/UIntといった型はBitsクラスを継承しているのに対して、Vec/BundleはそれぞれAggregate/Recordクラスを継承したものになっています。これらのクラスは内部にData型のインスタンスをSeqやListMapに入れて管理しており、複数のData型をまとめて扱うことが出来るようになっています。これだけだとScalaのSeq等と一緒じゃん。なるのですがVecは実際の回路上で動的に変化する要素に対して使えるところに大きな違いがあります。使い方についてを見ていこうと思います。HDLにおけるメモリ配列に相当する概念です。上に書いたとおりScalaだとSeqと似たデータ型ですが、Chiselにおいてはこの2つは、以下のように評価のタイミングが異なっています。Chiselのエラボレート時に評価され、ハードウェア要素が固定される。回路の動作中の信号を使って評価される。io.wrdata早い話がChiselのVecを使うと通常の論理回路におけるアドレス信号等の信号を使ってVecで宣言したChiselのハードウェア要素に動的にアクセスが可能になるということです。使い分けとしては以下のように考えると良いと思います。基本形Vecの宣言は以下のような形になります。<Chiselの型のインスタンス>)要素数10で8bitのUIntのVecを宣言すると以下のような形になります。UInt(8.W))なお、VecもChiselの”ハードウェア要素”ではなくChiselの"型"になるので、実際にハードウェアとして作成する論理回路の一部にするためには”ハードウェア要素”でラッピングする必要があります。上記の”要素数10で8bitのUIntのVec”をハードウェアとしてインスタンスする場合は以下のような感じです。UInt(8.W)))Chiselを書き始めた時はこの区別がついてなかったので、以下のようにVecを外側にしてエラーが発生しまくってました。hardware初期値が必要な場合さて上記でVecの宣言の仕方は分かったと思いますが、ここで以下のような場合はどうするの??と思った方がいるのではないでしょうか?Q:初期値付きのレジスタRegInitや既存の信号を受けるRegNextの場合も一緒で良いのか?この問についての答えですが、以下のようになります。A:ちょっと宣言の仕方が変わります。RegInit(VecInit(Seq.fill(10)(0.U)))見てお気づきになられたと思いますが、上記の例では全て0.Uでレジスタが初期化されます。このやり方は以下のChiselのwikiで発見しました。github.comRegNextを使う場合RegNextは2回目で紹介したとおり、特定の信号をレジスタ受けする場合に使用しますが、初期値のあり/なしを選択することが可能です。これらのケースについてそれぞれの記述を見てみましょう。別途特定の値の初期化したVecInitが必要ここでは全てのレジスタを固定値0.Uで生成するためにSeq.fillを使っていますが、それぞれ別の値で初期化したい場合にはVecInitに渡すSeqをその値で埋めたものを渡せばOKです。HDLでCPUで使うようなレジスタファイルを作成するケースを考えてみます。その場合、メモリ配列を使って以下のような感じになると思います。使う場合コードは以下のようにgenerate構文を使って処理するようなイメージになると思います。regs[rdaddr_1];endmoduleChiselで書くレジスタファイル同じものをChiselで書いてみると以下のようになります。́・ω・`)せっかくVecが使えるようになったのでリード系の端子もまとめてしまいましょう。}}もう少しScalaっぽくするためにforループ部分を高階関数を使って書き直すと以下のようになります。HDLのメモリ配列に相当する要素”と書きましたが、これは文法上の扱いだけでChiselのVecはRTLに変換するとVecに指定したChiselのハードウェア要素にインデックスが付与された形でベタにRTL上に展開されます。以下は上のRegFileの要素数を4に変更して生成したRTLです。endendmoduleChiselの記述によってRTLに変換した際に凄まじいif文のネストを含むRTLが生成されることがありますので、変換したRTLはチェックすることをお勧めします(前にRISC-VのレジスタファイルをVecで生成したら32個のレジスタ分だけif文のネストが出来たりしました)。上記の例で見た様にChiselのVec型は同じ型のIOポートを纏めるためにも使用できます。これを使うことでマルチプレクサやアービターのような回路をすっきりさせることが出来るようになります。ここの例ではまだ適用していませんが、次に紹介予定のBundleと組み合わせることで更に柔軟な表現が可能となり、Chiselで実装をするメリットが大きくなってくると個人的には思っています。いうことでChiselのaggregate型の一つVecの解説でした。次回はもうひとつのaggregate型であるBundleについて紹介していく予定です。〜その6:ChiselのVec〜Tweet関連記事2019-05-02Chiselで2次元メモリっぽいのを作る(2)令和になって最初の投稿。ほんとは昨日上げたかったんだけど。技書博2にChisel本を出してきました月別アーカイブはてなブログをはじめよう!diningyo-kpuku-jougekiさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。