- 有號數的計算:若有需要關於有號數的計算,應當利用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; assugb 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 signed number. assign 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 task assign 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