Question

What's going on here? Why am I getting an 'operator argument type mismatch', and what can I do to fix it?

--
-- 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;

Thanks

Was it helpful?

Solution

you can't increment std_logic directly, you need to convert it to unsigned and the result back to std_logic_vector using the numeric_std package.

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

See How Do Perform STD_LOGIC_VECTOR Addition Using IEEE.NUMERIC_STD for example.

OTHER TIPS

Try this code:

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

In my case this solution is works!

One more way is to overload the "+" in this case you can write:

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 ;

create a package and include this function in that package and this will do the trick . One more thing do include the ieee numeric_std package because it contains the conversion functions.

In addition to what the answers already provided, you could rewrite the code, defining nextvalue as having unsigned data type (below). Note the use of nextvalue <= to_unsigned(0, 32); to clear the counter, and the use of rising_edge(clk) to trigger off of a rising edge.

-- 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;

This form of concurrent assignment seems to be the preferred method of updating a counter from what I have found in books and online.

Also, if you continue to use the std_logic_vector type for nextvalue, the preferred method for clearing it seems to be nextvalue <= (others => '0'); rather than just nextvalue <= 0;.

In a nutshell, STD_LOGIC_VECTOR is just that, a vector of bits. It means nothing by itself so you cannot expect vhdl to semantically assume that an increment operation will work on it. The other posts here about converting it to an unsigned should do the trick.

This will also work:

nextvalue <= value + '1'; 

Dont know if you are really well versed in VHDL. The following syntax ist logicaly correct if you are using std_logic_arith package

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top