entity signed_sub is generic( WIDTH :integer := 16 ); port( a :in std_logic_vector(WIDTH-1 downto 0); b :in std_logic_vector(WIDTH-1 downto 0); c ut std_logic_vector(WIDTH-1 downto 0) ); end signed_sub;
architecture rtl of signed_sub is
signal a_ext :std_logic_vector(WIDTH downto 0); signal b_ext :std_logic_vector(WIDTH downto 0); signal diff :std_logic_vector(WIDTH downto 0);
begin
a_ext <= a(WIDTH-1) & a; b_ext <= b(WIDTH-1) & b; diff <= a_ext - b_ext; c <= diff(WIDTH downto 1);
end rtl; 对于上面的定点减法器,完成一般的两个带符号数据的相减是没有问题的! 但是当数据要经过多次减法操作的时候,就可能发生溢出的错误 有两种思路可以解决这个问题 1)增加数据的位数宽度,然后对高位进行带符号方式的扩展,此方法虽然相对简单 但是经过多次相加减之后就会对数据的实际表达需要的为数产生困惑 不知道到底需要几为才好 2)增加几个数位,进行标志,对于溢出的时候,可以用这几个位数标志此数据是对对高位截取了 并且记录截取的位数,这样经过多次 加减的时候,就可以相对准确的记录结果值
entity signed_subf is generic( WIDTH :integer := 16 ); port( a :in std_logic_vector(WIDTH-1 downto 0); b :in std_logic_vector(WIDTH-1 downto 0); c ut std_logic_vector(WIDTH downto 0) ); end signed_subf;
architecture rtl of signed_subf is
signal a_ext :std_logic_vector(WIDTH downto 0); signal b_ext :std_logic_vector(WIDTH downto 0); signal diff :std_logic_vector(WIDTH downto 0);
begin
a_ext <= a(WIDTH-1) & a; b_ext <= b(WIDTH-1) & b; diff <= a_ext - b_ext; c <= diff(WIDTH downto 0);
end rtl; 当然也可以采用这种方式,基本和 2)描述的方法相似 但是这个方式却没有对 进位溢出的我为数进行指定,而是直接截取高位 这样在数据相差比较大的时候是可以满足精度的 但是如果这两个数值相差本来就比较小的时候 就不是很妥当 因为本来 低 WIDTH/2 位就能表达这个准确的值,现在却将其最低位忽略了! 造成不必要的精度损失!
个人想法,希望大家批判!! |