、心の中でチゼルとScalaの間の差を維持することが重要です。より具体的には、when
はVerilogの条件付き接続にマッピングされるChisel構造ですが、for
はVerilogのgenerate
に似たハードウェアの生成に使用できるScala構造体です。
のは、ループのためにこれをアンロールし、我々が得るものを見てみましょう:
when(io.bits_perf.valid){
when(io.bits_perf.bits(0)) { hit_bits := hit_bits + Bits(1) }
when(io.bits_perf.bits(1)) { hit_bits := hit_bits + Bits(1) }
when(io.bits_perf.bits(2)) { hit_bits := hit_bits + Bits(1) }
}
注io.bits_perf.valid
が高く、io.bits_perf.bits
のビットのいずれかが高く、あなたが接続されたときにすべての接続は、同じであることhit_bits
〜hit_bits + Bits(1)
。これは組み合わせループです。
ここで、実際に何をしようとしているのかを説明しましょう。io.bits_perf.valid
が高い場合、io.bits_perf.bits
の個数にhit_bitsをどのように接続するのかを考えてみましょう。これは、ポップカウントとしても知られています。チゼルにはこのようなユーティリティがあります。
ただし、あなたが書いたコードは正しいものであり、とにかく動作させるようにしてください。私たちがしたいことは、コード生成を行うためにScala forループを使用することです。これを行う1つの方法は、valではなく、シズルノードの「ポインタ」の一種として、スレーブvar(再割り当てを許可する)を使用することです(したがって、ポイントを変更することはできません)。別のチゼルノード)。あなただけのビットを追加し、直接ではなく、条件付きで、ここで何が起こっている1を追加することができますので、私も時に条件付きのインナーを落とし
var hit_bits = Bits(0, 2) // We set the width because + does not expand width
when (io.bits_perf.valid) {
for (i <- 0 until 3) {
hit_bits = hit_bits + io.bits_perf.bits(i)
}
}
// Now hit_bits is equal to the popcount of io.bits_perf.bits (or 0 if not valid)
注hit_bits
が0
で始まる、チゼル・ノードへの参照であるということです。次に、forループ内の各インデックスについて、ヒットするノードを変更します。hit_bitsは、参照される以前のノードhit_bitsの加算の出力であるチゼルノードであり、ビットはio.bits_perf.bits
です。