【问题标题】:Why can't I increment this `std_logic_vector`为什么我不能增加这个`std_logic_vector`
【发布时间】:2010-10-25 16:14:56
【问题描述】:

这里发生了什么?为什么我会收到“运算符参数类型不匹配”,我该如何解决?

--
-- 32-bit counter with enable and async reset
--
architecture synthesis1 of counter_32bit is    
signal nextvalue : std_logic_vector ( 31 downto 0 );    
begin

  --
  -- combo
  --
  nextvalue <= value + 1; -- here

  --
  -- sequential
  --
  ff:process( clk, rst )
  begin

    if( rst = '1' ) then
      value <= 0; -- and here...
    elsif( clk'event and ( clk ='1' ) ) then
      if( ena = '1' ) then
         value <= nextvalue;
      end if;
    end if;

  end process ff;    

end synthesis1;

谢谢

【问题讨论】:

  • 对于value的初始化,to_stdlogicvector(bit_vector'(X"0"))X"0"如果模拟器上的-v93开关被轻弹。

标签: vhdl


【解决方案1】:

您不能直接增加 std_logic,您需要使用numeric_std 包将其转换为unsigned 并将结果转换回std_logic_vector

use ieee.numeric_std.all
...
nextvalue <= std_logic_vector( unsigned(value) + 1 );

例如,请参阅How Do Perform STD_LOGIC_VECTOR Addition Using IEEE.NUMERIC_STD

【讨论】:

  • 其实没那么挑剔,其实很明确。 std_logic_vector 只是一个位数组,所以它没有数值。在 VHDL-2008 中有两个包称为 IEEE.Numeric_Std_UnsignedIEEE.Numeric_Std_Signed,它们可以让您直接在 std_logic_vector 上进行算术运算。我不确定我是否认为这是一件好事,因为 VHDL 的强项之一就是明确性。但至少如果你想以 Verilog 风格来做的话,它就在那里。
  • 请注意,VHDL-2008 只添加了 IEEE.numeric_std_unsigned。
  • 转换的问题是您还需要将结果转换回 std_logic_vector ,这非常冗长
【解决方案2】:

另一种方法是重载“+”,在这种情况下你可以这样写:

function "+" ( a : std_logic_vector; b : integer ) return std_logic_vector is
    variable result : unsigned(a'range);
begin
    result := unsigned( a ) + 1 ;
    return std_logic_vector( result ) ;
end function ;

创建一个包并将此函数包含在该包中,这样就可以解决问题。还有一件事包括 ieee numeric_std 包,因为它包含转换函数。

【讨论】:

    【解决方案3】:

    除了已经提供的答案之外,您还可以重写代码,将nextvalue 定义为具有unsigned 数据类型(如下)。注意使用nextvalue &lt;= to_unsigned(0, 32); 清除计数器,使用rising_edge(clk) 触发上升沿。

    -- 32-bit counter with enable and async reset
    architecture synthesis1 of counter_32bit is    
        signal nextvalue : unsigned ( 31 downto 0 );    
    begin
    
        ff:process( clk, rst )
        begin
    
            if( rst = '1' ) then
                nextvalue <= to_unsigned(0, 32); -- reset the count
            elsif rising_edge(clk) then
                if( ena = '1' ) then
                    nextvalue <= nextvalue + 1;  -- increment the count
                end if;
            end if;
    
        end process ff;
    
        -- Concurrent assignment statement
        value <= std_logic_vector(nextvalue);
    
    end synthesis1;
    

    这种形式的并发分配似乎是根据我在书本和网上找到的更新计数器的首选方法。

    另外,如果你继续对nextvalue使用std_logic_vector类型,清除它的首选方法似乎是nextvalue &lt;= (others =&gt; '0');,而不仅仅是nextvalue &lt;= 0;

    【讨论】:

      【解决方案4】:

      简而言之,STD_LOGIC_VECTOR 就是一个比特向量。它本身没有任何意义,因此您不能期望 vhdl 在语义上假设增量操作将对其起作用。此处有关将其转换为无符号的其他帖子应该可以解决问题。

      【讨论】:

        【解决方案5】:

        这也可以:

        nextvalue <= value + '1'; 
        

        不知道你是否真的精通VHDL。如果您使用 std_logic_arith 包,则以下语法在逻辑上是正确的

        【讨论】:

          【解决方案6】:

          试试这个代码:

          use IEEE.STD_LOGIC_ARITH.ALL;
          use IEEE.STD_LOGIC_UNSIGNED.ALL;
          ...
          nextvalue <= value + "1";
          

          在我的情况下,这个解决方案是有效的!

          【讨论】:

            猜你喜欢
            • 2018-05-24
            • 1970-01-01
            • 2016-11-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-03-11
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多