さて、バレルシフタをverilogでどう記述するかというとこんな感じでしょうか?
parameter DATA_WIDTH = 8;
parameter SHIFT_WIDTH = 3;
input [DATA_WIDTH-1:0] iDATA_IN;
input [SHIFT_WIDTH-1:0] iSHIFT;
output [DATA_WIDTH-1:0] oDATA_OUT;
wire [(DATA_WIDTH*2)-1:0] shiftedData;
assign shiftedData = {iDATA_IN,iDATA_IN} << iSHIFT;
assign oDATA_OUT = shiftedData[(DATA_WIDTH*2)-1:DATA_WIDTH];
つまり入力がabcdefghと与えられた場合、まずそれを2つ並べて
{abcdefgh,abcdefgh}
それをシフト。たとえば3つシフトするなら
{defghabcdefgh,xxx}
最後に上位半分だけとって
defghabc
でバレルシフト完成。
ただ、これってどのような回路になっているのか簡単にはわからないですよね。
恐らく、この記述の合成結果は次のようになっていると思います。
wire [DATA_WIDTH-1:0] shift1stDATA;
wire [DATA_WIDTH-1:0] shift2ndDATA;
assign shift1stDATA = (iSHIFT[0]) ?
{iDATA_IN[DATA_WIDTH-2:0],iDATA_IN[DATA_WIDTH-1]} :
iDATA_IN;
assign shift2ndDATA = (iSHIFT[1]) ?
{shift1stDATA[DATA_WIDTH-3:0],
shift1stDATA[DATA_WIDTH-1:DATA_WIDTH-2]} :
shift1stDATA;
assign oDATA_OUT = (iSHIFT[2]) ?
{shift2ndDATA[DATA_WIDTH-5:0],
shift2ndDATA[DATA_WIDTH-1:DATA_WIDTH-4]} :
shift2ndDATA;
つまり、
シフトのビット0で1回シフトするかどうかを判断、
シフトのビット1で2回シフトするかどうかを判断、
シフトのビット2で4回シフトするかどうかを判断、
以上をカスケードに接続してバレルシフトが完了という感じです。
しかし、このように合成してくれるかどうかはツール次第なので
心配だったら後者の記述を直接書いてもいいと思います。
再利用性を考えると前者の方が楽ですね。
0 件のコメント:
コメントを投稿