【问题标题】:Arithmetic mean of a register in vhdlvhdl中寄存器的算术平均值
【发布时间】:2017-05-17 08:47:29
【问题描述】:

对于我目前正在进行的一个项目,我正在尝试获取一些输入,将它们存储在一个寄存器中,然后找到该寄存器的算术平均值。我所有的输入都是 24 位长的。我的寄存器是 4 输入长,因此我只需删除最低有效位的最后 3 位,同时将它们除以 4 以计算算术平均值,然后简单地将它们相加。

mean 是我的register(95 downto 0) (4 x 24 = 96),mean_medium 是类型 unsigned。

当我编写以下代码时

signal mean_medium : unsigned (23 downto 0) := (others => '0');
mean_medium <= unsigned(medium (95 downto 75)) +
               unsigned(medium (71 downto 51)) +
               unsigned(medium (47 downto 27)) +
               unsigned(medium (23 downto 3)) ;

我收到以下警告:

宽度不匹配。 mean_medium 的宽度为 24 位,但分配的表达式为 21 位。

您有什么建议可以解决这个问题吗?

【问题讨论】:

    标签: vhdl fpga xilinx xilinx-ise digital-logic


    【解决方案1】:

    一个错误已经是您通过移动 3 位来除以 4。你只需要移动 2 位。

    但对于正确/精确的算术,您应该不预先移动该表达式的操作符,因为您会因截断而失去精度。首先将所有 4 个完整的 24 位值添加到一个 26 位输出。然后对输出进行移位和舍入。示例

    signal mean_medium : unsigned (23 downto 0); -- redundant := (others => '0');
    signal mean_temp : unsigned(25 downto 0);
    
    mean_temp <=
        resize(unsigned(medium (95 downto 72)), mean_Temp'length) +
        resize(unsigned(medium (71 downto 48)), mean_Temp'length) +
        resize(unsigned(medium (47 downto 24)), mean_Temp'length) +
        resize(unsigned(medium (23 downto 0)), mean_Temp'length) +
        2; -- round factor
    
    mean_medium <= shift_right(mean_temp, 2); --divide by 4
    

    附言您也可以将其组合在一行中,从而消除 mean_temp 的必要性。

    【讨论】:

      【解决方案2】:

      我假设您使用的是numeric_std 包。

      在numeric_std 包中,+ 运算符要求求和的宽度与最宽的操作数的宽度相同。你的操作数是 21 位宽,你的总和是 24 位宽。因此,您也需要将操作数设为 24 位宽。您可以使用numeric_std 中的resize 函数来执行此操作。其实这样就足够了:

      mean_medium <= resize(unsigned(medium (95 downto 75)),24) +
                     unsigned(medium (71 downto 51)) +
                     unsigned(medium (47 downto 27)) +
                     unsigned(medium (23 downto 3)) ;
      

      但如果您认为它更整洁,您也可以这样做:

      mean_medium <= resize(unsigned(medium (95 downto 75)),24) +
                     resize(unsigned(medium (71 downto 51)),24) +
                     resize(unsigned(medium (47 downto 27)),24) +
                     resize(unsigned(medium (23 downto 3)) ,24) ;
      

      或者对此进行一些变化会更好:

      mean_medium <= resize(unsigned(medium (95 downto 75)),mean_medium'length) +
                     unsigned(medium (71 downto 51)) +
                     unsigned(medium (47 downto 27)) +
                     unsigned(medium (23 downto 3)) ;
      

      【讨论】:

        【解决方案3】:

        等式的两边应该有相同的大小,你可以使用 resize 函数或者你可以使用一个 24 位的临时信号并这样做:

        signal temp : std_logic_vector(23 downto 0); temp(23 downto 21) <= "000"; temp(20 downto 0) <= medium (95 downto 75); mean_medium <= temp + ....

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-10-17
          • 2011-12-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-01
          相关资源
          最近更新 更多