V:1.1 VHDL och laborationer i digitalteknik Vid laborationskursen i digitalteknik används VHDL till alla laborationerna utom den första. VHDL är ett stort språk och enbart en liten del av språket behövs för att gör laborationerna. Det mesta av teorin för VHDL-delen finns beskrivet i laboration 2 och 4. I den här presentationen finns ytterligare några råd och en mycket kortfattad introduktion till VHDL. VHDL (VHSIC Hardware Description Language) VHSIC (Very High SpeedIntegrated circuit) Verilog är ett liknande språk VHDL är en IEEE-standard som revideras med jämna mellanrum VHDL87, VHDL93, VHDL2001,.. V:1.2 VHDL är ett simulatorspråk som beskriver digitala modeller. Modellerna kan kompileras och studeras med olika typer av simulatorer. VHDL innehåller ingen standard för att beskriva hårdvara. VHDL är en händelsestyrd simulator där varje händelse är knuten till tid. För att köa upp samtidiga händelser används deltafördröjningar. Deltafördröjningarna bestämmer i vilken ordning samtidiga händelser skall utföras men de motsvarar ingen verklig tid. VHDL och liknade språk används numera nästan alltid vid konstruktion av digital logik. Vid konstruktion av hårdvara med VHDL kan enbart en delmängd av VHDL användas och det finns bestämda regler för hur vissa konstruktioner skall beskrivas. Att översätta VHDL till hårdvara kallas syntes.
Källkod för ett VHDL-program, exempel: library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity ex1 is port (signal a,b,c :in std_logic; signal u: out std_logic ); end ex1; architecture rtl of ex1 is signal u_b: std_logic; u <= u_b or c; u_b <= a and b; end rtl; V:1.3 Källkoden består av 3 delar: Specifikation av vilka bibliotek och packages som används. entity med deklaration av in- och utgångar. architecture som beskriver beteendet V:1.4 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; Alla VHDLprogram vid laborationerna måste innehålla Biblioteket IEEE Package IEEE.STD_LOGIC_1164.ALL Övriga package kan tillkomma vid behov, se exemplet ovan Kommentarer inleds med -- VHDL skiljer inte mellan stora och små bokstäver (Undantag Z )
V:1.5 entity ex1 is port (a,b,c :in std_logic; u: out std_logic ); end ex1; Under entity deklareras vilka externa anslutningar som modellen skall ha. Objekten a, b, c och u är av klassen signal, datatypen std_logic, mode in respektive out. Under laborationskursen kommer ofta datatypen std_logic_vector att användas. För övrigt får inga andra modes, klasser eller datatyper användas. OBS utsignaler kan enbart tilldelas värde (u i detta fall) insignaler kan enbart läsas (a, b och c) Att skriva en entity är alltid mycket enkelt. Enbart in- och utsignaler skall deklareras. V:1.6 architecture rtl of ex1 is signal u_b: std_logic; u <= u_b or c; u_b <= a and b; end rtl; Under architecture definieras konstruktionens beteende. Innan första kan ytterligare deklarationer göras. I detta fall deklareras en intern signal u_b. Den interna signalen kan både läsas och skrivas och den är praktisk som en dummy signal i många fall. Mellan architecturens -end finns de exekverbara satserna. I exemplet används de logiska operatorerna or och and.
V:1.7 Parallell (Concurrent) VHDL I det föregånde exemplet exekveras raderna i architecturen exakt samtidigt. Det spelar ingen roll i vilken ordning de står och antalet rader är obegränsat. Exemplet nedan visar att ordningen mellan satserna saknar betydelse, tiden delta är noll. u <= u_b or c; u_b <= a and b; u_b <= a and b; u <= u_b or c; Antag att a ändras vid t = 10 ns u_b ändras vid t = 10 ns +1 delta u ändras vid t = 10 ns+2 delta Antag att a ändras vid t = 10 ns u_b ändras vid t = 10 ns +1 delta u ändras vid t = 10 ns+2 delta Alla exekverbara satser utförs exakt samtidigt i parallell VHDL V:1.8 Instruktioner som kan användas i parallell VHDL: OBS bit-värdet anges med 1 eller 0
V:1.9 Instruktioner som kan användas i parallell VHDL,forts: OBS vektorvärdet anges med 00,. Aritmetiska operationer: OBS de aritmetiska operationerna finns definierade i ett antal packages, t.ex: IEEE.STD_LOGIC_UNSIGNED.ALL; V:1.10 Vektorer i VHDL: signal s: std_logic_vector(5 downto 0); signal a,b: std_logic vector(2 downto 0); a<= 00 &b(2); s <=a&b; -- (obs: s har 6 element, a,b har 3 element) end; &-tecknet innebär sammanslagning (concatenering) av två vektorer
V:1.11 Sekvensiell VHDL Med sekvensiell VHDL menas att instruktionerna utförs i sekvens precis som vid vanlig programmering. I laborationskursen används sekvensiell VHDLenbart i processer. En process kan vara i väntande (wait) eller i aktivt (executing) tillstånd. Om processen är väntande så måste ett startvillkor uppfyllas för att processen skall starta. Processen exekverar då tills nästa waitvillkor påträffas. En process är ett parallellt kommando som tar 1 delta att utföra. Signaler tilldelas värden inne i processen men värdet uppdateras när processen lämna sitt aktivt tillstånd. Signalerna erhåller värden (uppdateras) när processen avslutas. Sekvensiell och Parallell VHDL V:1.12
V:1.13 Att använda processer i VHDL är mycket vanligt och det förenklar beskrivningarna i hög grad. Det är mycket viktigt är att få en känsla för hur processerna fungerar och man brukar skilja mellan kombinatoriska processer och synkrona processer. En process består av: process(sensitivity_list) process_deklaration.. end process; V:1.14 Kombinatoriska processer I kombinatoriska processer måste alla insignaler till processen finnas med i sensitivity list. Det är inte säkert att det blir fel om någon signal utelämnas men det kan bli skillnader mellan simulering och verklighet. Naturligtvis måste alla utsignaler tilldelas värden annars uppstår minnesfunktioner för de signaler som inte får värden. När man använder if-satser är det lätt att glömma det. Exempel på en kombinatorisk process: process(a,b,c) variable temp: std_logic; temp:=a or b; ut<=temp and not c; end process; Här deklareras en variable. En variable uppdaterar sitt värde omedelbart.
V:1.15 Synkrona processer Synkrona processer styrs av flanken på en klocksignal. Sensivity list måste innehålla klocksignalen och andra direktverkande signaler (t.ex. reset). Här är det fel att ta med alla insignaler eftersom då försvinner den synkrona klockningen. Exempel på en synkron process: process (clk,resetn) if resetn = 0 then q<= 0 ; elsif clk event and clk = 1 then q<=d; end if; end process; V:1.16 process (clk,resetn) if resetn = 0 then q<= 0 ; elsif clk event and clk = 1 then q<=d; end if; end process;
V:1.17 If statement, syntax V:1.18 Case statement, syntax
V:1.19 Exempel med case-satsen V:1.20 Exempel: 4 bitars skiftregister,parallell in, serie ut libraray ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; --..unsigned.all för skiftoperationen sll entity shift_ex is port(clk,resetn,shift_en,load: in std_logic; d_in: in std_logic_vector(3 downto 0); shift_out: std_logic); end;
Exempel: 4 bitars skiftregister,parallell in, serie ut, forts V:1.21 architecture rtl of shift_ex is signal shift_reg_b: std_logic_vector(3 downto 0); process(clk,resetn) if resetn= 0 then shift_reg_b<= 0000 ; --(others=> 0 ) elsif clk event and clk= 1 then if load= 1 then shift_reg_b<=d_in; elsif shift_en= 1 then shift_reg_b(3 downto 1)<= shift_reg_b(2 downto 0); shift_reg_b(0)<= 0 ; -- shift_reg_b<=shift_reg_b sll 1; VHDL93 end if; end if; end process; shift_out<=shift_reg_b(3); end; V:1.22 Exempel: 4-bitars räknare med enable och carry out libraray ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; --..unsigned.all för aritmetiska operationen + entity count4 is entity count4 is port(clk,resetn,count_en: in std_logic; sum: out std_logic_vector(3 downto 0); cout: std_logic); end;
V:1.23 Exempel: 4-bitars räknare med enable och carry out, forts architecture rtl of count4 is signal count_b: std_logic_vector(3 downto 0); process(clk,resetn) if resetn= 0 then count_b<= 0000 ; --(others=> 0 ) elsif clk event and clk= 1 then if count_en= 1 then count_b<=count_b+1; end if; end if; end process; sum<=count_b cout<= 1 when count_b=15 and count_en= 1 else 0 ; end; V:1.24