Array aggregates type columns is range 1 to 4; type row is array (columns) of std_logic; variable r1 : row := ('1', '0', '1', '1'); variable r2 : row := (1 => '1', 2 => '0', others => '1'); variable r3 : row := (1 => '1', 2 => '0', 3 to 4 => '1'); variable r4 : row := (2 => '0', others => '1'); variable r5 : row := (1 | 3 | 4 => '1', 2 => '0'); variable r6 : row := ('0', 2 | 3 => '1', 4 => '0'); -- erro r1 – r5 1 0 1 1 associação posicional associação nomeada Array aggregates type rows is range 1 to 2; type columns is range 1 to 4; type row is array (columns) of std_logic; type matrix1 is array (rows) of row; type matrix2 is array (rows, columns) of std_logic; variable m3 : matrix2 := ( ('0', '0', '0', '0'), ('1', '1', '1', '1')); variable m4 : matrix1 := ((others => '0'), (others => '1')); variable m5 : matrix1 := (others => (others => '1')); variable m6 : matrix1 := (1 => (1|2 => '1', 3|4 => '0'), 2=> (1 => '0', others => '1')); m3, m4 0 0 0 1 1 1 0 1 m5 1 1 1 1 1 1 1 1 m6 1 1 0 1 0 0 1 1 type mapping is array (character range 'a' to 'b', 1 to 3) of std_logic; variable mapa : mapping := ('a' => (others => '0'), 'b' => (1 => '1', 2 => '0', 3 => '1')); 1 2 3 ‘a’ 0 0 0 ‘b’ 1 0 1 entity bcd_code is Port ( bin : in std_logic_vector(3 downto 0); bcd : out std_logic_vector(4 downto 0)); end bcd_code; architecture Behavioral of bcd_code is type codes is array (0 to 15) of std_logic_vector(4 downto 0); constant code : codes := ( "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", "10000", "10001", "10010", "10011", "10100", "10101“ ); begin bcd <= code(conv_integer(bin)); end Behavioral; 0000 0 0 0001 0 1 1110 1 4 1111 1 5 ... type type_name is array (range) of type_of_elements; data_in = 00110000 type RAM is array (9 downto 0) of std_logic_vector(7 downto 0); signal my_RAM : RAM; my_RAM(0) = “00110000” my_RAM(1) = “00110001” architecture Behavioral of VHDL_test is my_RAM(2) = “00110010” type RAM is array (9 downto 0) of std_logic_vector(7 downto 0); my_RAM(3) = “00110011” signal my_RAM : RAM; my_RAM(4) = “00110100” begin my_RAM(5) = “00110101” process(clk,reset) my_RAM(6) = “00110110” variable tmp : integer range 0 to 9; my_RAM(7) = “00110111” begin my_RAM(8) = “00111000” if reset = '1' then tmp := 0; my_RAM(9) = “00111001” elsif rising_edge(clk) then my_RAM(tmp) <= data_in + conv_std_logic_vector(tmp,8); if (tmp < 9) then tmp := tmp + 1; else tmp := 0; end if; end if; end process; Agregados na atribuição signal reg : std_logic_vector(3 downto 0); signal ms, b2, b1, ls : std_logic; ms <= reg(3); b2 <= reg(2); b1 <= reg(1); ls <= reg(0); = (ms, b2, b1, ls) <= reg; Atributos de arrays type'left(N); type'right(N); type‘low(N); type‘high(N); type‘range(N); type‘reverse_range(N); type‘length(N); type‘ascending(N); -- índice esquerdo da dimensão N do tipo (array) type -- índice direito da dimensão N do tipo (array) type -- índice menor da dimensão N do tipo (array) type -- índice maior da dimensão N do tipo (array) type -- gama de índices da dimensão N do tipo (array) type -- gama de índices invertida da dimensão N -//-- número de índices da dimensão N do tipo (array) type -- true se gama de índices da dimensão N do tipo (array) type é uma gama ascendente type matrix2 is array (rows, columns) of std_logic; type matriz is array (1 to 3, 3 downto 0) of std_logic; type mapping is array (character range 'a' to 'b', 1 to 3) of std_logic; variable m2 : matrix2; variable mapa : mapping; O número N pode ser omitido quando se refere à primeira dimensão. mapa'left(1) = 'a' mapping'right(1) = 'b' mapping‘high(2) = 3 mapa'length = 2 mapa'ascending(2) = true for i in mapa'reverse_range(1) loop --'b' downto 'a' end loop; matriz'ascending(2) = false Arrays não restringidos Os arrays não restringidos não especificam os limites para os seus índices, indicando apenas o tipo dos índices e o tipo de elementos a guardar. Quando se declara um objecto deste tipo é necessário indicar a gama de índices possíveis. type inteiro is array (natural range <> ) of integer; variable v1 : inteiro (3 to 8); variable v2 : inteiro (10 downto 0); 1. Indicação explícita subtype small_int is inteiro (0 to 64); variable v3 : small_int; 2. Sub-tipos constant c1 : inteiro := (1 => 1, 2 => 2, 3 => 3); constant c2 : inteiro := (1, 2, 3); 3. Inicialização de constantes com agregados Arrays não restringidos predefinidos type string is array (positive range <>) of character; constant linha1 : string := "Os nomes sao"; constant linha2 : string (1 to 12) := "Os nomes sao"; constant linha3 : string (30 downto 28) := "Ola"; type bit_vector is array (natural range <>) of bit; std_logic_1164 type std_logic_vector is array (natural range <>) of std_logic; É possível utilizar strings e bit strings para inicializar arrays cujos elementos são do tipo enumerativo que inclui caracteres. signal s4 : std_logic_vector(3 downto 0); s4 <= "010-"; s4 <= x"f"; Portas não restringidas entity porta_or is Port ( input : in std_logic_vector; result : out std_logic); end porta_or; architecture beh of porta_or is begin process (input) is variable temp : std_logic; begin temp := '0'; for i in input'range loop temp := temp or input(i); if (temp = '1') then exit; end if; end loop; result <= temp; end process; end beh; entity calc is Port ( vector1 : in std_logic_vector(1 downto 0); vector2 : in std_logic_vector(7 downto 0); vector3 : in std_logic_vector(0 to 15); r1 : out std_logic; r2 : out std_logic; r3 : out std_logic); end calc; architecture Behavioral of calc is begin v1: entity work.porta_or(beh) port map (input => vector1, result => r1); v2: entity work.porta_or(beh) port map (input => vector2, result => r2); v3: entity work.porta_or(beh) port map (input => vector3, result => r3); end Behavioral; Operações sobre arrays Operações lógicas not, and, or, nand, nor, xor, xnor podem ser aplicadas a um ou a dois arrays unidimensionais desde que estas operações sejam definidas para os elementos dos arrays. Operações de deslocamento sll, srl, sla, sra, rol, ror podem ser aplicadas a um array unidimensional (operando esquerdo) de bits ou valores booleanos. Operações comparativas podem ser aplicadas a dois arrays unidimensionais cujos elementos são de qualquer tipo discreto. entity arr_op is Port ( x : in std_logic_vector(7 downto 0); y : in std_logic_vector(7 downto 0); gr : out std_logic); end arr_op; O operador de concatenação & pode ser aplicado a dois arrays unidimensionais e a valores escalares. cmd <= "0011" & digit_dec; cmd <= "0011000" & ‘1'; architecture Beh of arr_op is begin process (x, y) is begin if (x > y) then gr <= '1'; else gr <= '0'; end if; end process; end Beh; Array slices Servem para especificar um subconjunto de elementos num array. A direcção de índices num slice deve ser idêntica à direcção de índices no array. signal x : std_logic_vector(7 downto 0); signal y : std_logic_vector(7 downto 0); signal s1 : std_logic_vector(3 downto 0); signal s2 : std_logic_vector(0 to 3); s1 <= x (7 downto 4); s1 <= y (0 to 3); -- erro s2 <= x (7 downto 4); s2 <= y (3 downto 0); y (0 downto 3); -- null slice Conversão entre tipos Um valor do tipo array pode ser convertido num outro valor de outro tipo array desde que ambos os tipos tenham: - o mesmo tipo de elementos; - o mesmo número de dimensões; - os tipos de índices que podem ser convertidos. type arr1 is array (‘b’ downto ‘a’, 1 to 2) of std_logic; type arr2 is array (‘a’ to ‘b’, 3 to 4) of std_logic; variable v1 : arr1; variable v2 : arr2; v2 := (v1); -- erro v2 := arr2(v1); Quando atribuímos um valor de um subtipo a um objecto de um outro subtipo do mesmo tipo, a conversão ocorre automaticamente. subtype BE is std_logic_vector(0 to 3); subtype LE is std_logic_vector(3 downto 0); subtype M is std_logic_vector(20 to 23); variable b : BE; variable l : LE; variable m : M; b := x"b"; l := b; m := b; b l m 0 1 2 3 1 0 1 1 3 2 1 0 1 0 1 1 20 21 22 23 1 0 1 1 Records - composição de elementos de vários tipos. entity rec is Port ( clk : in std_logic; d : in std_logic_vector(7 downto 0)); end rec; architecture Behavioral of rec is type sp is record start_bit : std_logic; data_bits : std_logic_vector (7 downto 0); parity_bit : std_ulogic; stop_bit : std_logic; end record sp; signal s1, s2 : sp; begin s1.data_bits <= d; s2 <= s1; end Behavioral; Agregados em records type sp is record start_bit : std_logic; data_bits : std_logic_vector (7 downto 0); parity_bit : std_ulogic; stop_bit : std_logic; end record sp; constant c1 : sp := (start_bit => '1', data_bits => x"f5", parity_bit => '0', stop_bit => '1'); constant c2 : sp := ('1', x"f5", '0', '1'); constant c3 : sp := (data_bits => x"f5", parity_bit => '0', stop_bit => '1', start_bit => '1'); associações posicionais e nomeadas code of entity architecture Behavioral of VHDL_test is -- declaração de bit3,…,bit0 e my_bus begin bit3 <= '0'; bit2 <= '1'; bit1 <= '1'; bit0 <= '1'; my_bus <= (0=>bit3, 2=>bit2, 1=>bit1, 3=>bit0); data_out <= my_bus; end Behavioral; Example in VHDL_AF.zip Isto é uma associação nomeada code of entity architecture Behavioral of VHDL_test is signal my_bus : std_logic_vector(3 downto 0); begin my_bus <= (1 downto 0 => '1', others => '0'); data_out <= my_bus; -- valor 3 end Behavioral; Os elementos podem ser agrupados. Palavra chave others indica os restantes elementos Example in VHDL_AF.zip code of entity architecture Behavioral of VHDL_test is type my_packet is record first_bit : std_logic; second_bit : std_logic; data : std_logic_vector (1 downto 0); end record; signal record_data : my_packet; begin record_data <= ('0', '1', "01"); data_out <= record_data.first_bit & record_data.second_bit & record_data.data; -- valor 5 end Behavioral; Example in VHDL_AF.zip std_logic code of entity architecture Behavioral of VHDL_test is type my_array is array(3 downto 0) of std_logic; type my_packet is array(0 to 5) of my_array; signal my_data : my_packet := (others => "0110"); begin data_out <= my_data(2)(3) & my_data(2)(2) & my_data(2)(1) & my_data(2)(0); -- valor 6 end Behavioral; 3 2 1 0 my_array my_array my_array my_array my_array my_data Example in VHDL_AF.zip my_packet my_array architecture Behavioral of VHDL_test is type my_array is array(3 downto 0) of std_logic; type my_packet is array(0 to 5) of my_array; inicialização signal my_data : my_packet := (others => "0110"); process(reset,clk) variable my_ind : integer range 0 to 5; begin if reset = '1' then my_data <= (5=>"1000", 3=>"1001", others => "0100"); my_ind := 0; elsif rising_edge(clk) then data_out <= my_data(my_ind)(3) & my_data(my_ind)(2) & my_data(my_ind)(1) & my_data(my_ind)(0); indice index_out <= conv_std_logic_vector(my_ind,4); if my_ind = 5 then my_ind := 0; else my_ind := my_ind + 1; end if; end if; end process; a sequência dos índices saída de dados para índice my_ind end Behavioral; 0,1,2,3,4,5 Example in VHDL_AF.zip type type_name is array (range) of type_of_elements; data_in = 00110000 type RAM is array (9 downto 0) of std_logic_vector(7 downto 0); signal my_RAM : RAM; my_RAM(0) = “00110000” my_RAM(1) = “00110001” architecture Behavioral of VHDL_test is my_RAM(2) = “00110010” type RAM is array (9 downto 0) of std_logic_vector(7 downto 0); my_RAM(3) = “00110011” signal my_RAM : RAM; my_RAM(4) = “00110100” begin my_RAM(5) = “00110101” process(clk,reset) my_RAM(6) = “00110110” variable tmp : integer range 0 to 9; my_RAM(7) = “00110111” begin my_RAM(8) = “00111000” if reset = '1' then tmp := 0; my_RAM(9) = “00111001” elsif rising_edge(clk) then my_RAM(tmp) <= data_in + conv_std_logic_vector(tmp,8); if (tmp < 9) then tmp := tmp + 1; else tmp := 0; end if; end if; end process; process(clk,reset) begin if falling_edge(clk) then for i in my_RAM'range loop data_out <= my_RAM(i); end loop; end if; end process; process(clk,reset) begin if falling_edge(clk) then for i in my_RAM'reverse_range loop data_out <= my_RAM(i); end loop; end if; end process; objecto’nome_de_atributo; -- o resultado é “00110000” (ASCII – 0) -- o resultado é “00111001” (ASCII – 9) object’attribute_name; process(clk,reset) variable tmp : integer range 0 to 9; begin if reset = '1' then tmp := 0; elsif falling_edge(clk) then data_out <= my_RAM(tmp); index_out <= "000" & my_RAM(tmp)(my_RAM(tmp)'right); index_out <= "000" & my_RAM(tmp)(my_RAM(tmp)'left); length index_out <= x"30" + conv_std_logic_vector((my_RAM'length)-1,8); --my_RAM'high - my_RAM'low + 1 - o resultado é 9 index_out <= x"30" + conv_std_logic_vector(my_RAM(0)'length,8); if (tmp < 9) then tmp := tmp + 1; else tmp := 0; end if; end if; end process; bit esquerdo bit direito o resultado é “00111000” (ASCII – 8) type nome_de tipo is especificação_de_tipo; Tipos escalares predefinidos são: integer, real, bit, Boolean, character type positive_integers is range 0 to integer'high; type FSM_states is (start, increment, save, decrement,repeat); signal state : FSM_states; signal p_i : positive_integers; subtype word8 is std_logic_vector (8 downto 1); type serial_pac is array (0 to 8) of word8; constant line_RS : serial_pac := ( x"1B", --delete display x"44", --delete display x"4C", --delete display x"1B", --draw line (ESC) x"47", --draw line (code of this operation) x"30", -- x1 left point x"15", -- y1 upper point x"E6", -- x2 right point x"72"); -- y2 bottom point type serial_package is record start_bit : std_logic; data_bits : std_logic_vector (7 downto 0); parity_bit : std_ulogic; stop_bit : std_logic; number : integer range 0 to 127; end record; signal my_sp : serial_package; my_sp.number <= 10; my_sp.start_bit <= '1'; my_sp.data_bits <= (others => '1'); Atribuição de bits individuais target_type(expressão) function(expressão) exemplos: Só as expressões relacionadas podem ser convertidas exemplos: type my_array is array (0 to 5) of std_logic; signal mem1 : my_array; signal mem2 : std_logic_vector (0 to 5); -- mem1 <= mem2; mem1 <= my_array(mem2); mem2 <= std_logic_vector(mem1); erro -- OK -- OK use IEEE.NUMERIC_STD.ALL; -- para to_unsigned -- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . index_out <= conv_std_logic_vector(index,4); for_op1 <= conv_integer(data_in(7 downto 5)); index_out <= std_logic_vector(to_unsigned(character'pos('6'),4)); index_out <= std_logic_vector(to_unsigned(character'pos(line2(1)), 8)); Para conversão de tipos não relacionados pode-se usar funções definidas pelo utilizador, por exemplo: architecture Behavioral of VHDL_test is -- . . . . . . . . . . . . . . . . . . . . . function Bollean_to_std_logic(input : Boolean) return std_logic is begin if input then return '1'; else return '0'; end if; end Bollean_to_std_logic; -- . . . . . . . . . . . . . . . . . . . . . begin index_out <= "000" & Bollean_to_std_logic(true); subtype nome_de_subtipo is tipo_base range intervalo_de_valores; subtype tiny is integer range 0 to 63; subtype part_of_std is std_logic range '1' to '-'; subtype word8 is std_logic_vector (8 downto 1); type serial_pac is array (0 to 8) of word8; constant line_RS : serial_pac := ( x"1B", --delete display x"44", --delete display x"4C", --delete display x"1B", --draw line (ESC) x"47", --draw line (code of this operation) x"30", -- x1 left point x"15", -- y1 upper point x"E6", -- x2 right point x"72"); -- y2 bottom point 1) 2) 3) 4) 5) 6) 7) 8) 9) '1' - logical 1 '0' - logical 0 'H' – weak 1 'L' – weak 0 'X' – unknown 'U' – uninitialized 'Z' – high impedance '-' – don't care 'W' – weak unknown std_logic values