Mam sygnał wejściowy z konwertera ADC, który ma 8 bitów (std_logic_vector(7 downto 0)
). Muszę przekonwertować je na sygnał 16-bitowy (std_logic_vector(15 downto 0
)) dla 16 bitowego przetwarzania sygnału do systemu 16-bitowego.Jak przekonwertować 8 bitów na 16 bitów w VHDL?
Odpowiedz
Jeśli wartość 8-bitowy jest interpretowany jako podpisany (2 dopełnienie), a następnie generał i standardowa metoda konwersji VHDL jest użycie IEEE biblioteki numeric_std:
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;
Więc najpierw std_logic_vector przekształca do wartości podpisanej, następnie zostanie zastosowana zmiana rozmiaru, która spowoduje podpisanie przedłużenia podpisanej wartości, a wynik zostanie ostatecznie przekształcony z powrotem na std_logic_vector.
Konwersja jest dość długa, ale ma tę zaletę, że jest ogólna i działa nawet wtedy, gdy docelowa długość zostanie później zmieniona.
Atrybut „długość prostu zwraca długość std_logic_vector slv_16, a więc 16.
Dla unsigned reprezentacji zamiast podpisane, można to zrobić za pomocą unsigned
zamiast signed
, co z tym kodem:
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;
Co to jest „X” w wierszu 5 oznacza? –
"X" jest dla "szesnastkowego". Więc x "00" to w zasadzie binarny "00000000". – Passepartout
Jeśli chcę przekonwertować "11111111" na "1111111111111111" –
Dla kompletności, jeszcze inny sposób, który jest czasami przydatne:
-- 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;
ja nie mam musiałem to zrobić dla wektorów, które pamiętam, ale potrzebowałem tego w bardziej złożonych okolicznościach: skopiowanie tylko kilku istotnych sygnałów do większego, bardziej złożonego zapisu było jednym razem.
Rozszerzenie znaku jest wykonywane z pierwszym przypisem jako slv_16 <= (others => slv_8 (7)); ' –
To jest poprawne funkcjonalnie, ale uważam, że jeśli chcesz rozszerzyć znak, powinieneś używać odpowiednich typów liczbowych (np. signed'), a następnie za pomocą funkcji 'resize' - jak zaproponowałeś w swojej odpowiedzi :) –
ten obsługuje konwersję bez konieczności edytowania Szerokości zer albo jeżeli zmiany 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;
Próbowałem zmienić rozmiar z 16 na 8 bitów jako: resized_var1: = std_logic_vector (zmiana rozmiaru (unsigned (Kp) * unsigned (integration1)), 8); Otrzymałem błąd w następujący sposób: "Konwersja typów (na std_logic_vector) nie może mieć argumentu agregującego." Dlaczego to nie działa? –
Ponieważ, 8 powinno znajdować się wewnątrz parens dla resize(), a nie std_logic_vector(). –