O controlo de tipos de objectos em VHDL é muito forte (strongly typed language). Definição de cada operação inclui os tipos dos valores a que esta operação pode ser aplicada. Valores dos tipos escalares não podem ser decompostos em valores de outros tipos. Declaração de tipos Os tipos novos são especificados num modelo VHDL com a ajuda de declarações de tipos. nome do tipo definição do tipo type word is std_logic_vector (7 downto 0); type alunos is range 1 to 16; type computadores is range 1 to 16; tipos incompatíveis Se quiser definir um tipo novo e utilizá-lo na especificação de portas de uma entidade, terá que definir este tipo num pacote (package) para que ele seja visível na declaração da entidade. package my_types is type small_int is range 0 to 8; end my_types; pacote package body my_types is end my_types; use work.my_types.all; entity tipos is port (number : small_int); end entity tipos; architecture Behavioral of tipos is type alunos is range 1 to 16; type computadores is range 1 to 16; signal a : alunos; signal c : computadores; begin a <= c; -- erro end Behavioral; entidade que utiliza tipos definidos no pacote Tipos inteiros integer – inclui todos os números inteiros representáveis num computador particular (standard: -231+1 ... 231-1). É possível construir tipos inteiros novos com a ajuda da sintaxe seguinte: range número1 to número2 (direcção ascendente) range número2 downto número1 (direcção descendente) type small_int is range 1 to 8; type small_int_2 is range 8 downto 1; type num_mec is range 1 to 30000; type cod_desc is range 100 to 10000; variable SDR : cod_desc := 812; variable Paulo : num_mec := 25555; Paulo := SDR; -- erro -- 1 2 3 4 5 6 7 8 -- 8 7 6 5 4 3 2 1 É possível utilizar expressões e constantes na definição dos limites da gama de valores: constant number := integer := 32; type index is range 0 to number - 1; Operações sobre inteiros: + mod rem * abs / ** - para as operações binárias ambos os operandos devem ser do mesmo tipo; - o resultado é um inteiro do mesmo tipo. O valor por defeito de uma variável do tipo inteiro é o valor que está mais à esquerda na definição da gama de valores possíveis. Para as gamas ascendentes este será o valor mais pequeno, para as gamas descendentes este será o valor maior. Tipos reais real – inclui todos os números reais (com a precisão de pelo menos 6 digitos decimais) existentes na gama -1.0E+38 ... 1.0E+38). É possível construir tipos reais novos com a ajuda da sintaxe seguinte: range n_real1 to n_real2 range n_real2 downto n_real1 (direcção ascendente) (direcção descendente) Os tipos reais não são suportados pela ISE. Os tipos físicos não são suportados pela ISE. Tipos enumerativos Permitem dar “nomes” a valores codificados de sinais. Cada “nome” deve ser um identificador ou um caracter. type state is (idle, read_value, incr_addr, write_value); type unit_function is (add, sub, mult, div); type my_logic is ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); type my_logic is (‘X', ‘0', ‘1', ‘Z'); signal next_state : state; constant two : dec_digit := '2'; next_state <= idle; O valor por defeito de uma variável do tipo enumerativo é o valor que está mais à esquerda na lista de valores possíveis. severity_level file_open_status character file_open_kind Character É um tipo predefinido que inclui todos os caracteres do conjunto de caracteres ISO (8 bits). type character is (nul, soh, ...); variable ch : character; 0 1 2 3 4 5 6 7 8 9 10 11 12 .. 25 0 nul lf dc4 rsp ‘(‘ ‘2’ ‘<’ ‘F’ ‘P’ ‘Z’ ‘d’ ‘n’ ‘x’ .. .. 1 soh vt nak usp ‘)’ ‘3’ ‘=’ ‘G’ ‘Q’ ‘[‘ ‘e’ ‘o’ ‘y’ .. .. 2 stx ff syn ‘’ ‘*’ ‘4’ ‘>’ ‘H’ ‘R’ ‘\’ ‘f’ ‘p’ ‘z’ .. .. 3 etx cr etb ‘!’ ‘+’ ‘5’ ‘?’ ‘I’ ‘S’ ‘]’ ‘g’ ‘q’ ‘{‘ .. .. 4 eot so can ‘”’ ‘,’ ‘6’ ‘@’ ‘J’ ‘T’ ‘^’ ‘h’ ‘r’ ‘|’ .. .. 5 enq si em ‘#’ ‘-‘ ‘7’ ‘A’ ‘K’ ‘U’ ‘_’ ‘i’ ‘s’ ‘}’ .. .. 6 ack dle sub ‘$’ ‘.’ ‘8’ ‘B’ ‘L’ ‘V’ ‘`’ ‘j’ ‘t’ ‘~’ .. 7 bel dc1 esc ‘%’ ‘/’ ‘9’ ‘C’ ‘M’ ‘W’ ‘a’ ‘k’ ‘u’ del .. 8 bs dc2 fsp ‘&’ ‘0’ ‘:’ ‘D’ ‘N’ ‘X’ ‘b’ ‘l’ ‘v’ .. .. 9 ht dc3 gsp ‘’’ ‘1’ ‘;’ ‘E’ ‘O’ ‘Y’ ‘c’ ‘m’ ‘w’ .. .. boolean type boolean is (false, true); 678 < 123 and x false false true true y false true false true ‘r’ = ‘r’ 12 = 12 not and false false false true or nand true true true false nand not (x) true true false false nor or false true true true xor nor true false false false xnor xor false true true false xnor true false false true bit type bit is (‘0’, ‘1’); and not ‘1’ and ‘1’ = ‘1’; or nand nor ‘0’ or true; --erro xor xnor std_ulogic type std_ulogic is ( ‘U’, ‘X’, ‘0’, ‘1’, ‘Z’ ‘W’ ‘L’, ‘H’, ‘-’ ); library ieee; use ieee.std_logic_1164.all; ---------- não inicializado não conhecido zero um alta impedância não conhecido (weak) zero (weak) um (weak) don’t care std_logic library ieee; use ieee.std_logic_1164.all; type std_logic is ( ‘U’, ‘X’, ‘0’, ‘1’, ‘Z’ ‘W’ ‘L’, ‘H’, ‘-’ ---------- não inicializado não conhecido zero um alta impedância não conhecido (weak) zero (weak) um (weak) don’t care ); -------------------------------------------------------------------- resolution function ------------------------------------------------------------------function resolved ( s : std_ulogic_vector ) return std_ulogic; -------------------------------------------------------------------- *** industry standard logic type *** ------------------------------------------------------------------subtype std_logic is resolved std_ulogic; U U U U U U U U U U X U X X X X X X X X 0 U X 0 X 0 0 0 0 X 1 U X X 1 1 1 1 1 X Z U X 0 1 Z W L H X W U X 0 1 W W W W X L U X 0 1 L W L W X H U X 0 1 H W W H X U X X X X X X X X U X 0 1 Z W L H - function resolved ( s : std_ulogic_vector ) return std_ulogic is variable result : std_ulogic := 'Z'; -- weakest state default begin -- the test for a single driver is essential otherwise the loop -- would return 'X' for a single driver of '-' and that would -- conflict with the value of a single driver unresolved signal. if (s‘length = 1) then return s(s‘low); else for i in s‘range loop result := resolution_table(result, s(i)); end loop; end if; return result; end resolved; função de resolução library IEEE; use IEEE.STD_LOGIC_1164.ALL; architecture Behavioral of logic is begin entity logic is port ( s : out std_ulogic; clk, a, b : in std_logic); end logic; p1: process (clk, a, b) is begin if (clk = '1') then s <= a and b; else s <= 'Z'; end if; end process p1; library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity logic is port ( s : out std_logic; clk, a, b : in std_logic); end logic; p2: process (clk, a, b) is begin if (clk = '0') then s <= a or b; else s <= 'Z'; end if; end process p2; end Behavioral; Signal s has a multi source. Subtipos Objectos podem operar sobre uma gama restrita de valores de um determinado tipo. Subtipos definem um conjunto restringido de valores do tipo base. subtype half_word is std_logic_vector (3 downto 0); signal ms, ls : half_word; subtype my_logic is std_ulogic range 'U' to '1'; -- ('U','X','0','1') Todas as operações aplicáveis aos tipos base podem também ser utilizadas para os valores de subtipos. O resultado de operações é um valor do tipo base. signal m1, m2, m3 : my_logic; … m3 <= m1 and m2; m2 <= '0'; m1 <= 'Z'; --erro Value 4 is not included in the range, 0 to 3, of m1. subtype si is integer range 0 to 10; signal i1, i2 : si; signal s3 : integer; … i1 <= i2 + s3; subtype natural is integer range 0 to maior_inteiro; subtype positive is integer range 1 to maior_inteiro; Qualificação de tipos type main_fsm_state is (idle, read_value, incr_addr, write_value); type aux_fsm_state is (idle, ready, busy); signal x : main_fsm_state; signal y : aux_fsm_state := aux_fsm_state'(idle); Atributos de tipos escalares type'left; type'right; type‘low; type‘high; type‘ascending; type‘image(value); type‘value(string); -- primeiro valor do tipo type -- último valor do tipo type -- o mais pequeno valor do tipo type -- o maior do tipo type -- true se type é um tipo ascendente -- uma string que representa o valor do value -- o valor representado pela string type indices is range 5 downto 1; std_logic'left = ‘U’ std_logic'right = ‘-’ std_logic'low = ‘U’ std_logic'high = ‘-’ std_logic'ascending = true indices'left = 5 indices'right = 1 indices'low = 1 indices'high = 5 indices'ascending = false type std_logic is (‘U’,‘X’, ‘0’, ‘1’, ‘Z’, ‘W’, ‘L’, ‘H’, ‘-’); type‘pos(value); type‘val(integer); type‘succ(value); type‘pred(value); type‘leftof(value); type‘rightof(value); type’base; -- o número da posição do value em type -- o valor em type que está na posição integer -- o valor em type que está na posição seguinte à do value -- -//- anterior -//-- -//- à esquerda -//-- -//- à direita -//-- o tipo base do tipo type type indices is range 5 downto 1; std_logic'pos('X') = 1 std_logic'val(5) = ‘W’ std_logic'succ('X') = ‘0’ std_logic'pred('X') = ‘U’ std_logic'leftof('X') = ‘U’ std_logic'rightof('X') = ‘0’ indices'pos(4) = 4 indices'val(1) = 1 indices'succ(3) = 4 indices'pred(3) = 2 indices'leftof(3) = 4 indices'rightof(3) = 2 type std_logic is (‘U’,‘X’, ‘0’, ‘1’, ‘Z’, ‘W’, ‘L’, ‘H’, ‘-’); cmd <= std_logic_vector( to_unsigned(character'pos(linha1(6)), 8)); Expressões ** + rol >= abs ror and not & = or * sll /= nand / srl < nor mod sla <= xor rem sra > xnor library IEEE; use IEEE.STD_LOGIC_1164.all; package shift_pac is type commands is (s_l_l, s_r_l, s_l_a, s_r_a, r_l, r_r); end package shift_pac; package body shift_pac is end shift_pac; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use work.shift_pac.all; entity rotate_shift is port ( clk : in std_logic; reset : in std_logic; command : in commands; result : out bit_vector(7 downto 0)); end rotate_shift; sll srl sla sra rol ror - 00011110 00000111 00011111 00000111 00011110 10000111 architecture Behavioral of rotate_shift is begin main: process (clk, reset) is constant vector : bit_vector (7 downto 0) := B"00001111"; begin if (reset = '0') then result <= (others => '0'); elsif (clk = '1' and clk'event) then case command is when s_l_l => result <= vector sll 1; when s_r_l => result <= vector srl 1; when s_l_a => result <= vector sla 1; when s_r_a => result <= vector sra 1; when r_l => result <= vector rol 1; when r_r => result <= vector ror 1; end case; end if; end process main; end Behavioral;