前回、メモ:QuartusII 12.1 バレルシフタの記述とTimeQuestによる速度評価の続き。

 バレルシフタの入力、出力を64bitとすると、シフト量は0~64になる。つまりシフト量の指定に6bit+1必要。これらをfunction文による自前の組み合わせ回路と<<演算子による記述で比較してみた。

ソースはこちら:https://gist.github.com/houmei/5522404 

 function文によるRTLはこのようになる。(8bit幅)
sll8_15LE3 
 コンパイル結果は以下。27LEで3段。
62MHz


 <<演算子によるRTLはこんな表示。
sll8shiftop

 コンパイル結果。32LE4段。
33MHz


 このような感じで4~64bitまでの組み合わせ回路によるバレルシフタと演算子によるバレルシフタについて、LE数と動作周波数で比較した。
  barrel

 横軸は4,8,16,24,32,48,64が等間隔に並んでいるのに注意。組み合わせ回路はLE数が少なくて済むが、8~16bitのあたりで速度が逆転する。これを配置配線後の回路でみると、こうなっている。

組み合わせ回路によるもの:
06MHz

<<演算子によるもの:
05MHz
 <<演算子でコンパイラに任せたほうが、LEがまんべんなく散らばっているようにみえる。LE自体のディレイよりも配線のディレイが大きいように思える。
16bitくらいの大きさまでなら組み合わせ回路で手書きしたほうがいいが、回路をケチる必要がなければコンパイラに任せたほうがいい。


 <<の演算子で書くならparameter文で指示したら良さそうと思うでしょう?実験した。上位モジュールからは
 sllp #(63) SLL(source,value,sftout);
の様に書いてparameter文を使ったsllp.vを呼び出すようにコンパイルしてみる。すると、24bitで以下の様な結果となった。 
24bitでの<<演算子 / parameter文によるもの
128LE,295.33MHz / 133LE,280.74MHz

 bit幅によってはまったく同じではないことがあり得る。なんでわざわざこれを試したかというと、20年くらい前に論理合成ツールを使った時に怪しい挙動を経験したため。なので、ギチギチに詰める必要がある場合はいろいろ疑ってみたほうがいいかもしれない。

追記:@ikwzmさんにfor文を使った書き方を教えてもらいました。https://gist.github.com/ikwzm/5523178 398LE/199.76MHz
ちょっと8byteシフト&8bitシフトの組み合わせで64biシフタを構成したら210LE/310.95MHz