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
Download

VHDL