Myšlenka
Jazyk pro popis hardwaru (Hardware Description Language)
Algoritmus
Algoritmus je konečná uspořádaná množina úplně definovaných kroků pro vyřešení nějakého problému. Intuitivně algoritmem rozumíme postup, který nás dovede k řešení úlohy. Formálněji vyjádřeno se jedná o přesně definovanou konečnou posloupnost příkazů (kroků), jejichž prováděním pro každé přípustné vstupní hodnoty získáme po konečném počtu kroků odpovídající hodnoty výstupní.
algoritmus lze naimplementovat softwarově, hardwarově, jejich kombinace
Jsme-li schopni naimplementovat sekvenci, selekci, iteraci, je možné řešit každý algoritmicky řešitelný problém.
výhody obvodové implementace
nevýhody obvodové implementace
Způsoby popisu
elementární komponenty jsou popsány behaviorálně (např. AND ⇒ nemá smysl popisovat jeho strukturu)
Proces syntézy
-- 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;
Popis kódu
definice komponent
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;
+ další komponenty
popis obvodu z komponent
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;
Popis kódu
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;
Popis kódu
sada testů pro danou komponentu
-- 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;
Průběh testů
umožňuje vícehodnotové stavy
std_logic - jeden vodič
std_logic_vector - skupina vodičů (např. sběrnice)
definuje aritmetické operátory nad binárními vektory pro operace sčítání (+), odčítání (-) a násobení (*).
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ř.
signal c : std_logic_vector (3 downto 0); signal ci : integer; c <= “1000”; ci <= conv_integer(signed(c)); -- v ci bude -8
CONSTANT constant_name : type_name [:= value];
CONSTANT PI : REAL := 3.14; CONSTANT SPEED : INTEGER;
Určeny pro lokální uložení dat. Hodnota se mění ihned po přiřazení ( := )
VARIABLE variable_name : type_name [:= value];
VARIABLE opcode : STD_LOGIC_VECTOR (3 DOWNTO 0) := "0000"; VARIABLE freq : INTEGER;
Slouží pro komunikaci mezi VHDL moduly
přiřazena se zpožděním, po skončení všech částí procesů
SIGNAL signal_name : type_name [:= value];
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;
real, integer
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)
výčtový typ
-- 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"
atributy
pro skalární typy, pomocí apostrofu
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
signály obsahují specifické atributy, např. active, last_active, last_event, last_value atd.
pro clk: clk'event (změna hodnoty)
pole
type ram_typ is array(0 to 63) of STD_LOGIC_VECTOR(15 downto 0); signal ram: ram_typ; ram(0) <= x"1a0f";
logické
and, or, nand, nor, xor, nxor, not
relační
=, /=, >, <, <=, >=
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
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
Priorita operátorů
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];
V rámci procesu lze použít:
if condition then sequential_statements {elsif condition then sequential_statements} [else sequential_statements] end if;
case expression is {when choices => sequential_statements} end case;
volba musí být ve tvaru:
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í
příklad
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;
[label:] while condition loop ... sequence of statements ... end loop label; [label:] for loop_variable in range loop ... sequence of statements... end loop label;
Ukončení současné iterace.
next [loop_label][when condition];
Opuštění cyklu:
exit [loop_label][when condition];
dovoluje v průběhu činnosti programu otestovat určitou kritickou podmínku a následně eventuelně ukončit činnost simulace.
assert condition [report string_expr] [severity failure|error|warning|note];
process (CLK, DIN) behavior of a D-FF variable X: integer; ... begin ... assert (X > 3) report "setup violation" severity warning; ... end process;
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.
wait [on signal_name {, signal_name}] [until condition] [for time_expr];
with expression select signal_name <=expression when value{, expression when value};
with MYSEL select Z <= A when 15, B when 22, C when 28;
signal_name <=expression when condition else {expression when condition else}
Příklad:
Z <= A when (X > 3) else B when (X < 3) else C;
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;
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;
alternativně pomocí procesu:
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;
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;
10 | ||
---|---|---|
Celé jméno | OK | !!! |
vagy | ||
Jirka Hynek | ||
2 |