VHDL numeric_std功能 ( "+" )



大家好!

请你给我解释一件奇怪的事。numeric_std库包含一个函数"+&";,附加我插入了功能说明。

--Id:A.3函数"+"(L,R:UNSIGNED(返回UNSIGNED;--结果子类型:未忽略(最大(L’LENGTH,R‘LENGTH(-1下降到0(。--结果:添加两个可能具有不同长度的未忽略矢量

例如,我们有:

a      : in  unsigned(2 downto 0);
b      : in  unsigned(1 downto 0);
result : out unsigned(2 downto 0);

因此,如果a是";111〃;并且b是"0";01〃;结果将是";000";。原因是溢出。我的问题是,为什么库允许它,为什么它不扩展结果长度?为什么编译器不警告我溢出?是否可以在没有溢出的情况下添加值?以及我应该如何防止或发现发生溢出。

谢谢!

在硬件中,我们有递增器和递减器-;"翻转";作为它们正常操作的一部分,我们有累加器,它永远不应该翻转,我们有数学单元,需要保持操作的完全精度。

在VHDL中,当我们进行操作时,它必须产生大小精确的结果。增量器、减量器和累加器都需要保持相同大小的结果,其中需要保持运算的全部精度的数学单元需要增加大小。

因此+"只能满足其中一种需求。另一部分需要通过代码来处理。

对于numeric_std+"正如您所说,结果的大小是最大数组操作数的大小。有趣的是,在ieee.fixed_pkg中,结果的大小是最大数组操作数的1+大小。

让我们来看看这对我们的数学有何影响。

signal Co : std_logic ; -- to throw away carry out
signal Incrementer_unsigned : unsigned(3 downto 0) ; 
signal Incrementer_ufixed   : ufixed(3 downto 0) ; 
signal Accumulator_unsigned : unsigned(3 downto 0) ; 
signal Next_unsigned        : unsigned(3 downto 0) ; 
signal Accumulator_ufixed   : ufixed(3 downto 0) ;
signal Next_ufixed          : ufixed(3 downto 0) ; 
signal Sum_unsigned         : unsigned(8 downto 0) ; 
signal A_unsigned           : unsigned(7 downto 0) ; 
signal B_unsigned           : unsigned(7 downto 0) ; 
signal Sum_ufixed           : ufixed(8 downto 0) ; 
signal A_ufixed             : ufixed(7 downto 0) ; 
signal B_ufixed             : ufixed(7 downto 0) ; 
. . .
process (Clk)
begin
if rising_edge(Clk) then 
-- Incrementer / Decrementer with unsigned or ufixed.  Result same size
Incrementer_unsigned     <= Incrementer_unsigned + 1 ; 
(Co, Incrementer_ufixed) <= Incrementer_ufixed   + 1 ; 
-- Accumulator with unsigned or ufixed.  Result same size
Accumulate_unsigned      <= Accumulate_unsigned + Next_unsigned ; 
(Co, Accumulate_ufixed)  <= Accumulate_unfixed  + Next_ufixed ; 
-- math unit with full precision.  Result size increases
Sum_unsigned  <= ('0' & A_unsigned) + ('0' & B_unsigned) ; 
Sum_ufixed    <= A_ufixed           +  B_ufixed ; 
end if ; 
end process ; 

因此,对于numeric_std,如果我们为增量器抛出警告,我们会得到许多假阳性警告,并最终忽略所有警告——这将是一个错误。

对于numeric_std,大小调整规则适用于增量器和累加器。结果的大小是预期的。对于Sum_unsigned,我们必须放大一个参数(如果它们大小相同(,我选择了放大两个参数。有一个调整大小的功能,我选择不使用。

对于fixed_pkg,对于增量器和累加器,我们不得不通过使用左侧的聚合来缩小结果以删除进位(此代码为VHDL-2008(。还有一个调整大小的功能可以处理这个问题。对于Sum_ufixed,结果的大小与我们的应用程序相匹配。

这表明,无论您选择哪种规则,编写代码的人都必须做一些事情

对于Sum_ufixed,如果我们有,结果会更加令人兴奋

signal Sum_ufixed10         : ufixed(9 downto 0) ; 
. . . 
Sum_ufixed10 <= (A_ufixed + B_ufixed) + (C_ufixed + D_ufixed) ; 

因为当您遵循规则时,关联性相同表达式的大小最终会大一点。虽然我在下面显示了括号,但它们是一样的。

signal Sum_ufixed11         : ufixed(10 downto 0) ; 
. . . 
Sum_ufixed11 <= ((A_ufixed + B_ufixed) + C_ufixed) + D_ufixed ; 

还要注意,两个包都支持"+"[insigned/ufixed,natural]返回unsigned/uixed,但是,natural参数不影响大小调整。我认为0和1使用起来很简单,但必须仔细检查其他值。如果整数被截断,会有一个警告,但在我看来,它可能应该是一个失败(这与数组值的情况一致(。这当然可以在IEEE工作组中进行讨论(参见http://www.eda-twiki.org/cgi-bin/view.cgi/P1076/WebHome)。

你是对的,关于使用这个运算符的警告会很有帮助。但是,由开发人员决定他们是否需要一个滚动的添加操作,或者一个和溢出会导致不良行为的添加操作。

执行加法时,如果不希望出现溢出,则结果需要比最长的操作数长1位。然后,您可以通过查看最高有效位是否设置为"1"来检查溢出。

相关内容

  • 没有找到相关文章

最新更新