Por que não pode incrementar esta `std_logic_vector`
-
21-08-2019 - |
Pergunta
O que está acontecendo aqui? Por que estou recebendo um 'operador tipo de argumento incompatibilidade', eo que posso fazer para corrigir isso?
--
-- 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;
Graças
Solução
Você pode std_logic não incremento diretamente, você precisa convertê-lo para unsigned
e as costas resultado para std_logic_vector
usando o pacote numeric_std
.
use ieee.numeric_std.all
...
nextvalue <= std_logic_vector( unsigned(value) + 1 );
Veja Como Realizar std_logic_vector Adição Usando IEEE.NUMERIC_STD por exemplo.
Outras dicas
Tente este código:
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
...
nextvalue <= value + "1";
No meu caso esta solução é obras!
Uma mais maneira é sobrecarregar o "+", neste caso, você pode escrever:
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 ;
criar um pacote e incluir esta função no pacote e isso vai fazer o truque. Só mais uma coisa que inclui o pacote numeric_std IEEE, pois contém as funções de conversão.
Além do que as respostas já fornecidas, você poderia reescrever o código, definindo nextvalue
como tendo o tipo de dados unsigned
(abaixo). Observe o uso de nextvalue <= to_unsigned(0, 32);
para limpar o balcão, e o uso de rising_edge(clk)
para desencadear de uma borda de subida.
-- 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;
Esta forma de atribuição simultânea parece ser o método preferido de atualizar um contador do que tenho encontrado em livros e online.
Além disso, se você continuar a usar o tipo std_logic_vector
para nextvalue
, o método preferido para limpá-lo parece ser nextvalue <= (others => '0');
ao invés de apenas nextvalue <= 0;
.
Em poucas palavras, std_logic_vector é apenas isso, um vetor de bits. Não significa nada por si só para que você não pode esperar VHDL para assumir semanticamente que uma operação de incremento irá trabalhar nele. Os outros posts aqui sobre convertê-lo para um sem assinatura deve fazer o truque.
Esta será também trabalho:
nextvalue <= value + '1';
Não sei se você está realmente bem versado em VHDL. A sintaxe a seguir é logicamente correta se você estiver usando o pacote std_logic_arith