Perché non è possibile incrementare questo `std_logic_vector`
-
21-08-2019 - |
Domanda
Che cosa sta succedendo qui? Perché ricevo un 'operatore tipo di argomento non corrispondente', e cosa posso fare per risolvere il problema?
--
-- 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;
Grazie
Soluzione
Non si può incrementare direttamente std_logic, è necessario convertirlo in unsigned
e il risultato torna a std_logic_vector
utilizzando il pacchetto numeric_std
.
use ieee.numeric_std.all
...
nextvalue <= std_logic_vector( unsigned(value) + 1 );
Vedere Come Eseguire std_logic_vector aggiunta Utilizzando IEEE.NUMERIC_STD per esempio.
Altri suggerimenti
Prova questo codice:
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
...
nextvalue <= value + "1";
Nel mio caso questa soluzione è funziona!
Un altro modo è quello di sovraccaricare il "+" in questo caso è possibile scrivere:
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 ;
creare un pacchetto per inserire questa funzione nel quel pacchetto e questo farà il trucco. Un'altra cosa fare includere il pacchetto numeric_std IEEE perché contiene le funzioni di conversione.
In aggiunta a quanto le risposte già fornite, si potrebbe riscrivere il codice, che definisce nextvalue
come avere unsigned
tipo di dati (qui di seguito). Si noti l'uso di nextvalue <= to_unsigned(0, 32);
per azzerare il contatore, e l'uso di rising_edge(clk)
per innescare fuori di un fronte di salita.
-- 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;
Questa forma di assegnazione concorrente sembra essere il metodo preferito di aggiornare un contatore da quello che ho trovato nei libri e on-line.
Inoltre, se si continua a utilizzare il std_logic_vector
tipo per nextvalue <= (others => '0');
, il metodo preferito per la compensazione sembra essere nextvalue <= 0;
piuttosto che semplicemente <=>.
In poche parole, std_logic_vector è proprio questo, un vettore di bit. Non significa niente per sé, quindi non ci si può aspettare VHDL supporre semanticamente che un'operazione di incremento lavorerà su di esso. Gli altri posti qui circa convertendolo in un unsigned dovrebbe fare il trucco.
Questo funzionerà anche:
nextvalue <= value + '1';
Non so se siete veramente esperto in VHDL. La seguente sintassi ist logicaly corretto se si utilizza il pacchetto std_logic_arith