|
Klasy inżynieria elektroniczna są zwykle podyktowane za pomocą popularne narzędzia, więc zawsze spędzam kilka godzin, szukając pracy wolne oprogramowanie. Z tego powodu postanowiłem podzielić się poniższymi informacjami przewodnik. |
Instalowanie niezbędnych
Do kompilacji i symulacji naszych programów użyjemy GHDL, darmowego kompilatora opartego na GCC. Aby zobaczyć wyniki symulacji, użyjemy GTKWAVE. Jako redaktor polecam Geany, ponieważ rozpoznaje prawie wszystkie języki programowania.
sudo apt-get zainstaluj ghdl gtkwave geany
Przykładowy projekt
Użyjmy tego komparatora jako przykładu:
Przed utworzeniem projektu zacznijmy od utworzenia folderu, w którym będą hostowane wszystkie pliki. W tym przypadku / home / user / vhdl. Tam zapiszemy kod źródłowy naszych programów z rozszerzeniem .vhd.
Następnie piszemy nasz program przy użyciu Geany, jak widać na zrzucie ekranu.
Zapisujemy go jako compare.vhd.
Teraz będziemy musieli stworzyć sygnały do symulacji. Aby to zrobić, utworzymy komponent, który używa poprzedniego bloku i określimy sygnały.
Linie A <= „0011” po 0 ns, „0111” po 5 ns, „0111” po 10 ns; to te, które konfigurują sygnały wejściowe w czasie
Zapisujemy pliki w / home / user / vhdl. Następnie otwieramy terminal i kompilujemy:
ghdl -a porównaj.vhd
Jeśli nie ma komunikatów o błędach, kompilacja zakończyła się pomyślnie.
Teraz kompilujemy „komponent”
ghdl -a compare_tb.vhd
Jeśli nie ma błędów, tworzymy plik wykonywalny:
ghdl -e porównaj_tb
Na koniec pozostaje wykonanie symulacji i zapisanie wyników w nazwie „porównaj.vcd”
ghdl -r porównaj_tb --vcd = porównaj.vcd
Aby zobaczyć wyniki, użyjemy gtkwave:
gtkwave compare.vcd
Po otwarciu użyj klawisza Ctrl i myszy, aby wskazać sygnały, które nas interesują, i naciśnij wstaw. Następnie kliknij dwukrotnie wektory, aby zobaczyć oddzielne sygnały. Następnie kliknij prawym przyciskiem myszy sygnały, aby wybrać format (binarny, szesnastkowy, ósemkowy, dziesiętny itp.)
W razie potrzeby przycisk lupy z kwadratem pośrodku dostosowuje wykres do ekranu.
ALU: jednostka arytmetyczno-logiczna
OK, zróbmy teraz coś bardziej interesującego: ALU (jednostka arytmetyczna i logiczna). Będzie to jednostka logiczna, jednostka arytmetyczna i multiplekser.
Dysk logiczny (LoU.vhdl)
LIBRARY ieee; UŻYJ IEEE.STD_LOGIC_1164.all; UŻYJ IEEE.NUMERIC_STD.all;
ENTITY lou JEST
PORT (op1: IN std_logic_vector (7 DOWNTO 0);
op2: IN std_logic_vector (7 W DÓŁ 0);
proces: IN std_logic_vector (3 W DÓŁ 0);
res: OUT std_logic_vector (7 W DÓŁ 0));
KONIEC lou;
ARCHITEKTURA synth2 OF lou IS
SIGNAL a, b: UNSIGNED (op1'range);
SIGNAL c: UNSIGNED (zmień zakres);
ZACZYNAĆ
PROCES (a, b, proces)
ZACZYNAĆ
CASE proces JEST
KIEDY "0000" => c <= ZMIEŃ ROZMIAR ((nie a), c'length);
KIEDY "0001" => c <= ZMIEŃ ROZMIAR ((a i b), c'length);
KIEDY "0010" => c <= ZMIEŃ ROZMIAR ((a lub b), c'length);
KIEDY "0011" => c <= ZMIEŃ ROZMIAR ((a xor b), c'length);
KIEDY "0100" => c <= ZMIEŃ ROZMIAR ((a nand b), c'length);
KIEDY "0101" => c <= ZMIEŃ ROZMIAR ((a ani b), c'length);
KIEDY INNE => null;
KOŃCÓWKA;
KONIEC PROCESU;
a <= UNSIGNED (op1);
b <= UNSIGNED (op2);
res <= std_logic_vector (c);
KONIEC syntezatora2;
Jednostka arytmetyczna (ArU.vhd)
LIBRARY ieee; UŻYJ IEEE.STD_LOGIC_1164.all; UŻYJ IEEE.NUMERIC_STD.all;
ENTITY aru JEST
PORT (op1: IN std_logic_vector (7 DOWNTO 0);
op2: IN std_logic_vector (7 W DÓŁ 0);
proces: IN std_logic_vector (3 W DÓŁ 0);
res: OUT std_logic_vector (7 W DÓŁ 0));
KONIEC;
ARCHITEKTURA syntezator aru IS
SIGNAL a, b: UNSIGNED (op1'range);
SIGNAL c: UNSIGNED (zmień zakres);
ZACZYNAĆ
PROCES (a, b, proces)
ZACZYNAĆ
CASE proces JEST
KIEDY "0000" => c <= ZMIEŃ ROZMIAR ((a + b), c'length);
KIEDY "0001" => c <= ZMIEŃ ROZMIAR ((a - b), c'length);
KIEDY "0010" => c <= ZMIEŃ ROZMIAR ((a * b), c'length);
KIEDY "0011" => c <= ZMIEŃ ROZMIAR ((a / b), c'length);
KIEDY "0100" => c <= ZMIEŃ ROZMIAR ((a + "1"), c'length);
KIEDY "0101" => c <= ZMIEŃ ROZMIAR ((b + "1"), c'length);
KIEDY INNE => null;
KOŃCÓWKA;
KONIEC PROCESU;
a <= UNSIGNED (op1);
b <= UNSIGNED (op2);
res <= std_logic_vector (c);
END syntezator;
Multiplekser (muxVector.vhd)
LIBRARY ieee; UŻYJ IEEE.STD_LOGIC_1164.all; UŻYJ IEEE.NUMERIC_STD.all;
ENT. muxVector JEST
PORT (z ARU: IN std_logic_vector (7 W DÓŁ 0);
fromLOU: IN std_logic_vector (7 DOWNTO 0);
przełącznik: IN std_logic;
wyjście: out std_logic_vector (7 DOWNTO 0));
KONIEC muxVector;
ARCHITEKTURA zmiana muxVector IS
ZACZYNAĆ
za pomocą przełącznika wyboru
wyjście <= z ARU, gdy '0', z LOU, gdy inni;
KONIEC zmiana;
Komponent ALU (aluComponent.vhd)
LIBRARY ieee; UŻYJ IEEE.STD_LOGIC_1164.all; UŻYJ IEEE.NUMERIC_STD.all;
ENTITY alu Component IS
END aluComponent;
ARCHITEKTURA input_aluComponent OF aluComponent IS
KOMPONENT aru
PORT (op1: IN std_logic_vector (7 DOWNTO 0);
op2: IN std_logic_vector (7 W DÓŁ 0);
proces: IN std_logic_vector (3 W DÓŁ 0);
res: OUT std_logic_vector (7 W DÓŁ 0));
KOMPONENT KOŃCOWY;
KOMPONENT lou
PORT (op1: IN std_logic_vector (7 DOWNTO 0);
op2: IN std_logic_vector (7 W DÓŁ 0);
proces: IN std_logic_vector (3 W DÓŁ 0);
res: OUT std_logic_vector (7 W DÓŁ 0));
KOMPONENT KOŃCOWY;
SKŁADNIK muxVector
PORT (z ARU: IN std_logic_vector (7 W DÓŁ 0);
fromLOU: IN std_logic_vector (7 DOWNTO 0);
przełącznik: IN std_logic;
wyjście: out std_logic_vector (7 DOWNTO 0));
KOMPONENT KOŃCOWY;
SIGNAL outputARU: std_logic_vector (7 DOWNTO 0);
SIGNAL outputLOU: std_logic_vector (7 DOWNTO 0);
Przełącznik sygnału: std_logic;
proces sygnału: std_logic_vector (3 DOWNTO 0);
wyjście sygnału: std_logic_vector (7 DOWNTO 0);
SYGNAŁ A: std_logic_vector (7 W DÓŁ 0);
SIGNAL B: std_logic_vector (7 W DÓŁ 0);
ZACZYNAĆ
u0: aru MAPA PORTU (A, B, proces, wyjście ARU);
u1: lou MAPA PORTU (A, B, proces, wyjście LOU);
u2: muxVector PORT MAP (outputARU, outputLOU, switch, output);
A <= „00000011” po 0 ns, „00000111” po 5 ns, „00000111” po 10 ns, „00001001” po 15 ns, „00000000” po 20 ns, „00000101” po 25 ns, „00001111” po 30 ns ns, „00000101” po 35 ns;
B <= „00000010” po 0 ns, „00000100” po 5 ns, „00000010” po 10 ns, „00000011” po 15 ns, „00000100” po 20 ns, „00000110” po 25 ns, „00001111” po 30 ns ns, „00000011” po 35 ns;
zmiana <= '1' po 0 ns, '0' po 5 ns, '1' po 10 ns, '0' po 15 ns, '1' po 20 ns, '0' po 25 ns, '1' po 30 ns, „0 ′ po 35 ns,„ 1 ′ po 40 ns;
proces <= „0000” po 0 ns, „0001” po 5 ns, „0010” po 10 ns, „0011” po 15 ns, „0100” po 20 ns, „0101” po 25 ns, „0110” po 30 ns;
END input_aluComponent;
Aby nie tracić czasu na kompilowanie polecenia komendą podczas pracy nad programem, w tym samym folderze zapisujemy plik o nazwie compilar.sh z następującą zawartością:
ghdl -a lou.vhd && ghdl -a aru.vhd && ghdl -a muxVector.vhd && ghdl -a aluComponente.vhd && ghdl -e aluComponente && ghdl -r aluComponent --vcd = alu & componente.wave
Otwórz terminal, wejdź do folderu i uruchom skrypt:
cd / home / user / vhdl sh compile.sh
Jeśli nie ma błędów, to gtkwave się otworzy i możemy zobaczyć sygnały:
Narzędzia te były bardzo przydatne i łatwiejsze w użyciu niż zastrzeżone narzędzia, których używamy na zajęciach, których kompilacja jest podejrzanie zbyt długa. W przypadku ghdl przełączanie okien trwa dłużej niż kompilacja.
Więcej informacji o VHDL
Dla nowych użytkowników vhdl, tutaj mają podstawowy przykład deniera.
Przykładowe wideo:
http://www.youtube.com/watch?v=feVMXsyLSOU
Pamiętaj, że najnowsze wersje Ubuntu nie mają GHDL w swoich repozytoriach. Można to pobrać dla systemu Linux / Windows ze strony projektu:
http://ghdl.free.fr/site/pmwiki.php?n=Main.Download




