Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

temata:10-principy_vhdl:main [2011/03/31 09:39]
vagabund vytvořeno
temata:10-principy_vhdl:main [2011/03/31 14:12] (aktuální)
vagabund
Řádek 1: Řádek 1:
-===== Principy VHDL =====+~~ODT~~
  
-<box round blue 90%|**Myšlenka**>+====== 10 - Principy VHDL ====== 
 + 
 +===== Úvod ===== 
 +<box round green 90%|**Myšlenka**>
  
 Jazyk pro popis hardwaru (Hardware Description Language)\\ Jazyk pro popis hardwaru (Hardware Description Language)\\
Řádek 36: Řádek 39:
  
 **Proces syntézy**\\ **Proces syntézy**\\
-  * behaviorální syntéza - popis na nejvyšší úrovni (viz. behaviorální popis), výstupem popis na úrovni meziregistrových přenosů, nevýhodou je nemožnost ovlivnit výsledný popis (závislí na vývojových nástrojích) +  * **behaviorální syntéza** - popis na nejvyšší úrovni (viz. behaviorální popis), výstupem popis na úrovni meziregistrových přenosů, nevýhodou je nemožnost ovlivnit výsledný popis (závislí na vývojových nástrojích) 
-  * RTL syntéza - popis pomocí registrů, čítačů, automatů, atd., oddělena datová (registry, sčítačky, ...) a řídící část (FSM), výstupem popis pomocí hradel +  * **RTL (Register Transfer Language) syntéza** - popis pomocí registrů, čítačů, automatů, atd., oddělena datová (registry, sčítačky, ...) a řídící část (FSM), výstupem popis pomocí hradel 
-  * logická syntéza - popis na úrovní hradel, sestaven z komponent cílové architektury propojených vodiči+  * **logická syntéza** - popis na úrovní hradel, sestaven z komponent cílové architektury propojených vodiči
  
 </box> </box>
  
 +
 +===== Základní kontrukce jazyka =====
 +
 +<code vhdl>
 +-- knihovny
 +library IEEE;
 +use IEEE.std_logic_1164.all;
 +
 +-- popis rozhraní
 +entity FA is
 +  port (
 +    A, B, CI : in std_logic;
 +    S, COUT : out std_logic);
 +end FA;
 +
 +-- realizace rozhraní
 +architecture RTL of FA is
 +begin
 +  S <= A xor B xor CI;
 +  COUT <= (A and B) or (A and CI) or (B and CI);
 +end RTL;
 +</code>
 +
 +<box round blue round 90%|**Popis kódu**>
 +
 +  * uvedení knihoven, které se budou používat (na začátku kódu)
 +    * **library** - použivá knihovna
 +    * **use** - výběr dané komponenty z knihovny
 +  * popis rozhraní obvodu
 +    * **entity**  jmeno **is**
 +    * **port** - deklarace signálů (in, out, inout; std_logic, std_logic_vector, ...)
 +  * implementace rozhraní
 +    * **architecture typ_popisu of** jmeno **is**
 +    * uvnitř je popis, který probíhá paralélně (nezávisí na pořadí příkazů)
 +    * před **begin** deklarace signálů, komponent, atd. použitých v implementaci
 +  * **<=** přiřazení logické hodnoty signálu
 +
 +</box>
 +
 +==== Strukturální popis sčítačky ====
 +
 +**definice komponent**
 +
 +<code vhdl>
 +library IEEE;
 +use IEEE.std_logic_1164.all;
 +
 +entity OR3 is
 +  port (
 +  A, B, C : in std_logic;
 +  Z : out std_logic);
 +end OR3;
 +
 +architecture DF of OR3 is
 +begin
 +  Z <= A or B or C;
 +end DF;
 +</code>
 +
 ++ další komponenty
 +
 +**popis obvodu z komponent**
 +
 +<code vhdl>
 +library IEEE;
 +use IEEE.std_logic_1164.all;
 +
 +entity FA is
 +  port(
 +    A, B, CI : in std_logic;
 +    S, COUT : out std_logic);
 +end FA;
 +
 +architecture LIB of FA is
 +  component EO
 +    port( A, B : in std_logic; Z : out std_logic);
 +  end component;
 +  
 +  component AN2
 +    port( A, B : in std_logic; Z : out std_logic);
 +  end component;
 +  
 +  component OR3
 +    port( A, B, C : in std_logic; Z : out std_logic);
 +  end component;
 +  
 +  signal S1, A1, A3, A2 : std_logic;
 +begin
 +  u0 : EO port map( A => A, B => B, Z => S1);
 +  u1 : EO port map( A => CI, B => S1, Z => S);
 +  u2 : AN2 port map( A => A, B => B, Z => A1);
 +  u3 : AN2 port map( A => A, B => CI, Z => A2);
 +  u4 : AN2 port map( A => B, B => CI, Z => A3);
 +  u5 : OR3 port map( A => A1, B => A2, C => A3, Z => COUT);
 +end LIB;
 +</code>
 +
 +<box round blue round 90%|**Popis kódu**>
 +  * **component** - include komponenty vytvořené v jiném souboru
 +  * **port map** - propojení portů jednotlivých komponent (mapování portů)
 +    * port_komponenty => signal definovaný pro architecture
 +    * u0 : E0 - pojmenovani_instance : komponenta 
 +</box>
 +
 +==== Behaviorální popis sčítačky ====
 +
 +<code vhdl>
 +architecture BEH of FA is
 +begin
 +  p1 : PROCESS(A, B, CIN)
 +  BEGIN
 +    IF (A='1' AND B='1') OR (A='1' AND CIN='1') OR
 +    (B ='1' AND CIN='1') THEN
 +      COUT <= '1';
 +    ELSE
 +      COUT <= '0';
 +    END IF;
 +    S <= A XOR B XOR CIN;
 +  END PROCESS;
 +end BEH;
 +</code>
 +
 +<box round blue round 90%|**Popis kódu**>
 +  * **PROCESS** - pro popis chování obvodu a jeho části, příkazy se v něm vykonávají sekvenčně
 +    * může obsahovat proměnné, řídící struktury, přiřazení signálů
 +    * návěstí **p1** je nepovinné, v závorkách seznam citlivých signálů - proces se provede, je-li aktivní jeden ze signálů
 +  * 
 +</box>
 +
 +==== Test Bench ====
 +
 +sada testů pro danou komponentu
 +
 +<code vhdl>
 +-- testbench pro FA
 +library ieee;
 +use ieee.std_logic_1164.all;
 +
 +entity tb_fa is
 +end tb_fa;
 +
 +architecture arch_tb_fa of tb_fa is
 +  -- pomoci techto signalu se pripojime k testovane jednotce
 +  signal A, B, CI: std_logic;
 +  signal S, COUT : std_logic;
 +  
 +  -- tuto jednotku budeme testovat ("deklarace")
 +  component FA port (
 +    A, B, CI : in std_logic;
 +    S, COUT : out std_logic);
 +  end component;
 +begin
 +  -- "instance" testovane jednotky je pripojena pomoci zavedenych signalu
 +  UUT : FA
 +  port map (
 +    S => S, COUT => COUT);
 +    
 +  -- vlastni testovani zkousi vsechny kombinace na vstupech
 +  process
 +  begin
 +    A <= '0'; B <= '0'; CI <= '0';
 +    wait for 10 ns;
 +    A <= '0'; B <= '0'; CI <= '1';
 +    wait for 10 ns;
 +    A <= '0'; B <= '1'; CI <= '0';
 +    wait for 10 ns;
 +    A <= '0'; B <= '1'; CI <= '1';
 +    wait for 10 ns;
 +    A <= '1'; B <= '0'; CI <= '0';
 +    wait for 10 ns;
 +    A <= '1'; B <= '0'; CI <= '1';
 +    wait for 10 ns;
 +    A <= '1'; B <= '1'; CI <= '0';
 +    wait for 10 ns;
 +    A <= '1'; B <= '1'; CI <= '1';
 +    wait for 10 ns;
 +  end process;
 +end arch_tb_fa;
 +</code>
 +
 +**Průběh testů**
 +
 +{{: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~~
temata/10-principy_vhdl/main.1301557173.txt.gz · Poslední úprava: 2011/03/31 09:39 autor: vagabund
Recent changes RSS feed Debian Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki