Ho un segnale di ingresso dal convertitore ADC che è 8 bit (std_logic_vector(7 downto 0)
). Devo convertirli in un segnale a 16 bit (std_logic_vector(15 downto 0
) per l'elaborazione del segnale a 16 bit sul sistema a 16 bit.Come convertire 8 bit in 16 bit in VHDL?
risposta
Se il valore a 8 bit viene interpretato come segno (complemento a 2), quindi il metodo di conversione VHDL generale e standard è quello di utilizzare la libreria numeric_std IEEE:
library ieee;
use ieee.numeric_std.all;
architecture sim of tb is
signal slv_8 : std_logic_vector(8 - 1 downto 0);
signal slv_16 : std_logic_vector(16 - 1 downto 0);
begin
slv_16 <= std_logic_vector(resize(signed(slv_8), slv_16'length));
end architecture;
Quindi, prima la std_logic_vector viene convertito a un valore con segno, quindi viene applicato il ridimensionamento, che firmerà estendere il valore firmato e il risultato verrà infine riconvertito in std_logic_vector.
La conversione è piuttosto lunga, ma ha il vantaggio che è generale e funziona anche se la lunghezza obiettivo viene modificata in seguito.
L'attributo 'lunghezza restituisce semplicemente la lunghezza del std_logic_vector slv_16, quindi 16.
Per rappresentazione senza segno anziché firmata, può essere fatto utilizzando unsigned
anziché signed
, quindi con questo codice:
slv_16 <= std_logic_vector(resize(unsigned(slv_8), slv_16'length));
architecture RTL of test is
signal s8: std_logic_vector(7 downto 0);
signal s16: std_logic_vector(15 downto 0);
begin
s16 <= X"00" & s8;
end;
Qual è 'X' in linea 5 significa? –
La 'x' è per "esadecimale". Quindi x "00" è un binario di base "00000000". – Passepartout
Se voglio convertire "11111111" in "1111111111111111" –
Per completezza, ancora un altro modo, che è a volte utile:
-- Clear all the slv_16 bits first and then copy in the bits you need.
process (slv_8)
begin
slv_16 <= (others => '0');
slv_16(7 downto 0) <= slv_8;
end process;
non ho dovevo fare questo per i vettori che posso ricordare, ma ho avuto bisogno di questo in circostanze più complesse: copiare solo alcuni segnali rilevanti in un disco più grande, più complesso, era una volta.
E l'estensione del segno viene eseguita con il primo assegnamento come 'slv_16 <= (others => slv_8 (7));' –
Questo è corretto dal punto di vista funzionale, ma direi che se si desidera l'estensione di segno, si dovrebbero usare i tipi numerici appropriati (es. signed') e quindi usando la funzione 'resize' - come hai proposto nella tua risposta :) –
Questo gestisce la conversione senza dover modificare la larghezza degli zeri se uno cambia std_logic_vector:
architecture RTL of test is
signal s8: std_logic_vector(7 downto 0);
signal s16: std_logic_vector(15 downto 0) := (others => '0');
begin
s16(s8'range) <= s8;
end;
Stavo cercando di ridimensionare da 16 a 8 bit come: resized_var1: = std_logic_vector (ridimensiona (senza segno (Kp) * senza segno (integrazione1)), 8); Stavo ricevendo errore come: "Digitare la conversione (in std_logic_vector) non può avere un operando aggregato." Perché non funziona? –
Dato che, 8 dovrebbe essere all'interno del paren per ridimensionare() e non per std_logic_vector(). –