verilog中的有符號數運算
有符號數的計算:若有需要關於有號數的計算,應當利用Verilog 2001所提供的signed及$signed()機制。
Ex:
input signed [7:0] a, b;
output signed [15:0] o;
assign o = a * b;
or
input [7:0] a, b;
output [15:0] o;
wire signed [15:0] o_sgn;
assisn o_sgn = $signed(a) * $signed(b);
assign o = $unsigned(o_sgn);
正負號的擴展:應多加利用Verilog的implicity signed extension,避免手動進行轉換。
Ex:
input signed [7:0] a, b;
input signed [8:0] o;
assign o = a + b; // Verilog會自動進行符號的擴展。有號數與無號數的混合計算:不要在同一個verilog敘述中進行有號數與無號數的計算。應該要分成個別獨立的敘述。在一個verilog敘述中只要有一個無號數的操作數,整個算式將被當成無號數進行計算。
input [7:0] a;
input signed [7:0] b;
output signed [15:0] o; // Don't do this: assign o = a * b;
// The $signed({1'b0, a}) can convert the unsigned number to signednumber.a
ssign o = $signed({1'b0, a}) * b;
input signed [7:0] a;output signed [15:0] o;
// Don't do this: assign o = a * 8'b10111111;
// Use $signed() system taskassign o = a * $signed(8'b10111111);
// or sb keyword.assign o = a * 8'sb10111111;part-select運算過後的操作數是無號數。就算是選擇的範圍包含整個register或wire。input signed [7:0] a;
input signed [7:0] b;
output signed [15:0] o1, o2; // Don't do this:
assign o1 = a[7:0];assign o1 = a;// Don't do this: assign o2 = a[6:0] * b;
assign o2 = $signed(a[6:0]) + b