VHDL如何处理溢出?

sro*_*r32 2 binary fpga vhdl addition

我正在进行一项设计,我认为可能会出现一些我需要处理的溢出问题.为了解决我的问题,我需要了解VHDL如何处理二进制溢出.下面是一些示例代码.

signal temp   : std_logic_vector (7 downto 0) := "11111111"; 
signal temp_2 : std_logic_vector (7 downto 0) := "11111111";
signal result : std_logic_vector (8 downto 0) := "000000000";

result <= temp + temp_2 ;
Run Code Online (Sandbox Code Playgroud)

显然,这没有调用相关的库,但它给出了我正在使用的代码的概念.我的问题是:这个二进制加法如何工作(temp + temp_2),即result运行此代码后信号会是什么?现在,我在编译中遇到错误,因为它result是9位,它期望8位.任何关于这个二进制加法如何工作的解释都会非常有用!

Rus*_*ell 6

VHDL是强类型的.无论何时分配信号,都需要匹配类型和宽度.

对于类型:您不能将整数类型信号分配给std_logic_vector信号,编译器将抛出错误.您必须首先将整数转换为std_logic_vector.

对于宽度:您需要始终完美匹配宽度分配.在您的情况下,该工具对您很生气,因为您要为信号结果(宽度为9位)分配8位宽的内容.

为了达到您想要的效果,您必须使用符号扩展名.您是签名还是未签名?如果它们是无符号的,只需在最高位位置添加"0".如果它们已签名,则必须确定位位置7的符号,然后将其扩展到位位置8.

以下是两种情况下的处理方法:

temp_extended_unsigned <= '0' & temp(7 downto 0);
temp_extended_signed   <= temp(7) & temp(7 downto 0);

temp_2_extended_unsigned <= '0' & temp_2(7 downto 0);
temp_2_extended_signed   <= temp_2(7) & temp_2(7 downto 0);

result <= temp_extended_unsigned + temp_2_extended_unsigned; -- unsigned case
result <= temp_extended_signed   + temp_2_extended_signed; -- signed case
Run Code Online (Sandbox Code Playgroud)

注意,添加1位的位置适用于加法,但乘法呢?您必须考虑要执行的操作...将两个8位宽的向量相乘会产生16位宽的结果,因此在该示例中必须对高8位进行符号扩展.

  • 另请注意,ieee.numeric_std包中的resize()函数可以正确地扩展有符号向量(并在收缩时保持符号):data_out <= resize(data_in,data_out'length); (并且包std_logic_arith中有符号扩展函数SXT(),但这不是标准库,而且读取有点密码.) (4认同)