追記:@ikwzmさんから。https://gist.github.com/ikwzm/5558633
バイト単位でシフトすべきところを4bit単位でやってました。あああ
ご指摘ありがとうございました。
※前段の 8byteシフト間違ってる気がしてきた。多分3bit分を<<5した時点ですべて'0'になってしまってるはず
(1)組み合わせ回路のシフトについて、下xx bitを削っていくような間違いをしていました。書きなおしたのは以下。
https://gist.github.com/houmei/5555418
(2)<<演算子を使ったbyte shiftは、いったん幅[6:0]の下位3bitを'000'とし、上位にシフト量を入れることで書き直しました。
扱うbit幅が大きくなるとLE数は増え動作周波数は落ちていくバレルシフタ。ここでシフト量を制限したらどうなるか傾向を見てみた。例えば1bitシフトする/しないだけなら大幅にセレクタ数が減るはず。
以下の様なコードでシフト量を1,2,4,8...と変えながら試してみる。上位モジュールからは
sll64_partial #6 SLL(source,value,sftout); // partial shift
の様に呼び出す。
64bitを部分シフト
では、最初にバイト単位でシフトして次にビット単位で8つまでシフトするようにしてみる。
シフト量のnnnnxxxのうち、nnnnはバイトでのシフト量、xxxはビットのシフト量とする。nnnnについてはシフトする量がデータ幅をあふれたらall0とする。
ソースはこちら:https://gist.github.com/houmei/5541783
コンパイル結果は207LE/284.41MHzとなった。組み合わせ回路でべたに書いた283LE/105.06MHzよりよい。
※以下も怪しい
もし、もっと追求するとしたらbit幅の組み合わせを変える(4-3を3-4)、段数を増やす(2-2-3)、一部組み合わせ回路にしてみる、など。やりだすときりがなくなるけど構造的な改善である程度の性能が出たらしばらく放置して他に着手したほうがいいかも。
あと、QuartusIIにはMagawizard Plugin Managerというのがあって、用途に合わせたライブラリが使える。今回の用途にはGates→LPMCLSHIFTというのが使えた。verilogやVHDLのインターフェース部分がソースとして出力されるのでこれを呼び出して使用する。
バイト単位でシフトすべきところを4bit単位でやってました。あああ
ご指摘ありがとうございました。
※前段の 8byteシフト間違ってる気がしてきた。多分3bit分を<<5した時点ですべて'0'になってしまってるはず
(1)組み合わせ回路のシフトについて、下xx bitを削っていくような間違いをしていました。書きなおしたのは以下。
https://gist.github.com/houmei/5555418
(2)<<演算子を使ったbyte shiftは、いったん幅[6:0]の下位3bitを'000'とし、上位にシフト量を入れることで書き直しました。
比較結果:
349LE/214.92MHz (Megafunction)
349LE/214.92MHz (Megafunction)
343LE/214.55MHz (シフト演算子)
291LE/335.46MHz (組み合わせ回路)
ただし、組み合わせ回路によるものは(1)の間違いあり。
反省:見積もりに検証していない回路を軽い気持ちで使うと大失敗
以下は間違いありです。
反省:見積もりに検証していない回路を軽い気持ちで使うと大失敗
以下は間違いありです。
扱うbit幅が大きくなるとLE数は増え動作周波数は落ちていくバレルシフタ。ここでシフト量を制限したらどうなるか傾向を見てみた。例えば1bitシフトする/しないだけなら大幅にセレクタ数が減るはず。
以下の様なコードでシフト量を1,2,4,8...と変えながら試してみる。上位モジュールからは
sll64_partial #6 SLL(source,value,sftout); // partial shift
の様に呼び出す。
module sll64_partial (indata,val,outdata);
parameter width=6; //[6:0]
input [63:0] indata;
input [width:0] val;
output [63:0] outdata;
assign outdata=indata<<val;
endmodule
結果は以下のとおり。64bitを部分シフト
[0:0] 129LE/615.38MHz
[1:0] 136LE/413.56MHz
[2:0] 143LE/357.65MHz
[3:0] 210LE/270.71MHz
[4:0] 285LE/250.38MHz
[5:0] 384LE/223.31MHz
[6:0] 390LE/220.17MHz
では、最初にバイト単位でシフトして次にビット単位で8つまでシフトするようにしてみる。
シフト量のnnnnxxxのうち、nnnnはバイトでのシフト量、xxxはビットのシフト量とする。nnnnについてはシフトする量がデータ幅をあふれたらall0とする。
※以下も怪しい
もし、もっと追求するとしたらbit幅の組み合わせを変える(4-3を3-4)、段数を増やす(2-2-3)、一部組み合わせ回路にしてみる、など。やりだすときりがなくなるけど構造的な改善である程度の性能が出たらしばらく放置して他に着手したほうがいいかも。
あと、QuartusIIにはMagawizard Plugin Managerというのがあって、用途に合わせたライブラリが使える。今回の用途にはGates→LPMCLSHIFTというのが使えた。verilogやVHDLのインターフェース部分がソースとして出力されるのでこれを呼び出して使用する。










