Почему я не могу увеличить этот `std_logic_vector`
Что здесь происходит? Почему я получаю "несоответствие типа аргументов оператора" и что я могу сделать, чтобы исправить его?
--
-- 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;
Спасибо
Ответы
Ответ 1
вы не можете напрямую увеличить std_logic, вам нужно преобразовать его в unsigned
, а результат вернуться к std_logic_vector
с помощью пакета numeric_std
.
use ieee.numeric_std.all
...
nextvalue <= std_logic_vector( unsigned(value) + 1 );
См. Например, если вы выполняете дополнение STD_LOGIC_VECTOR с помощью IEEE.NUMERIC_STD.
Ответ 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 ;
создайте пакет и включите эту функцию в этот пакет, и это сделает трюк. Еще одна вещь включает в себя пакет ieie numeric_std, поскольку он содержит функции преобразования.
Ответ 3
В дополнение к тому, что уже предоставлены ответы, вы можете переписать код, указав nextvalue
как имеющий тип данных unsigned
(см. ниже). Обратите внимание на использование nextvalue <= 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;
Эта форма параллельного присваивания представляется предпочтительным методом обновления счетчика от того, что я нашел в книгах и в Интернете.
Кроме того, если вы продолжаете использовать тип std_logic_vector
для nextvalue
, предпочтительным методом его очистки является nextvalue <= (others => '0');
, а не только nextvalue <= 0;
.
Ответ 4
В двух словах STD_LOGIC_VECTOR - это просто вектор бит. Это само по себе ничего не значит, поэтому вы не можете ожидать, что vhdl семантически предположит, что на нем будет работать операция увеличения. Другие сообщения здесь о преобразовании его в unsigned должны делать трюк.
Ответ 5
Попробуйте этот код:
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
...
nextvalue <= value + "1";
В моем случае это решение работает!
Ответ 6
Это также будет работать:
nextvalue <= value + '1';
Не знаю, действительно ли вы хорошо разбираетесь в VHDL. Следующий синтаксис ist логически корректен, если вы используете пакет std_logic_arith