ČESKÉ VYSOKÉ UČENÍ TECHNICKÉ V PRAZE Fakulta elektrotechnická Ing. Radek Sedláček, Ph.D. , katedra měření K13138
Jazyk VHDL – konstanty, signály a proměnné Jazyk VHDL – paralelní a sekvenční doména
Kurz A0B38FPGA – Aplikace hradlových polí
OPERAČNÍ PROGRAM PRAHA ADAPTABILITA Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti
Jazyk VHDL – konstanty, signály a proměnné
1. část přednášky Kurz A0B38FPGA – Aplikace hradlových polí
Snímek 2 z 38
▼ Datové objekty ve VHLD
VHDL rozlišuje tyto datové objekty:
Konstanty
Signály
Proměnné
Soubory (Files)
Deklarace těchto objektů = přiřazení datového typu k tomuto objektu, v případě konstant též i její hodnotu
Konstanty používáme v případě vícenásobného využití jedné hodnoty – zpřehledňují a zlepšují citelnost kódu, jejich hodnota je neměnná
Signály můžeme chápat jako jednotlivé vodiče (dráty) ve schématu – hodnota je dána přiřazením
Proměnné nepředstavují skutečné signály, jsou pomocné objekty používány např. pro počítání cyklů v těle procesu, je možné je použít pouze jen v rámci procesu
Soubory – využívají se např. pro uložení vstupních a výstupních dat při simulaci, pro syntézu význam nemají
Snímek 3 z 38
▼ Pravidla pro název identifikátorů
první znak musí být písmeno
poslední znak nesmí být podtržítko
nejsou povolena dvě podtržítka
identifikátor konstanty, signálu či proměnné nesmí být shodný s rezervovaným slovem jazyka VHDL
VHDL jazyk NENÍ case-senzitive (nerozlišují se malá/velká písmena)
Proto např. zápis txclk, Txclk, TXCLK – vždy reprezentuje jeden a tentýž identifikátor datového objektu !!!
Snímek 4 z 38
▼ Datový objekt konstanta ve VHDL Syntaxe: constant identifikátor : typ := výraz;
Příklady: constant Pi : real := 3.141; constant Half_Pi : real := Pi/2.0; constant cycle_time : time := 2 ns; constant N, N5 : integer := 5;
konstanty mají pevnou hodnotu, ta nemůže být měněna během procesu simulace
konstanty nemusí být inicializovány v rámci deklarace package, jejich hodnotu je možné nadefinovat až v sekci těla package – jedná se o tzv. deferred constants
konstanty můžou být deklarovány na začátku architektury, pak ji lze použít kdekoliv v rámci této architektury
konstanty deklarovány v těle procesu jsou viditelné pouze z tohoto procesu Snímek 5 z 38
▼ Datový objekt proměnná ve VHDL Syntaxe: variable identifikátor : typ [ := výraz ];
Příklady: variable count : integer := 0; variable CNTR_BIT: bit :=0; variable VAR1: boolean :=FALSE;
proměnná má také přiřazenu pouze jednu hodnotu jako konstanta, ovšem lze její hodnotu změnit pomocí přiřazení pro proměnnou :=
proměnné musí být definovány uvnitř procesu (lze je chápat jako lokální proměnné procesu)
proměnné jsou aktualizovány okamžitě bez jakéhokoliv zpoždění (na rozdíl od signálu !!!)
Snímek 6 z 38
▼ Datový objekt signál ve VHDL Syntaxe: signal identifikátor : typ [ := výraz ];
Přiřazení nové hodnoty do signálu v paralelní doméně je „bez zpoždění“ !!!
Přiřazení nové hodnoty do signálu v procesu (sekvenční doměně) se provede na konci procesu !!!
Příklady: signal enable : bit ;
-- deklarace signálu bez počáteční hodnoty
signal bit_a : bit := '0';
-- deklarace signálu s počáteční hodnotou
bit_a <= bit_a xor '1';
-- okamžité přiřazení signálu
signal my_word : word := X"0123_4567";
-- deklarace signálu
my_word <= X"FFFF_FFFF";
-- okamžité přiřazení signálu
suma <= (A xor B) after 2 ns;
-- zpožděné přiřazení signálu (pouze pro simulaci)
Snímek 7 z 38
▼ Datový objekt soubor ve VHDL Syntaxe: file identifikátor : typ [open mode ] is výraz ;
[Open mode] : read_mode, write_mode, append_mode Příklady:
type interger_file is file of integer;
-- deklarace nového typu souboru
file lookup_table_file : integer_file is “hodnoty.txt” ;
-- deklarace souboru
-- soubor hodnoty.txt musí být umístěn v aktuálním adresáři
Snímek 8 z 38
▼ Příklad využití objektu soubor pro inicializaci paměti
Snímek 9 z 38
▼ Atributy
nesou dodatečnou informaci o entitě, architektuře, datovém typu či signálu
zjednodušují syntaxi zápisu
předdefinována celá řada atributů – název atributu se umístí za apostrof
Příklad:
zjištění délky pole my_array:
my_array’length
předdefinované atributy
pro skalární datové typy (např. left, right, low, high)
pro signály (např. event, active)
Snímek 10 z 38
▼ Atributy skalárních typů
left
- vrací 1.hodnotu zleva
right
- vrací 1.hodnotu zprava
low
- vrací nejmenší hodnotu
high
- vrací největší hodnotu
ascending
- vrací TRUE, pokud rozsah je rostoucí posloupnost
image(x)
- vrací řetězec reprezentující hodnotu x
value(s)
- vrací hodnotu, která je reprezentována řetězcem s
pos (x)
- vrací pozici prvku x
val (n)
- vrací hodnotu na pozici n
succ(x)
- vrací hodnotu následující po prvku x
pred(x)
- vrací hodnotu, která předchází prvku x
leftof(x)
- vrací hodnotu, která je o jednu pozici vlevo od prvku x
rightof (x)
- vrací hodnotu, která je o jednu pozici vpravo od prvku x
Snímek 11 z 38
▼ Atributy skalárních typů Příklad: type citac is integer range 0 to 255 type pole is array (15 downto 0) of std_logic; citac’left
vrací 0
pole’left
vrací 15
citac’right
vrací 255
pole’right
vrací 0
citac’length
vrací 256
pole’length
vrací 16
citac’high
vrací 255
pole’high
vrací 15
citac’low
vrací 0
pole’low
vrací 0
citac’ascending
vrací TRUE
pole’ascending
vrací FALSE
citac’image(1)
vrací „1“
pole’image(15)
vrací „15“
citac’value(“20”)
vrací 20
pole’value(“10”)
vrací 10
citac’pos(15)
vrací 15
pole’pos(15)
vrací 15
citac’val(0)
vrací 0
pole’pos(0)
vrací 0
citac’succ(1)
vrací 2
pole’succ(1)
vrací 0
citac’pred(5)
vrací 4
pole’pred(5)
vrací 6
citac’leftof(5)
vrací 4
pole’leftof(5)
vrací 6
citac’rightof(5)
vrací 6
pole’rightof(5)
vrací 4 Snímek 12 z 38
▼ Atributy skalárních typů Příklad: type stavy is (iddle, rx_startbit, rx_data, rx_stopbit) stavy’left stavy’right stavy’length stavy’high stavy’low stavy’ascending stavy’image(iddle) stavy’value(“iddle”) stavy’pos(iddle) stavy’val(1) stavy’succ(iddle) stavy’pred(rx_data) stavy’leftof(rx_data) stavy’rightof(rx_data)
vrací iddle vrací rx_stopbit vrací 4 vrací rx_stopbit vrací iddle vrací TRUE vrací “iddle” vrací iddle vrací 0 vrací rx_startbit vrací rx_startbit vrací rx_startbit vrací rx_startbit vrací , rx_stopbit
Snímek 13 z 38
▼ Předdefinované atributy pro signály
signal’event - vrací typ boolean, hodnotu True, jestliže nastal event na daném signálu
signal’active – vrací typ boolean, hodnotu True, jestliže nastalo přiřazení na signálu
signal’transaction – vrací typ bit, komplementuje se po každém novém přiřazení
signal’last_event – vrací čas od poslední události na signálu
signal’last_active - vrací čas od posledního přiřazení
signal’last_value - vrací hodnotu signálu před poslední událostí
signal’delayed(T) - vrací hodnotu signálu zpožděného o čas T [T je option, defaultní hodnota T=0]
signal’stable(T) - vrací typ boolean, hodnotu True, jestliže nenastal událost na signálu během intervalu T [T is optional, defaultní hodnota T=0]
signal’quiet(T) - vrací typ boolean, hodnotu True, jestliže nenastalo žádné přiřazení během intervalu T [T is optional, defaultní hodnota T=0]
Snímek 14 z 38
▼ Atributy signálu Příklad:
if (CLOCK’event and CLOCK=’1’) then … -- podmínka je pslněna, pokud se na signálu CLK objevila náběžná hrana
if (CLOCK’event) then … -- podmínka je splněna při náběžné i sestupné hraně
Snímek 15 z 38
▼ Rozdíl mezi signálem a proměnnou Příklad: proces využívající proměnné architecture arch of EXAMPLE is signal TRIGGER, RESULT: integer := 0; begin process variable a: integer :=1; variable b: integer :=2; variable c: integer :=3; begin wait on TRIGGER; a := b; --2 b := a + c; --5 c := b; --5 RESULT <= a + b + c; end process; end arch Hodnota RESULT bude 12. Proč? Protože v procesu výpočtu proměnných probíhá sekvenčně (jeden po druhém) a „bez zpoždění“. Snímek 16 z 38
▼ Rozdíl mezi signálem a proměnnou Příklad: proces využívající signály architecture arch of EXAMPLE is signal TRIGGER, OUTPUT: integer := 0; signal a integer :=1; signal b: integer :=2; signal c: integer :=3; begin process begin wait on TRIGGER; a<= b; b <= a + c; c<= b; RESULT <= a + b + c; end process; end arch; Hodnota signálu RESULT bude 6. Proč ? Protože hodnoty signálů jsou vypočteny současně v jeden okamžik na konci procesu Snímek 17 z 38
▼ Rozdíl mezi signálem a proměnnou - způsob přiřazení
Inicializace : pro signály i proměnné se používá se symbol := Přiřazení: pro signály – používá se symbol
<=
pro proměnné – používá se symbol
:=
Snímek 18 z 38
Jazyk VHDL – paralelní a sekvenční doména
2. část přednášky Kurz A0B38FPGA – Aplikace hradlových polí
Snímek 19 z 38
▼ Paralelní x sekvenční doména
Pro hradlová pole – typické paralelní zpracování signálu (paralelní doména) – vyplývá s vlastní podstaty HW
Je navrženo na paralelní výpočty, na realizaci paralelních struktur apod.
Nicméně existují možnosti, jak provádět sekvenční vykonávání příkazů – např. implementací softwarového procesoru na FPGA
Snímek 20 z 38
▼ Paralelní doména - paralelní (souběžné) přiřazení
Vše, co je umístěno mimo procesy = odpovídá paralelní doméně
Může to být
přiřazení nové hodnoty signálu – podmíněné i nepodmíněné
použití nové instance entity – příkaz port map
souběh několika procesů
Snímek 21 z 38
▼ Paralelní doména - podmíněné přiřazení hodnoty do signálu Existují tyto možnosti, jak podmíněně přiřadit novou hodnotu signálu
Konstrukce příkazu WITH – SELECT – WHEN
Konstrukce příkazu WHEN – ELSE
Snímek 22 z 38
▼ Konstrukce příkazu WITH-SELECT-WHEN Syntaxe: WITH signal_A SELECT signal_B
<= hodnota_1 WHEN 1_hodnota_signalu_A, <= hodnota_2 WHEN 2_hodnota_signalu_A, <= hodnota_3 WHEN 3_hodnota_signalu_A;
Příklad:
WITH sel SELECT output <= i0 WHEN “0000” TO “0100”, -- výbět „od“ „do“ <= i1 WHEN “0101” | “0111”,
-- „nebo“
<= i2 WHEN “1111”, <= i3 WHEN OTHERS;
-- nutno ošetřit všechny ostatní případy
Snímek 23 z 38
▼ Konstrukce příkazu WHEN-ELSE Syntaxe: signal
<=
hodnota_1 WHEN podmínka_1 ELSE hodnota_2 WHEN podmínka_2 ELSE hodnota_3 WHEN podmínka_3 ELSE hodnota_4;
Příklad: signal enable: std_logic_vector (7 downto 0);
enable <=
X”00” WHEN w=’0’ ELSE X”01” WHEN x=’1’ ELSE X”10” WHEN z=’1’ ELSE X”11”;
Snímek 24 z 38
▼ Sekvenční doména
Opak paralelní domény - vše, co je umístěno do procesu, je zpracováno jako sekvenční zpracování
Možné příkazy uvnitř procesu
příkazy IF – THEN – ELSE
příkaz CASE – WHEN
příkaz WAIT
programové smyčky – LOOP, FOR, WHILE
Snímek 25 z 38
▼ Sekvenční doména - proces
proces typický obsahuje i citlivostní seznam signálů, které proces spouští
proces je volán v okamžiku, kdy nastane jakákoliv změna na těchto signálech, které jsou uvedeny na citlivostním seznamu
pokud proces tento seznam nedefinuje, znamená to, že je volán při první běhu VHDL kódu v čase t = 0, zároveň je nutné v těle procesu alespoň 1x použít příkaz WAIT
pokud proces má citlivostní seznam, znamená to, že je to ekvivalentní situaci, kdy proces bez seznamu, ale je nutné přidat příkaz wait (viz. níže uvedený příklad)
Snímek 26 z 38
▼ Sekvenční doména - proces Syntaxe: process (citlivostní seznam signálů) --variables begin --Sequential Statements end process; Příklad: proces se synchronním RESET signálem process begin wait until clk'event and clk='1'; if reset = '0' then A <= "0000"; else A <= B; end if; end process; Snímek 27 z 38
▼ Sekvenční doména - proces Příklad: proces s asynchronním RESET signálem
process (reset, clk) begin if reset='0' then -- uvedení struktury (entity, obvodu) do počátečního stavu elsif (clk'event and clk='1') then -- sekce definující vlastní chování entity end if; end process;
Snímek 28 z 38
▼ Sekvenční doména - příkaz IF-THEN-ELSE Syntaxe: if podmínka1 then --sekveční přiřazení elsif podmínka2 then --sekveční přiřazení else
--sekveční přiřazení
end if;
Snímek 29 z 38
▼ Sekvenční doména - příkaz IF-THEN-ELSE Příklad: entity my_if is port ( c, d, e, f : in std_logic; s : in std_logic_vector(1 downto 0); pout : out std_logic );
Fyzická realizace podmínek typu IF
end my_if; architecture my_arc of my_if is begin myif_pro: process (s, c, d, e, f) begin if s = “00” then pout <= c; elsif s = “01” then pout <= d; elsif s = “10” then pout <= e; else pout <= f; end if; end process myif_pro; end my_arc; Snímek 30 z 38
▼ Sekvenční doména - příkaz CASE - WHEN Syntaxe: CASE signal IS WHEN hodnota 1 => přiřazení 1; WHEN hodnota 2 => přiřazení 2; WHEN hodnota 3 => přiřazení 3; WHEN ostatní_hodnoty => přiřazení 4; END CASE;
Snímek 31 z 38
▼ Sekvenční doména - příkaz CASE - WHEN Příklad: entity my_case is port ( c, d, e, f : in std_logic; s : in std_logic_vector(1 downto 0);
Fyzická realizace podmínek typu IF
pout : out std_logic ); end my_case; architecture my_arc of my_case is begin mycase_pro: process (s, c, d, e, f) begin case s is when “00” => pout <= c; when “01” => pout <= d; when “10” => pout <= e; when others => pout <= f; end case; end process mycase_pro; end my_arc; Snímek 32 z 38
▼ Sekvenční doména - příkaz WAIT Syntaxe:
WAIT (ON signal_list) (UNTIL expression) (FOR time);
Příklady:
WAIT ON s1,s2;
-- čeká na změnu signálů s1, s2
WAIT FOR 50 ns;
-- čeká po dobu 50ns
WAIT UNTIL enable = ‘1’;
-- čeká dokud enable = “1”
Podmínky můžou být kombinovány viz. následující příklad:
WAIT ON a,b UNTIL clk=’1’;
Snímek 33 z 38
▼ Sekvenční doména – programové smyčky ve VHDL Syntaxe: loop_label: LOOP
-- nepodmíněná (nekonečná) smyčka
statement(s); END LOOP loop_label;
loop_label: FOR loop_variable IN RANGE LOOP -- smyčka typu FOR statement(s); END LOOP loop_label;
loop_label: WHILE condition LOOP -- smyčka typu WHILE statement(s); END LOOP loop_label; Snímek 34 z 38
▼ Sekvenční doména - programové smyčky ve VHDL
NEXT loop_label WHEN condition; -- NEXT : pokud je splněna podmínka , smyčka se začně vykonávat
EXIT loop_label;
-jedna možnost –ukončení
EXIT loop_label WHEN condition; - -druhá možnost dle podmínky -- příkaz EXIT : ukončuje všechny smyčky, podmíněné i nepodmíněné
Snímek 35 z 38
▼ Programové smyčky Příklady:
Snímek 36 z 38
▼ Programové smyčky Příklady:
Snímek 37 z 38
▼ Děkuji za pozornost, máte nějaké dotazy?
Snímek 38 z 38