目的:
ビットシフトの記述の仕方について 記す
記述の仕方:
図のようなビットシフトを行う場合、次の様な記述の仕方がある。-
シフト演算子でシフト
シフト演算子 ( << や >> ) を用いてシフトを行う。 - シフトした信号を定義してセレクト
1bit づつシフトした信号を定義し、シフト量に応じて選択する。
通常は、シフト演算子でビットシフトを行う。
但し、下図の様に シフト量+元データ長 が シフト結果 のデータ長より長い場合、lintチェック等で Warning が 報告される。
はみ出した分は捨てられるのみで、合成は正常にできる為問題は無いが、Warning を減らしたい場合は 2. の記述をする。
また、下図の様に 元データ以外が '0' でない場合も 2. の記述で対応できる。
記述例:
シフトするデータを dat[2:0] (3bit), シフト結果を sft_data[7:0] (8bit),
シフト量を sft[3:0] (4bit) とし、左シフトする場合の記述例を示す。
- シフト演算子でシフト
assign sft_data = dat << sft ; - シフトした信号を定義してセレクト
// シフトした信号の定義
wire [7:0] sft_dt[0:8] ;
assign sft_dt[0] = { 5'd0, dat } ;
assign sft_dt[1] = { 4'd0, dat, 1'd0 } ;
assign sft_dt[2] = { 3'd0, dat, 2'd0 } ;
assign sft_dt[3] = { 2'd0, dat, 3'd0 } ;
assign sft_dt[4] = { 1'd0, dat, 4'd0 } ;
assign sft_dt[5] = { dat, 5'd0 } ;
assign sft_dt[6] = { dat[1:0], 6'd0 } ;
assign sft_dt[7] = { dat[0], 7'd0 } ;
assign sft_dt[8] = 8'd0 ;
// ビットシフト
assign sft_data = (sft < 8) sft_dt[sft] : sft_dt[8] ;
各データ長をパラメータ化した場合の 2. の記述例を以下に示す。
( 1. の場合は パラメータ化しても 変わらない )
// パラメータ定義
parameter P_DT_BW = 8 ; // 元データ ビット幅
parameter P_SFTDT_BW = 128 ; // シフト結果データ ビット幅
parameter P_SFT_BW = 8 ; // シフト量 ビット幅 (MAX 256)
// 各データの定義
wire [P_DT_BW-1:0] dat ; // 元データ
wire [P_SFTDT_BW-1:0] sft_data ; // シフト後のデータ
wire [P_SFT_BW-1:0] sft ; // シフト量
// シフトした信号の定義
wire [P_SFTDT_BW-1:0] sft_dt[0:P_SFTDT_BW] ;
genvar i ;
generate
for(i=0;i<P_SFTDT_BW-P_DT_BW;i=i+1) begin
assign sft_dt[i] =
{{(P_SFTDT_BW-P_DT_BW-i){1'b0}},dat,{(i){1'b0}}} ;
end
for(i=0;i<P_DT_BW;i=i+1) begin
assign sft_dt[P_SFTDT_BW-P_DT_BW+i] =
{dat[P_DT_BW-i-1:0],{(P_SFTDT_BW-(P_DT_BW-i)){1'b0}}} ;
end
assign sft_dt[P_SFTDT_BW] = {(P_SFTDT_BW){1'b0}} ;
endgenerate
assign sft_data = (sft < P_SFTDT_BW) ? sft_dt[sft] :
sft_dt[P_SFTDT_BW] ;
parameter P_DT_BW = 8 ; // 元データ ビット幅
parameter P_SFTDT_BW = 128 ; // シフト結果データ ビット幅
parameter P_SFT_BW = 8 ; // シフト量 ビット幅 (MAX 256)
// 各データの定義
wire [P_DT_BW-1:0] dat ; // 元データ
wire [P_SFTDT_BW-1:0] sft_data ; // シフト後のデータ
wire [P_SFT_BW-1:0] sft ; // シフト量
// シフトした信号の定義
wire [P_SFTDT_BW-1:0] sft_dt[0:P_SFTDT_BW] ;
genvar i ;
generate
for(i=0;i<P_SFTDT_BW-P_DT_BW;i=i+1) begin
assign sft_dt[i] =
{{(P_SFTDT_BW-P_DT_BW-i){1'b0}},dat,{(i){1'b0}}} ;
end
for(i=0;i<P_DT_BW;i=i+1) begin
assign sft_dt[P_SFTDT_BW-P_DT_BW+i] =
{dat[P_DT_BW-i-1:0],{(P_SFTDT_BW-(P_DT_BW-i)){1'b0}}} ;
end
assign sft_dt[P_SFTDT_BW] = {(P_SFTDT_BW){1'b0}} ;
endgenerate
assign sft_data = (sft < P_SFTDT_BW) ? sft_dt[sft] :
sft_dt[P_SFTDT_BW] ;
元データ以外が base_data の場合 (パラメータ化)
// パラメータ定義
parameter P_DT_BW = 8 ; // 元データ ビット幅
parameter P_SFTDT_BW = 128 ; // シフト結果データ ビット幅
parameter P_SFT_BW = 8 ; // シフト量 ビット幅 (MAX 256)
// 各データの定義
wire [P_DT_BW-1:0] dat ; // 元データ
wire [P_SFTDT_BW-1:0] sft_data ; // シフト後のデータ
wire [P_SFTDT_BW-1:0] base_data ; // base_data
wire [P_SFT_BW-1:0] sft ; // シフト量
// シフトした信号の定義
wire [P_SFTDT_BW-1:0] sft_dt[0:P_SFTDT_BW] ;
genvar i ;
generate
assign sft_dt[0] = {base_data[P_SFTDT_BW-1:P_DT_BW], dat} ;
for(i=1;i<P_SFTDT_BW-P_DT_BW;i=i+1) begin
assign sft_dt[i] =
{base_data[P_SFTDT_BW1:P_DT_BW+i], dat, base_data[i-1:0]} ;
end
for(i=0;i<P_DT_BW;i=i+1) begin
assign sft_dt[P_SFTDT_BW-P_DT_BW+i] =
{dat[P_DT_BW-i-1:0], base_data[P_SFTDT_BW-P_DT_BW+i-1:0]} ;
end
assign sft_dt[P_SFTDT_BW] = base_data ;
endgenerate
assign sft_data = (sft < P_SFTDT_BW) ? sft_dt[sft] :
sft_dt[P_SFTDT_BW] ;
parameter P_DT_BW = 8 ; // 元データ ビット幅
parameter P_SFTDT_BW = 128 ; // シフト結果データ ビット幅
parameter P_SFT_BW = 8 ; // シフト量 ビット幅 (MAX 256)
// 各データの定義
wire [P_DT_BW-1:0] dat ; // 元データ
wire [P_SFTDT_BW-1:0] sft_data ; // シフト後のデータ
wire [P_SFTDT_BW-1:0] base_data ; // base_data
wire [P_SFT_BW-1:0] sft ; // シフト量
// シフトした信号の定義
wire [P_SFTDT_BW-1:0] sft_dt[0:P_SFTDT_BW] ;
genvar i ;
generate
assign sft_dt[0] = {base_data[P_SFTDT_BW-1:P_DT_BW], dat} ;
for(i=1;i<P_SFTDT_BW-P_DT_BW;i=i+1) begin
assign sft_dt[i] =
{base_data[P_SFTDT_BW1:P_DT_BW+i], dat, base_data[i-1:0]} ;
end
for(i=0;i<P_DT_BW;i=i+1) begin
assign sft_dt[P_SFTDT_BW-P_DT_BW+i] =
{dat[P_DT_BW-i-1:0], base_data[P_SFTDT_BW-P_DT_BW+i-1:0]} ;
end
assign sft_dt[P_SFTDT_BW] = base_data ;
endgenerate
assign sft_data = (sft < P_SFTDT_BW) ? sft_dt[sft] :
sft_dt[P_SFTDT_BW] ;
0 件のコメント:
コメントを投稿