OBSAH WEBU
ČTĚTE!
Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
temata:10-principy_vhdl:main [2011/03/31 11:27] vagabund |
temata:10-principy_vhdl:main [2011/03/31 14:12] (aktuální) vagabund |
||
---|---|---|---|
Řádek 1: | Řádek 1: | ||
- | ===== 3. Principy VHDL ===== | + | ~~ODT~~ |
+ | ====== 10 - Principy VHDL ====== | ||
+ | |||
+ | ===== Úvod ===== | ||
<box round green 90%|**Myšlenka**> | <box round green 90%|**Myšlenka**> | ||
Řádek 43: | Řádek 46: | ||
- | ==== Základní kontrukce jazyka ==== | + | ===== Základní kontrukce jazyka ===== |
- | <code> | + | <code vhdl> |
-- knihovny | -- knihovny | ||
library IEEE; | library IEEE; | ||
Řádek 81: | Řádek 84: | ||
</box> | </box> | ||
- | === Strukturální popis sčítačky === | + | ==== Strukturální popis sčítačky ==== |
**definice komponent** | **definice komponent** | ||
- | <code> | + | <code vhdl> |
library IEEE; | library IEEE; | ||
use IEEE.std_logic_1164.all; | use IEEE.std_logic_1164.all; | ||
Řádek 105: | Řádek 108: | ||
**popis obvodu z komponent** | **popis obvodu z komponent** | ||
- | <code> | + | <code vhdl> |
library IEEE; | library IEEE; | ||
use IEEE.std_logic_1164.all; | use IEEE.std_logic_1164.all; | ||
Řádek 146: | Řádek 149: | ||
</box> | </box> | ||
- | === Behaviorální popis sčítačky === | + | ==== Behaviorální popis sčítačky ==== |
- | <code> | + | <code vhdl> |
architecture BEH of FA is | architecture BEH of FA is | ||
begin | begin | ||
Řádek 171: | Řádek 174: | ||
</box> | </box> | ||
- | === Test Bench === | + | ==== Test Bench ==== |
sada testů pro danou komponentu | sada testů pro danou komponentu | ||
- | <code> | + | <code vhdl> |
-- testbench pro FA | -- testbench pro FA | ||
library ieee; | library ieee; | ||
Řádek 225: | Řádek 228: | ||
{{:temata:10-principy_vhdl:sim.jpg?500|}} | {{:temata:10-principy_vhdl:sim.jpg?500|}} | ||
+ | |||
+ | ===== Vybrané konstrukce ===== | ||
+ | |||
+ | ==== Knihovny ==== | ||
+ | |||
+ | === ieee.std_logic_1164.all === | ||
+ | umožňuje vícehodnotové stavy\\ | ||
+ | |||
+ | {{:temata:10-principy_vhdl:table.jpg|}} | ||
+ | |||
+ | **std_logic** - jeden vodič\\ | ||
+ | **std_logic_vector** - skupina vodičů (např. sběrnice)\\ | ||
+ | |||
+ | === ieee.std_logic_unsigned.all === | ||
+ | |||
+ | definuje aritmetické operátory nad binárními vektory pro operace sčítání (+), odčítání (-) a násobení (*). | ||
+ | |||
+ | === ieee.std_logic_arith.all === | ||
+ | |||
+ | umožňuje pracovat s čísly se znaménkem i bez znaménka tak, že zavádí dva nové typy signed a unsigned. Binární hodnotu h datového typu std_logic_vector můžeme zkonvertovat na typ unsigned zápisem unsigned (h) a na typ signed zápisem signed(h).\\ | ||
+ | Pomocí funkce conv_integer je možné provádět konverze mezi hodnotami typu integer a std_logic_vector, např. | ||
+ | |||
+ | <code vhdl> | ||
+ | signal c : std_logic_vector (3 downto 0); | ||
+ | signal ci : integer; | ||
+ | c <= “1000”; | ||
+ | ci <= conv_integer(signed(c)); -- v ci bude -8 | ||
+ | </code> | ||
+ | |||
+ | ==== Konstanty ==== | ||
+ | |||
+ | <code vhdl> | ||
+ | CONSTANT constant_name : type_name [:= value]; | ||
+ | </code> | ||
+ | |||
+ | <code vhdl> | ||
+ | CONSTANT PI : REAL := 3.14; | ||
+ | CONSTANT SPEED : INTEGER; | ||
+ | </code> | ||
+ | |||
+ | ==== Proměnné ==== | ||
+ | |||
+ | Určeny pro lokální uložení dat. Hodnota se mění ihned po přiřazení ( := ) | ||
+ | |||
+ | <code vhdl> | ||
+ | VARIABLE variable_name : type_name [:= value]; | ||
+ | </code> | ||
+ | |||
+ | <code vhdl> | ||
+ | VARIABLE opcode : STD_LOGIC_VECTOR (3 DOWNTO 0) := "0000"; | ||
+ | VARIABLE freq : INTEGER; | ||
+ | </code> | ||
+ | |||
+ | ==== Signály ==== | ||
+ | |||
+ | Slouží pro komunikaci mezi VHDL moduly\\ | ||
+ | přiřazena se zpožděním, po skončení všech částí procesů\\ | ||
+ | |||
+ | <code vhdl> | ||
+ | SIGNAL signal_name : type_name [:= value]; | ||
+ | </code> | ||
+ | |||
+ | <code vhdl> | ||
+ | signal din: STD_LOGIC_VECTOR (7 downto 0); -- 7 MSB, 0 LSB, pristup k jednotlivým bitům: din(4), ... | ||
+ | signal a: STD_LOGIC_VECTOR (0 to 2); -- 0 MSB, 2 LSB | ||
+ | signal y: STD_LOGIC; | ||
+ | </code> | ||
+ | |||
+ | ==== Porty entity ==== | ||
+ | |||
+ | * in - výstupní port | ||
+ | * out - vstupní port | ||
+ | * inout - obousměrný port | ||
+ | * buffer - výstupní port, obsah lze ale číst | ||
+ | * linkage - směr toku dat nezadaný | ||
+ | |||
+ | ==== Datové typy ==== | ||
+ | |||
+ | **real, integer** | ||
+ | |||
+ | <code vhdl> | ||
+ | constant pi: real := 3.14; | ||
+ | constant cislo: integer := 5; | ||
+ | -- soustavy: 123 (10), 8#730# (8), 16#FFFF# (16), 2#1001# (2) | ||
+ | -- pro std_logic_vector - "0111101" (2), X"76" (16), O"77" (8) | ||
+ | </code> | ||
+ | |||
+ | **výčtový typ** | ||
+ | |||
+ | <code vhdl> | ||
+ | -- Vytvoření nového výčtového typu muj_stav | ||
+ | TYPE muj_stav IS (reset, idle, rw, io); | ||
+ | -- Vytvoření proměnné typu muj_stav | ||
+ | signal stav: muj_stav; | ||
+ | -- Do proměnné lze přiřadit pouze hodnotu daného typu | ||
+ | stav <= reset; -- nelze psát, např. stav <= "00" | ||
+ | </code> | ||
+ | |||
+ | **atributy** | ||
+ | |||
+ | pro skalární typy, pomocí apostrofu | ||
+ | |||
+ | <code vhdl> | ||
+ | VARIABLE pom: integer; | ||
+ | |||
+ | pom`pred -- předchůdce | ||
+ | pom`succ -- následník | ||
+ | pom`high -- maximální hodnota v rozsahu | ||
+ | pom`low -- minimální hodnota v rozsahu | ||
+ | </code> | ||
+ | |||
+ | signály obsahují specifické atributy, např. active, last_active, last_event, last_value atd.\\ | ||
+ | pro clk: clk'event (změna hodnoty) | ||
+ | |||
+ | **pole** | ||
+ | |||
+ | <code vhdl> | ||
+ | type ram_typ is array(0 to 63) of STD_LOGIC_VECTOR(15 downto 0); | ||
+ | |||
+ | signal ram: ram_typ; | ||
+ | |||
+ | ram(0) <= x"1a0f"; | ||
+ | </code> | ||
+ | |||
+ | ==== Operátory ==== | ||
+ | |||
+ | **logické** | ||
+ | |||
+ | <code vhdl> | ||
+ | and, or, nand, nor, xor, nxor, not | ||
+ | </code> | ||
+ | |||
+ | **relační** | ||
+ | <code vhdl> | ||
+ | =, /=, >, <, <=, >= | ||
+ | </code> | ||
+ | |||
+ | **aritmetické**\\ | ||
+ | Binární: +, -, *, /, rem, mod, * * (mocnina)\\ | ||
+ | Operátory rem i mod produkují zbytek po celočíselném dělení (výsledek a mod b má znaménko shodné s b, a rem b má znaménko shodné s a)\\ | ||
+ | Unární: +, -, abs\\ | ||
+ | |||
+ | |||
+ | **Posuvy a rotace**\\ | ||
+ | Posuvy: SLL, SRL (logický), SLA, SRA (aritmetický – zachovává nejnižší bit)\\ | ||
+ | Rotace: ROL (vlevo), ROR (vpravo)\\ | ||
+ | |||
+ | **Konkatenace** | ||
+ | |||
+ | <code vhdl> | ||
+ | signal a, b: std_logic_vector (3 downto 0) := "0011"; | ||
+ | signal c: std_logic_vector (7 downto 0) := "1111"; | ||
+ | |||
+ | c <= a & b; -- konkatenace, v c bude „00111111“ | ||
+ | |||
+ | a <= a(2 downto 0) & a(3); -- „0011“ -> “0110”, rotace | ||
+ | |||
+ | b(3 downto 2) <= “01”; -- práce s horními dvěma bity b | ||
+ | |||
+ | c <= (‘0’, ‘1’, others=>’0’); -- agregace, a <= 01000000 | ||
+ | </code> | ||
+ | |||
+ | **Priorita operátorů** | ||
+ | |||
+ | * 1. * *, ABS, NOT | ||
+ | * 2. *, /, MOD, REM | ||
+ | * 3. Unární +, - | ||
+ | * 4. +, -, & | ||
+ | * 5. SLL, SRL, SLA, SRA, ROL, ROR | ||
+ | * 6. =, /=, <, <=, >, >= | ||
+ | * 7. AND, OR, NAND, NOR, XOR, XNOR | ||
+ | |||
+ | ==== Proces ==== | ||
+ | |||
+ | <code vhdl> | ||
+ | process [(sensitivity_list)] | ||
+ | [subprogram_decl|subprogram_body] | ||
+ | [type_decl] | ||
+ | [subtype_decl] | ||
+ | [constant_decl] | ||
+ | [variable_decl] | ||
+ | [file_decl] | ||
+ | [alias_decl] | ||
+ | [attribute_decl] | ||
+ | [attribute_spec] | ||
+ | [use_clause] | ||
+ | begin | ||
+ | [sequential_statements] | ||
+ | end process [proc_label]; | ||
+ | </code> | ||
+ | |||
+ | V rámci procesu lze použít: | ||
+ | |||
+ | === if === | ||
+ | <code vhdl> | ||
+ | if condition then | ||
+ | sequential_statements | ||
+ | {elsif condition then | ||
+ | sequential_statements} | ||
+ | [else | ||
+ | sequential_statements] | ||
+ | end if; | ||
+ | </code> | ||
+ | |||
+ | === case === | ||
+ | <code vhdl> | ||
+ | case expression is | ||
+ | {when choices => sequential_statements} | ||
+ | end case; | ||
+ | </code> | ||
+ | |||
+ | volba musí být ve tvaru: | ||
+ | |||
+ | <code vhdl> | ||
+ | value => sequential_statements -- pro jednu hodnotu | ||
+ | value1 | value2 ... => sequential_statements -- pro více hodnot | ||
+ | value1 to value2 => sequential_statements -- pro určitý rozsah | ||
+ | others => sequential_statements -- pro ostatní | ||
+ | </code> | ||
+ | |||
+ | **příklad** | ||
+ | |||
+ | <code vhdl> | ||
+ | case BCD is | ||
+ | when "0000" => LED := "1111110"; | ||
+ | when "0001" => LED := "1100000"; | ||
+ | when "0010" => LED := "1011011"; | ||
+ | when "0011" => LED := "1110011"; | ||
+ | when "0100" => LED := "1100101"; | ||
+ | when "0101" => LED := "0110111"; | ||
+ | when "0110" => LED := "0111111"; | ||
+ | when "0111" => LED := "1100010"; | ||
+ | when "1000" => LED := "1111111"; | ||
+ | when "1001" => LED := "1110111"; | ||
+ | when others => LED := "-------"; -- don't care | ||
+ | end case; | ||
+ | </code> | ||
+ | |||
+ | === Loop === | ||
+ | |||
+ | <code vhdl> | ||
+ | [label:] while condition loop | ||
+ | ... sequence of statements ... | ||
+ | end loop label; | ||
+ | [label:] for loop_variable in range loop | ||
+ | ... sequence of statements... | ||
+ | end loop label; | ||
+ | </code> | ||
+ | |||
+ | Ukončení současné iterace. | ||
+ | <code vhdl> | ||
+ | next [loop_label][when condition]; | ||
+ | </code> | ||
+ | |||
+ | Opuštění cyklu: | ||
+ | <code vhdl> | ||
+ | exit [loop_label][when condition]; | ||
+ | </code> | ||
+ | |||
+ | === Assert === | ||
+ | |||
+ | dovoluje v průběhu činnosti programu otestovat určitou kritickou podmínku a následně eventuelně ukončit činnost simulace. | ||
+ | |||
+ | <code vhdl> | ||
+ | assert condition | ||
+ | [report string_expr] | ||
+ | [severity failure|error|warning|note]; | ||
+ | </code> | ||
+ | |||
+ | <code vhdl> | ||
+ | process (CLK, DIN) behavior of a D-FF | ||
+ | variable X: integer; | ||
+ | ... | ||
+ | begin | ||
+ | ... | ||
+ | assert (X > 3) | ||
+ | report "setup violation" | ||
+ | severity warning; | ||
+ | ... | ||
+ | end process; | ||
+ | </code> | ||
+ | |||
+ | === Wait === | ||
+ | |||
+ | Dynamicky řídí spouštění a pozastavování procesů. Pokud je tento příkaz použit v rámci procesu, pak proces nesmí obsahovat citlivostní seznam. | ||
+ | |||
+ | <code vhdl> | ||
+ | wait | ||
+ | [on signal_name {, signal_name}] | ||
+ | [until condition] | ||
+ | [for time_expr]; | ||
+ | </code> | ||
+ | |||
+ | === Výběrové přiřazení signálu === | ||
+ | <code vhdl> | ||
+ | with expression select | ||
+ | signal_name <=expression when value{, expression when value}; | ||
+ | </code> | ||
+ | |||
+ | <code vhdl> | ||
+ | with MYSEL select | ||
+ | Z <= A when 15, | ||
+ | B when 22, | ||
+ | C when 28; | ||
+ | </code> | ||
+ | |||
+ | === Podmíněné přiřazení signálu === | ||
+ | <code vhdl> | ||
+ | signal_name <=expression when condition else | ||
+ | {expression when condition else} | ||
+ | </code> | ||
+ | |||
+ | **Příklad:** | ||
+ | <code vhdl> | ||
+ | Z <= A when (X > 3) else | ||
+ | B when (X < 3) else | ||
+ | C; | ||
+ | </code> | ||
+ | |||
+ | ==== Příklady ==== | ||
+ | |||
+ | === Multiplexor === | ||
+ | |||
+ | <code vhdl> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | entity Mux is | ||
+ | port( I3: in std_logic_vector(2 downto 0); | ||
+ | I2: in std_logic_vector(2 downto 0); | ||
+ | I1: in std_logic_vector(2 downto 0); | ||
+ | I0: in std_logic_vector(2 downto 0); | ||
+ | S: in std_logic_vector(1 downto 0); | ||
+ | O: out std_logic_vector(2 downto 0) | ||
+ | ); | ||
+ | end Mux; | ||
+ | |||
+ | -- varianta 1 | ||
+ | architecture behv1 of Mux is | ||
+ | begin | ||
+ | process(I3,I2,I1,I0,S) | ||
+ | begin | ||
+ | -- příkaz case | ||
+ | case S is | ||
+ | when "00" => O <= I0; | ||
+ | when "01" => O <= I1; | ||
+ | when "10" => O <= I2; | ||
+ | when "11" => O <= I3; | ||
+ | when others => O <= "XXX"; | ||
+ | end case; | ||
+ | end process; | ||
+ | end behv1; | ||
+ | |||
+ | -- varianta 2 | ||
+ | architecture behv2 of Mux is | ||
+ | begin | ||
+ | -- příkaz when.. else | ||
+ | O <= I0 when S="00" else | ||
+ | I1 when S="01" else | ||
+ | I2 when S="10" else | ||
+ | I3 when S="11" else | ||
+ | "XXX"; | ||
+ | end behv2; | ||
+ | </code> | ||
+ | |||
+ | === Dekodér === | ||
+ | |||
+ | <code vhdl> | ||
+ | library IEEE; | ||
+ | use IEEE.std_logic_1164.all; | ||
+ | entity dec3to8 is | ||
+ | port ( | ||
+ | addr: in STD_LOGIC_VECTOR (2 downto 0); | ||
+ | y: out STD_LOGIC_VECTOR (7 downto 0) | ||
+ | ); | ||
+ | end dec3to8; | ||
+ | |||
+ | architecture dec3to8 of dec3to8 is | ||
+ | begin | ||
+ | with addr select | ||
+ | y <= "10000000" when "111", | ||
+ | "01000000" when "110", | ||
+ | "00100000" when "101", | ||
+ | "00010000" when "100", | ||
+ | "00001000" when "011", | ||
+ | "00000100" when "010", | ||
+ | "00000010" when "001", | ||
+ | "00000001" when others; | ||
+ | end dec3to8; | ||
+ | </code> | ||
+ | |||
+ | alternativně pomocí procesu: | ||
+ | |||
+ | <code vhdl> | ||
+ | process(addr) | ||
+ | begin | ||
+ | y <= "00000000"; | ||
+ | case addr is | ||
+ | when "000" => y <= "00000001"; | ||
+ | when "001" => y <= "00000010"; | ||
+ | when "010" => y <= "00000100"; | ||
+ | when "011" => y <= "00001000"; | ||
+ | when "100" => y <= "00010000"; | ||
+ | when "101" => y <= "00100000"; | ||
+ | when "110" => y <= "01000000"; | ||
+ | when "111" => y <= "10000000"; | ||
+ | when others => null; | ||
+ | end case; | ||
+ | end process; | ||
+ | </code> | ||
+ | |||
+ | === ALU === | ||
+ | |||
+ | <code vhdl> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | use ieee.std_logic_unsigned.all; | ||
+ | use ieee.std_logic_arith.all; | ||
+ | |||
+ | entity ALU is | ||
+ | port( A: in std_logic_vector(1 downto 0); | ||
+ | B: in std_logic_vector(1 downto 0); | ||
+ | Sel: in std_logic_vector(1 downto 0); | ||
+ | Res: out std_logic_vector(1 downto 0) | ||
+ | ); | ||
+ | end ALU; | ||
+ | |||
+ | architecture behv of ALU is | ||
+ | begin | ||
+ | process(A,B,Sel) | ||
+ | begin | ||
+ | case Sel is | ||
+ | when "00" => Res <= A + B; | ||
+ | when "01" => Res <= A + (not B) + 1; | ||
+ | when "10" => Res <= A and B; | ||
+ | when "11" => Res <= A or B; | ||
+ | when others => Res <= "XX"; | ||
+ | end case; | ||
+ | end process; | ||
+ | end behv; | ||
+ | </code> | ||
+ | |||
+ | <note> | ||
+ | Další popisu obvodů lze nalézt [[https://www.fit.vutbr.cz/study/courses/INP/private/cvic/inp_vhdl_opora.pdf|zde]] od strany 25. | ||
+ | </note> | ||
+ | |||
+ | ===== Potvrzení ===== | ||
+ | |||
+ | <doodle single login|10> | ||
+ | ^ OK ^ !!! ^ | ||
+ | </doodle> | ||
+ | |||
+ | {{tag>vagabund INP vhdl}} | ||
+ | |||
+ | ~~DISCUSSION~~ |