丸め機能付の算術右シフト関数をVHDLで書きました。
丸めは演算の精度に大きく影響することはよく知られていますし、実験結果もそのとおりになります。たとえば、32bit NCOの精度評価でも丸めの有無で結果が変っています。ところが、丸め自身は軽視されることがあります。具体的には算術右シフトです。算術右シフトはMSBの符号ビットが保存されることばかり強調されますが、なぜか右側のビットは常に切り捨てられます。VHDLのnumeric_std.signedでは違うのではないかと期待しましたが、期待は裏切られました。
そういうわけで、自分で作ったのが丸め付き右シフト関数です。
-- shift right arithmetic with rounding. function sra_round( arg : signed; count : integer ) return signed is -- create a bit vector which has value 1 at bit position count -1, the width is same with arg. constant r : signed( arg'range ) := ( ( count - 1 ) => '1', others => '0' ); begin -- to make rouding for n bit shift right, -- add 1 to the bit bit position n-1 return ( arg + r ) sra count; end sra_round;
この関数は受け取ったnumeric_std.signed型引数argをcountビットだけ右シフトします。その際、LSBの右側のビットが1であれば切り上げ、そうでなければ切り捨てしています。返す値にの幅はargの幅と同じです。