(1)符号拡張
8ビットから15ビットへの変換例
左右のビット幅が異なってもVerilogではエラーになりません。例として良くないですが。
左右のビット幅が異なってもVerilogではエラーになりません。例として良くないですが。
いずれもOK
input signed [7:0] a;output signed [14:0] answer;
output [14:0] answer2, answer3, answer4;
wire [14:0] temp;
assign temp = a;
assign answer = a;
assign answer2 = a;
assign answer3 = temp;
assign answer4 = {{7{a[7]}}, a};
いずれもNG
input [7:0] a;
output signed [14:0] answer, answer2;
output [14:0] answer3;
output signed [14:0] answer, answer2;
output [14:0] answer3;
wire signed [14:0] temp;
assign temp = a;
assign answer = a;
assign answer2 = temp;
assign answer3 = temp;
output [14:0] answer;
assign answer = {{7{a[7]}}, a};
signed使わない例
input [7:0] a;output [14:0] answer;
assign answer = {{7{a[7]}}, a};
(2)シフト演算
符号を保持してシフトする演算例
算術シフト演算子を使う場合
input signed [7:0] a;output signed [14:0] answer;
output signed [14:0] answer2;
assign answer = a>>>2;
assign answer2 = a<<<2; // 右側は0詰めされる
input [7:0] a;
output [14:0] answer;
output [14:0] answer2;
assign answer = {{9{a[7]}}, a[7:2]};
assign answer2 = {{7{a[7]}}, a, 2'b0};
input signed [7:0] a;
output signed [7:0] answer;
assign answer = - a;
(4)加算
input signed [7:0] a, b;
output [7:0] answer;
assign answer = a + b;
(5)減算
input signed [7:0] a, b;
output [7:0] answer;
assign answer = a - b;
(6)乗算
input signed [7:0] a, b;
output [14:0] answer;
assign answer = a * b;
ただし、負の最大値同士の乗算でビット溢れが出ます。これを避けるためには出力のビット幅を8+8=16ビットとします。
ただし、負の最大値同士の乗算でビット溢れが出ます。これを避けるためには出力のビット幅を8+8=16ビットとします。
(7)signedとunsignedが混在する場合
unsignedをsignedに変換するには、1ビット符号拡張して符号を付ける。(MSBが1だった場合に負の数と誤認されてしまうため)
wire signed [8:0] temp;
assign temp = $signed({1'b0, a[7:0]});
wire signed [8:0] temp;
assign temp = $signed({1'b0, a[7:0]});
参考資料
・小林優(2004) 改訂・入門Verilog HDL記述 CQ出版
・元大学院生の日記 - [メモ]verilogでsignedとunsignedの乗算
・HDL Simulator Veritakのホームページ - Verilogチュートリアル
・元大学院生の日記 - [メモ]verilogでsignedとunsignedの乗算
・HDL Simulator Veritakのホームページ - Verilogチュートリアル
0 件のコメント:
コメントを投稿