Klasat e Inxhinieri elektronike zakonisht diktohen duke përdorur mjete popullore, kështu që unë gjithmonë kaloj disa orë në kërkim për të bërë punën time me të software të lirë. Për këtë arsye, unë kam vendosur të ndaj sa vijon udhëheq. |
Instalimi i nevojshëm
Për të përpiluar dhe simuluar programet tona, ne do të përdorim GHDL, një përpilues falas i bazuar në GCC. Për të parë rezultatet e simulimit, ne do të përdorim GTKWAVE. Si redaktor rekomandoj Geany pasi njeh pothuajse të gjitha gjuhët e programimit.
sudo apt-get instalo ghdl gtkwave geany
Një projekt shembull
Le të përdorim këtë krahasues si një shembull:
Para se të krijoni një projekt, le të fillojmë duke krijuar një dosje ku do të strehohen të gjithë skedarët. Në këtë rast, / shtëpi / përdorues / vhdl. Aty do të ruajmë kodin burimor të programeve tona me një shtrirje .vhd.
Pastaj ne shkruajmë programin tonë duke përdorur Geany, siç shihet në screenshot.
Ne e ruajmë atë si krahasim.vhd.
Tani do të duhet të krijojmë sinjalet për simulimin. Për ta bërë këtë, ne do të krijojmë një komponent që përdor bllokun e mëparshëm dhe ne do të specifikojmë sinjalet.
Linjat A <= "0011" pas 0 ns, "0111" pas 5 ns, "0111" pas 10 ns; janë ato që konfigurojnë sinjalet hyrëse në kohë
Ne i ruajmë skedarët në / shtëpi / përdorues / vhdl. Pastaj, ne hapim një terminal dhe përpilojmë:
ghdl -a krahasuar.vhd
Nëse nuk ka mesazhe gabimi, përpilimi është i suksesshëm.
Tani ne përpilojmë "përbërësin"
ghdl -a krahasoni_tb.vhd
Nëse nuk ka gabime, ne krijojmë të ekzekutueshmen:
ghdl -e krahasoj_tb
Më në fund, mbetet të kryejmë simulimin dhe të ruajmë rezultatet në atë të quajtur "krahaso.vcd"
ghdl -r krahasoni_tb --vcd = krahasoni.vcd
Për të parë rezultatet do të përdorim gtkwave:
krahasoni gtkwave.vcd
Pasi të hapet, përdorni tastin Ctrl dhe miun për të treguar sinjalet që na interesojnë dhe shtypni insert. Pastaj klikoni dy herë në vektorë për të parë sinjalet e ndara. Pastaj, kliko me të djathtën mbi sinjalet për të zgjedhur formatin (binar, magji, oktal, dhjetor, etj.)
Nëse është e nevojshme, butoni i lupës me një katror në qendër rregullon grafikun në ekran.
ALU: njësia aritmetike dhe logjike
Mirë, tani le të bëjmë diçka më interesante: një ALU (njësia aritmetike dhe logjike). Do të jetë një njësi logjike, një njësi aritmetike dhe një multiplekser.
Makinë logjike (LoU.vhdl)
BIBLIOTEKA dmth; PERDORIM IEEE.STD_LOGIC_1164.all; PERDORIM IEEE.NUMERIC_STD.të gjitha;
ENTITY është IS
PORTI (op1: IN std_logic_vector (7 DOWNTO 0);
op2: IN std_logic_vector (7 DOWNTO 0);
procesi: N st std_logic_vector (3 DOWNTO 0);
res: OUT std_logic_vector (7 DOWNTO 0));
FUND lou;
ARKITEKTURA synth2 E LOU IS
SIGNAL a, b: E PAGUAR (op1'range);
SIGNALI c: I PA FENJUAR (rigjenerim);
BEGIN
PROCESI (a, b, procesi)
BEGIN
RASTI proces është
KUR "0000" => c <= RREGULLONI ((jo a), gjatësia c);
KUR "0001" => c <= RREGULLONI ((a dhe b), gjatësia c);
KUR "0010" => c <= RREGULLONI ((a ose b), gjatësia c);
KUR "0011" => c <= RREGULLONI ((a xor b), gjatësia c);
KUR "0100" => c <= RREGULLONI ((a nand b), gjatësia c);
KUR "0101" => c <= RREGULLONI ((a as b), gjatësia c);
KUR T O TJERT => nul;
RASTI I FUNDIT;
PROCESI FUND;
a <= E PAGUAR (op1);
b <= I PAFENGUAR (op2);
res <= std_logic_vector (c);
FUND synth2;
Njësia aritmetike (ArU.vhd)
BIBLIOTEKA dmth; PERDORIM IEEE.STD_LOGIC_1164.all; PERDORIM IEEE.NUMERIC_STD.të gjitha;
ENTITY aru ËSHTË
PORTI (op1: IN std_logic_vector (7 DOWNTO 0);
op2: IN std_logic_vector (7 DOWNTO 0);
procesi: N st std_logic_vector (3 DOWNTO 0);
res: OUT std_logic_vector (7 DOWNTO 0));
FUND aru;
ARKITEKTURA sinti i aru IS
SIGNAL a, b: E PAGUAR (op1'range);
SIGNALI c: I PA FENJUAR (rigjenerim);
BEGIN
PROCESI (a, b, procesi)
BEGIN
RASTI proces është
KUR "0000" => c <= RREGULLONI ((a + b), gjatësia c);
KUR "0001" => c <= RREGULLONI ((a - b), gjatësia c);
KUR "0010" => c <= RREGULLONI ((a * b), gjatësia c);
KUR "0011" => c <= RREGULLONI ((a / b), gjatësia c);
KUR "0100" => c <= RREGULLONI ((a + "1"), gjatësia c);
KUR "0101" => c <= RREGULLONI ((b + "1"), gjatësia c);
KUR T O TJERT => nul;
RASTI I FUNDIT;
PROCESI FUND;
a <= E PAGUAR (op1);
b <= I PAFENGUAR (op2);
res <= std_logic_vector (c);
Sinteti përfundimtar;
Multiplekseri (muxVector.vhd)
BIBLIOTEKA dmth; PERDORIM IEEE.STD_LOGIC_1164.all; P USRDORI IEEE.NUMERIC_STD.të gjitha;
ENTITY muxVektori ËSHTË
PORTI (nga ARU: IN std_logic_vector (7 DOWNTO 0);
ngaLOU: IN std_logic_vector (7 SHKEL 0);
kaloni: N st std_logic;
dalja: jashtë std_logic_vector (7 SHKEL 0));
MuxVektori FUND;
ARKITEKTURA ndryshimi i IS muxVector
BEGIN
me zgjedh ndërprerësin
dalja <= nga ARU kur '0', nga LOU kur të tjerët;
Ndryshimi i FUNDIT;
Komponenti ALU (aluComponent.vhd)
BIBLIOTEKA dmth; PERDORIM IEEE.STD_LOGIC_1164.all; P USRDORI IEEE.NUMERIC_STD.të gjitha;
ENTITY alu Komponenti është
FUND aluKomponenti;
ARKITEKTURA inputs_aluPërbërësi i aluKomponenti IS
KOMPONENTI aru
PORTI (op1: IN std_logic_vector (7 DOWNTO 0);
op2: IN std_logic_vector (7 DOWNTO 0);
procesi: N st std_logic_vector (3 DOWNTO 0);
res: OUT std_logic_vector (7 DOWNTO 0));
KOMPONENTA E FUNDIT;
Lou komponent
PORTI (op1: IN std_logic_vector (7 DOWNTO 0);
op2: IN std_logic_vector (7 DOWNTO 0);
procesi: N st std_logic_vector (3 DOWNTO 0);
res: OUT std_logic_vector (7 DOWNTO 0));
KOMPONENTA E FUNDIT;
KOMPONENTI muxVector
PORTI (nga ARU: IN std_logic_vector (7 DOWNTO 0);
ngaLOU: IN std_logic_vector (7 SHKEL 0);
kaloni: N st std_logic;
dalja: jashtë std_logic_vector (7 SHKEL 0));
KOMPONENTA E FUNDIT;
Dalja SIGNALEARU: std_logic_vector (7 SHKEL 0);
Dalja SIGNALELOU: std_logic_vector (7 DOWNTO 0);
Ndërprerësi i sinjalit: std_logic;
procesi i sinjalit: std_logic_vector (3 DOWNTO 0);
dalja e sinjalit: std_logic_vector (7 DOWNTO 0);
SIGNAL A: std_logic_vector (7 SHKEL 0);
SIGNAL B: std_logic_vector (7 SHKEL 0);
BEGIN
u0: aru PORT MAP (A, B, procesi, dalja ARU);
u1: LOU PORT MAP (A, B, procesi, dalja LOU);
u2: Harta e portit muxVector (outputARU, outputLOU, çelësi, dalja);
A <= "00000011" pas 0 ns, "00000111" pas 5 ns, "00000111" pas 10 ns, "00001001" pas 15 ns, "00000000" pas 20 ns, "00000101" pas 25 ns, "00001111" pas 30 ns, "00000101" pas 35 ns;
B <= "00000010" pas 0 ns, "00000100" pas 5 ns, "00000010" pas 10 ns, "00000011" pas 15 ns, "00000100" pas 20 ns, "00000110" pas 25 ns, "00001111" pas 30 ns, "00000011" pas 35 ns;
kaloni <= '1' pas 0 ns, '0 ′ pas 5 ns,' 1 ′ pas 10 ns, '0' pas 15 ns, '1 ′ pas 20 ns,' 0 ′ pas 25 ns, '1 ′ pas 30 ns, '0' pas 35 ns, '1' pas 40 ns;
procesi <= "0000" pas 0 ns, "0001" pas 5 ns, "0010" pas 10 ns, "0011" pas 15 ns, "0100" pas 20 ns, "0101" pas 25 ns, "0110" pas 30 ns;
Inputet_përfundimtare_përbërësi;
Për të mos humbur kohë duke përpiluar komandën me komandë gjatë punës në program, ne ruajmë një skedar të quajtur compilar.sh me përmbajtjen vijuese në të njëjtën dosje:
ghdl -a lou.vhd && ghdl -a aru.vhd && ghdl -a muxVector.vhd && ghdl -a aluComponente.vhd && ghdl -e aluKomponenti && ghdl -r aluKomponenti --vcd = alu & ghdlwave
Hapni një terminal, futni dosjen dhe ekzekutoni skenarin:
cd / home / user / vhdl sh përpilim.sh
Nëse nuk ka gabime, gtkwave do të hapet dhe ne do të jemi në gjendje të shohim sinjalet:
Këto mjete kanë qenë shumë të dobishme dhe më të lehta për t'u përdorur sesa mjetet e pronarit që ne përdorim në klasë, të cilat me dyshim kërkojnë shumë kohë për t'u përpiluar. Me ghdl duhet më shumë kohë për të ndërruar dritaret sesa për të përpiluar.
Më shumë informacion rreth VHDL
Për ata të rinj në vhdl, këtu ata kanë një shembull themelor të një mohuesi.
Një video shembull:
http://www.youtube.com/watch?v=feVMXsyLSOU
Mos harroni se versionet e fundit të Ubuntu nuk kanë GHDL në depot e tyre. Kjo mund të shkarkohet për Linux / Windows nga faqja e projektit:
http://ghdl.free.fr/site/pmwiki.php?n=Main.Download
A ka ndonjë mënyrë që GTKWave t'ju japë qarkun e portës që përfaqëson?