2016-12-02 16 views
2

1クロックサイクル中に変数hit_bitsを複数回再割り当てしたいとします。 io.bits_perf.bits(i)がtrueの場合はhit_bitsが増加します。私は "COMBINATIONAL PATHを見つけました!"私はコードをコンパイルしようとします。クロックサイクル内で変数を複数回再割り当て - チゼル

この例では

val hit_bits = Bits() 
    hit_bits := Bits(0) 

    when(io.bits_perf.valid){ 
    for(i<- 0 until 3){ 
     when(io.bits_perf.bits(i)) { hit_bits := hit_bits + Bits(1) 
     } 
    } 
    } 

答えて

3

、心の中でチゼル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_bitshit_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_bits0で始まる、チゼル・ノードへの参照であるということです。次に、forループ内の各インデックスについて、ヒットするノードを変更します。hit_bitsは、参照される以前のノードhit_bitsの加算の出力であるチゼルノードであり、ビットはio.bits_perf.bitsです。

関連する問題